diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e1de630..c633131 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,10 +12,13 @@ build-ubuntu-x: - ubuntu stage: build script: - - sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libxext-dev - - cd src - - ln -s vars_x86linux_x11 vars + - sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libxext-dev re2c cmake + - mkdir build + - cd build + - cmake .. + - make - make clean ; make + - mv bin/GSplus ../gsplusx artifacts: paths: - gsplusx @@ -62,11 +65,12 @@ build-ubuntu-sdl2: - ubuntu stage: build script: - - sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libsdl2-dev libfreetype6-dev libsdl2-image-dev - - cd src - - ln -s vars_x86linux_sdl2 vars - - make clean ; make - - mv ../gsplus ../gsplus-ubuntu-sdl.bin + - sudo apt-get update -qq && sudo apt-get install -y -qq g++ libpcap0.8-dev libx11-dev libsdl2-dev libfreetype6-dev libsdl2-image-dev re2c cmake + - mkdir build + - cd build + - cmake .. + - make + - mv bin/GSplus ../gsplus-ubuntu-sdl.bin artifacts: paths: - gsplus-ubuntu-sdl.bin @@ -126,22 +130,22 @@ deploy-ubuntu: - aws s3 cp $PACKAGE_NAME.deb s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/ubuntu-sdl-deb/$CI_BUILD_ID/ --acl public-read - - # TARGET SYSTEM: OSX 10.SOMETHING build-osx: tags: - osx stage: build script: - - cd src - - ln -s vars_osx_sdl2 vars + - mkdir build + - cd build + - cmake .. + - make - make clean ; make - - mv ../gsplus ../gsplus-osx + - mv bin/GSplus.app/Contents/MacOS/GSplus ../gsplus-osx artifacts: paths: - gsplus-osx - expire_in: 10 minutes + expire_in: 15 minutes package-osx: tags: @@ -170,123 +174,139 @@ deploy-osx: - aws s3 cp GSplus-Install.dmg s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/osx/$CI_BUILD_ID/ --acl public-read -# TARGET SYSTEM: WIN32 WIN API UNDER CYGWIN -build-win32: +# TARGET SYSTEM: WIN32 GDI WIN API UNDER MSYS2 +build-win32-gdi: tags: - - windows + - windows,msys stage: build script: - - bash -c "cd src; ln -s vars_win32 vars; make clean ; make" + - ls + - mkdir build + - cd build + - cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "Unix Makefiles" + - make VERBOSE=1 GSplus + - mv bin/GSplus.exe ../GSplus-win32-gdi.exe artifacts: paths: - - gsplus32.exe + - GSplus-win32-gdi.exe expire_in: 10 minutes only: - master - /^win.*/ + - /^ks.*/ -package-win32: +package-win32-gdi: tags: - - windows + - windows,msys + variables: + GIT_STRATEGY: fetch + PACKAGE_DIR: gsplus-win32-gdi stage: package script: - - cp src/config.txt . - - 'echo "# CI_BUILD_ID: $CI_BUILD_ID" >> config.txt' + - ls + - mkdir %PACKAGE_DIR% + - cp src/config.txt %PACKAGE_DIR% + - 'echo "# CI_BUILD_ID: $CI_BUILD_ID" >> %PACKAGE_DIR%/config.txt' - cp LICENSE.txt doc/ - - cp /bin/cyggcc_s-1.dll . - - cp /bin/cygstdc++-6.dll . - - cp /bin/cygwin1.dll . - - cp /bin/cygfreetype-6.dll . - variables: - GIT_STRATEGY: fetch - PACKAGE_DIR: gsplus-win32 - script: - - mkdir %PACKAGE_DIR% - - cp gsplus32.exe %PACKAGE_DIR% + - cp GSplus-win32-gdi.exe %PACKAGE_DIR%/GSplus.exe - cp LICENSE.txt %PACKAGE_DIR% - cp src/config.txt %PACKAGE_DIR% - cp src/parallel.rom %PACKAGE_DIR% - cp doc/gsplusmanual.pdf %PACKAGE_DIR% - cp doc/README.txt %PACKAGE_DIR% - - cp /bin/cyggcc_s-1.dll %PACKAGE_DIR% - - cp /bin/cygstdc++-6.dll %PACKAGE_DIR% - - cp /bin/cygwin1.dll %PACKAGE_DIR% - - cp /bin/cygfreetype-6.dll %PACKAGE_DIR% - - zip gsplus-win32.zip -r %PACKAGE_DIR% + - cp /mingw32/bin/libgcc_s_dw2-1.dll %PACKAGE_DIR% + - cp /mingw32/bin/libstdc++-6.dll %PACKAGE_DIR% + - cp /mingw32/bin/libwinpthread-1.dll %PACKAGE_DIR% + - zip gsplus-win32-gdi.zip -r %PACKAGE_DIR% artifacts: paths: - - gsplus-win32.zip + - gsplus-win32-gdi.zip expire_in: 10 minutes only: - master - /^win.*/ + - /^ks.*/ -deploy-win32: +deploy-win32-gdi: tags: - - windows + - osx stage: deploy variables: GIT_STRATEGY: none script: - - aws s3 cp gsplus-win32.zip s3://%AWS_BUCKET%/%CI_TAG%/%CI_VERSION%/%CI_PIPELINE_ID%/win32/%CI_BUILD_ID%/ --acl public-read + - aws s3 cp gsplus-win32-gdi.zip s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/win32/$CI_BUILD_ID/ --acl public-read only: - master - /^win.*/ + - /^ks.*/ -# TARGET SYSTEM: WIN32 SDL2 UNDER CYGWIN W MINGW64 SDL2 LIBS -build-win-sdl2: +# TARGET SYSTEM: MSYS2 MINGW32 SDL2 +build-win32-sdl2: tags: - windows stage: build script: - - cd src - - ln -s vars_win32_sdl2 vars - - make clean - - make + - mkdir build + - cd build + - bash -l -c 'PATH=/mingw32/bin:$PATH ; MSYSTEM=MINGW32 MSYSTEM_PREFIX=/mingw32 /mingw32/bin/cmake ../ -DDRIVER=SDL2 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles"' + - bash -l -c 'PATH=/mingw32/bin:$PATH ;MSYSTEM=MINGW32 MSYSTEM_PREFIX=/mingw32 /mingw32/bin/mingw32-make VERBOSE=1 GSplus' + - mv bin/GSplus.exe ../GSplus-win32-sdl.exe + artifacts: paths: - - gsplus.exe + - GSplus-win32-sdl.exe expire_in: 10 minutes + only: + - master + - /^win.*/ + - /^ks.*/ -package-win-sdl2: + +package-win32-sdl2: tags: - windows stage: package variables: GIT_STRATEGY: fetch - PACKAGE_DIR: gsplus-win-sdl + PACKAGE_DIR: gsplus-win32-sdl script: + - ls - mkdir %PACKAGE_DIR% - - cp gsplus.exe %PACKAGE_DIR% + - cp GSplus-win32-sdl.exe %PACKAGE_DIR%/GSplus.exe - cp LICENSE.txt %PACKAGE_DIR% - cp src/config.txt %PACKAGE_DIR% - cp src/parallel.rom %PACKAGE_DIR% - cp doc/gsplusmanual.pdf %PACKAGE_DIR% - cp doc/README.txt %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygbz2-1.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygfreetype-6.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cyggcc_s-1.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygjpeg-8.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygpng16-16.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygjpeg-8.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygstdc++-6.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygwin1.dll %PACKAGE_DIR% - - cp /cygdrive/c/cygwin/bin/cygz.dll %PACKAGE_DIR% - - cp /cygdrive/c/mingw/i686-w64-mingw32/bin/SDL2.dll %PACKAGE_DIR% - - cp /cygdrive/c/mingw/i686-w64-mingw32/bin/SDL2_image.dll %PACKAGE_DIR% - - zip gsplus-win-sdl.zip -r %PACKAGE_DIR% + - cp /mingw32/bin/libbz2-1.dll %PACKAGE_DIR% + - cp /mingw32/bin/libfreetype-6.dll %PACKAGE_DIR% + - cp /mingw32/bin/libgcc_s_dw2-1.dll %PACKAGE_DIR% + - cp /mingw32/bin/libglib-2.0-0.dll %PACKAGE_DIR% + - cp /mingw32/bin/libgraphite2.dll %PACKAGE_DIR% + - cp /mingw32/bin/libharfbuzz-0.dll %PACKAGE_DIR% + - cp /mingw32/bin/libiconv-2.dll %PACKAGE_DIR% + - cp /mingw32/bin/libintl-8.dll %PACKAGE_DIR% + - cp /mingw32/bin/libpcre-1.dll %PACKAGE_DIR% + - cp /mingw32/bin/libpng16-16.dll %PACKAGE_DIR% + - cp /mingw32/bin/libstdc++-6.dll %PACKAGE_DIR% + - cp /mingw32/bin/libwinpthread-1.dll %PACKAGE_DIR% + - cp /mingw32/bin/SDL2.dll %PACKAGE_DIR% + - cp /mingw32/bin/SDL2_image.dll %PACKAGE_DIR% + - cp /mingw32/bin/zlib1.dll %PACKAGE_DIR% + - zip gsplus-win32-sdl.zip -r %PACKAGE_DIR% artifacts: paths: - - gsplus-win-sdl.zip + - gsplus-win32-sdl.zip expire_in: 10 minutes -deploy-win-sdl2: + +deploy-win32-sdl2: tags: - - windows + - osx stage: deploy variables: GIT_STRATEGY: none script: - - aws s3 cp gsplus-win-sdl.zip s3://%AWS_BUCKET%/%CI_TAG%/%CI_VERSION%/%CI_PIPELINE_ID%/win-sdl/%CI_BUILD_ID%/ --acl public-read + - aws s3 cp gsplus-win32-sdl.zip s3://$AWS_BUCKET/$CI_TAG/$CI_VERSION/$CI_PIPELINE_ID/win-sdl/$CI_BUILD_ID/ --acl public-read update-website-universal: tags: @@ -299,4 +319,3 @@ update-website-universal: - php assets/updatewebsite.php s3artifacts.txt public > index.html - php assets/updatewebsite.php s3artifacts.txt auto > index_auto.html - aws s3 cp index.html s3://$AWS_BUCKET/ --acl public-read - - aws s3 cp index_auto.html s3://$AWS_BUCKET/ --acl public-read diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a58c12b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +language: c + +matrix: + include: + - os: linux + dist: xenial + - os: osx + +addons: + apt: + packages: + - re2c + - libsdl2-dev + - libsdl2-image-dev + - libfreetype6-dev + homebrew: + packages: + - re2c + - sdl2 + - sdl2_image + - freetype + +before_script: + - mkdir build + - cd build + - cmake .. + +script: make GSplus diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..742ebf7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.1) +project(gsplus VERSION 0.14) + + +if(CYGWIN OR MSYS) + set(WIN32 1) + add_definitions(-DWIN32 -D_WIN32 -D__USE_W32_SOCKETS) +endif() + +# msys/cygwin/mingw32 add dirent.h, etc. +# Visual C++ does not. +if(MSVC) + include_directories(include/msvc) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + add_compile_options(/wd4996) +endif() + +# add pcap headers for win32. assume os/x, linux, etc, already have them. +if(WIN32) + include_directories(include/npcap) +endif() + +add_subdirectory(src bin) diff --git a/README.md b/README.md index c11c8eb..2c950b4 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,45 @@ -# GSplus -An Apple IIgs emulator for Mac OSX, Windows, and Linux. +# GS+ Pro Xtreme HD Developer Edition -![Screenshot of starting the program](doc/web/Screenshot.png "Screenshot of starting the program") +My personal fork of GSplus which is a fork of GSport which is fork of KEGS. Replaces the edbugger facilities with something more suitable for my tastes. -# About -This is an early release of an experimental project to modernize the -KEGS/GSport emulator platform and eventually extend it. +# Build instructions -# Install -Go to https://apple2.gs/plus to get the latest downloads for your system. +## OS X dependencies + brew install re2c sdl2 sdl2_image freetype -# Usage Notes -You need to provide the ROM file and disk images and a config file. I'd -recommend you just drop it in your current GSport or KEGS folder and run it -from there. +## Linux dependencies + apt-get install re2c libsdl2-dev libsdl2-image-dev libfreetype6-dev libpcap0.8-dev -See the doc/gsplusmanual.pdf file for much more complete documentation. +## WIN32 dependencies +Install MSYS2 (not MSYS, not cygwin) -# Build Instructions -See the /doc/ directory for "Developer-Quickstart" docs which cover building -for the various platforms. +32-bit build: + + pacman -S re2c mingw-w64-i686-cmake mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_image mingw-w64-i686-freetype + +64-bit build: + + pacman -S re2c mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_image mingw-w64-x86_64-freetype + + +## Linux, OS X, build + mkdir build + cd build + cmake .. + (optionally: ccmake .. to configure stuff) + make + + +## Windows Build + +### mingw SDL build + mkdir build + cd build + cmake ../ -DDRIVER=SDL2 -DWITH_DEBUGGER=OFF -G "MSYS Makefiles" + make GSplus.exe +### mingw GDI build + + mkdir build + cd build + cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -G "MSYS Makefiles" + make GSplus.exe diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..8ada2bf --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,141 @@ +version: 1.0.{build} +image: + - Visual Studio 2017 + - Ubuntu1804 +configuration: +- mingw32-sdl +- mingw32-gdi +- mingw64-gdi +- msys-gdi +- linux-sdl +- linux-headless + +matrix: + exclude: + - configuration: linux-sdl + image: Visual Studio 2017 + - configuration: linux-headless + image: Visual Studio 2017 + - configuration: mingw32-sdl + image: Ubuntu1804 + - configuration: mingw32-gdi + image: Ubuntu1804 + - configuration: mingw64-gdi + image: Ubuntu1804 + - configuration: msys-gdi + image: Ubuntu1804 + +for: + - # mingw64/gdi + matrix: + only: + - image: Visual Studio 2017 + configuration: mingw64-gdi + install: + - cmd: set MSYSTEM=MINGW64 + - cmd: set MSYSTEM_PREFIX=/mingw64 + - cmd: set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH% + - cmd: pacman --noconfirm -Sy + - cmd: pacman --noconfirm -S re2c mingw-w64-x86_64-cmake + build_script: + - cmd: mkdir build + - cmd: cd build + - cmd: cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles" + - cmd: make VERBOSE=1 GSplus + artifacts: + - path: 'build\bin\GSplus.exe' + name: GSplus-64-gdi + + - # mingw32/gdi + matrix: + only: + - image: Visual Studio 2017 + configuration: mingw32-gdi + install: + - cmd: set MSYSTEM=MINGW32 + - cmd: set MSYSTEM_PREFIX=/mingw32 + - cmd: set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\bin;%PATH% + - cmd: pacman --noconfirm -Sy + - cmd: pacman --noconfirm -S re2c mingw-w64-i686-cmake + build_script: + - cmd: mkdir build + - cmd: cd build + - cmd: cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles" + - cmd: make VERBOSE=1 GSplus + artifacts: + - path: 'build\bin\GSplus.exe' + name: GSplus-32-gdi + + - # mingw32/sdl + matrix: + only: + - image: Visual Studio 2017 + configuration: mingw32-sdl + install: + - cmd: set MSYSTEM=MINGW32 + - cmd: set MSYSTEM_PREFIX=/mingw32 + - cmd: set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\bin;%PATH% + - cmd: pacman --noconfirm -Sy + - cmd: pacman --noconfirm -S re2c mingw-w64-i686-cmake mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_image mingw-w64-i686-freetype + build_script: + - cmd: mkdir build + - cmd: cd build + - cmd: cmake ../ -DDRIVER=SDL2 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "MSYS Makefiles" + - cmd: make VERBOSE=1 GSplus + artifacts: + - path: 'build\bin\GSplus.exe' + name: GSplus-32-sdl + + - # msys2/gdi + matrix: + only: + - image: Visual Studio 2017 + configuration: msys-gdi + install: + - cmd: set MSYSTEM=MSYS + - cmd: set MSYSTEM_PREFIX=/usr/ + - cmd: set PATH=C:\msys64\bin;C:\msys64\usr\bin;%PATH% + - cmd: pacman --noconfirm -Sy + - cmd: pacman --noconfirm -S re2c + build_script: + - cmd: mkdir build + - cmd: cd build + - cmd: cmake ../ -DDRIVER=WIN32 -DWITH_DEBUGGER=OFF -DWITH_STATIC=ON -G "Unix Makefiles" + - cmd: make VERBOSE=1 GSplus + artifacts: + - path: 'build\bin\GSplus.exe' + name: GSplus-cygwin-32-gdi + + - # linux/sdl + matrix: + only: + - image: Ubuntu1804 + configuration: linux-sdl + install: + - sh: sudo apt-get update + - sh: sudo apt-get install -y re2c libsdl2-dev libsdl2-image-dev libfreetype6-dev + build_script: + - sh: mkdir build + - sh: cd build + - sh: cmake ../ -DDRIVER=SDL2 + - sh: make VERBOSE=1 GSplus + artifacts: + - path: 'build/bin/GSplus' + name: GSplus-linux-sdl + + - # linux/headless + matrix: + only: + - image: Ubuntu1804 + configuration: linux-headless + install: + - sh: sudo apt-get update + - sh: sudo apt-get install -y re2c + build_script: + - sh: mkdir build + - sh: cd build + - sh: cmake ../ -DDRIVER=HEADLESS + - sh: make VERBOSE=1 GSplus + artifacts: + - path: 'build/bin/GSplus' + name: GSplus-linux-headless diff --git a/doc/Developer-QuickStart-Linux.txt b/doc/Developer-QuickStart-Linux.txt index 0021ab2..61da48a 100644 --- a/doc/Developer-QuickStart-Linux.txt +++ b/doc/Developer-QuickStart-Linux.txt @@ -6,11 +6,10 @@ # relatively straightforward to modify for something like yum -# system prep +# Build tools sudo apt-get -y update sudo apt-get -y upgrade -sudo apt-get -y install git -sudo apt-get -y install g++ +sudo apt-get -y install git g++ cmake re2c sudo apt-get -y install libpcap0.8-dev sudo apt-get -y install libfreetype6-dev @@ -27,8 +26,9 @@ sudo apt-get -y install libsdl2-dev sudo apt-get -y install libsdl2-image-dev -# Example build to test out our system -cd gsplus/src -ln -s vars_x86linux_sdl2 vars -make clean ; make +# Clone & Build. +git clone git@github.com:digarok/gsplus.git +mkdir build ; cd build +cmake .. +make diff --git a/doc/Developer-QuickStart-MacOSX.txt b/doc/Developer-QuickStart-MacOSX.txt index b5e41c6..a3f63ca 100644 --- a/doc/Developer-QuickStart-MacOSX.txt +++ b/doc/Developer-QuickStart-MacOSX.txt @@ -14,12 +14,10 @@ xcode-select --install /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" # Use brew to install dependencies. -brew install sdl2 -brew install sdl2_image -brew install freetype +brew install sdl2 sdl2_image freetype re2c cmake -# Build. +# Clone & Build. git clone git@github.com:digarok/gsplus.git -cd gsplus/src -ln -s vars_osx_sdl2 vars -make clean ; make +mkdir build ; cd build +cmake .. +make diff --git a/src/arch/win32/dirent-win32.h b/include/msvc/dirent.h similarity index 100% rename from src/arch/win32/dirent-win32.h rename to include/msvc/dirent.h diff --git a/include/npcap/Packet32.h b/include/npcap/Packet32.h new file mode 100644 index 0000000..1e2edc7 --- /dev/null +++ b/include/npcap/Packet32.h @@ -0,0 +1,421 @@ +/***********************IMPORTANT NPCAP LICENSE TERMS*********************** + * * + * Npcap is a Windows packet sniffing driver and library and is copyright * + * (c) 2013-2016 by Insecure.Com LLC ("The Nmap Project"). All rights * + * reserved. * + * * + * Even though Npcap source code is publicly available for review, it is * + * not open source software and my not be redistributed or incorporated * + * into other software without special permission from the Nmap Project. * + * We fund the Npcap project by selling a commercial license which allows * + * companies to redistribute Npcap with their products and also provides * + * for support, warranty, and indemnification rights. For details on * + * obtaining such a license, please contact: * + * * + * sales@nmap.com * + * * + * Free and open source software producers are also welcome to contact us * + * for redistribution requests. However, we normally recommend that such * + * authors instead ask your users to download and install Npcap * + * themselves. * + * * + * Since the Npcap source code is available for download and review, * + * users sometimes contribute code patches to fix bugs or add new * + * features. By sending these changes to the Nmap Project (including * + * through direct email or our mailing lists or submitting pull requests * + * through our source code repository), it is understood unless you * + * specify otherwise that you are offering the Nmap Project the * + * unlimited, non-exclusive right to reuse, modify, and relicence your * + * code contribution so that we may (but are not obligated to) * + * incorporate it into Npcap. If you wish to specify special license * + * conditions or restrictions on your contributions, just say so when you * + * send them. * + * * + * This software 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. * + * * + * Other copyright notices and attribution may appear below this license * + * header. We have kept those for attribution purposes, but any license * + * terms granted by those notices apply only to their original work, and * + * not to any changes made by the Nmap Project or to this entire file. * + * * + * This header summarizes a few important aspects of the Npcap license, * + * but is not a substitute for the full Npcap license agreement, which is * + * in the LICENSE file included with Npcap and also available at * + * https://github.com/nmap/npcap/blob/master/LICENSE. * + * * + ***************************************************************************/ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino, CACE Technologies + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** @ingroup packetapi + * @{ + */ + +/** @defgroup packet32h Packet.dll definitions and data structures + * Packet32.h contains the data structures and the definitions used by packet.dll. + * The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included + * by the applications that use the functions of this library + * @{ + */ + +#ifndef __PACKET32 +#define __PACKET32 + +#include + +#ifdef HAVE_AIRPCAP_API +#include +#else +#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) +#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ +typedef struct _AirpcapHandle* PAirpcapHandle; +#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ +#endif /* HAVE_AIRPCAP_API */ + +#ifdef HAVE_DAG_API +#include +#endif /* HAVE_DAG_API */ + +// Libpcap/wpcap recognizes this macro and knows Npcap Packet API is provided for compilation. +#define HAVE_NPCAP_PACKET_API + +// Working modes +#define PACKET_MODE_CAPT 0x0 ///< Capture mode +#define PACKET_MODE_STAT 0x1 ///< Statistical mode +#define PACKET_MODE_MON 0x2 ///< Monitoring mode +#define PACKET_MODE_DUMP 0x10 ///< Dump mode +#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode + + +/// Alignment macro. Defines the alignment size. +#define Packet_ALIGNMENT sizeof(int) +/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. +#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) + +#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent +#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent + +// Loopback behaviour definitions +#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver +#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver + +/*! + \brief Network type structure. + + This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. +*/ +typedef struct NetType +{ + UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information) + ULONGLONG LinkSpeed; ///< The speed of the network in bits per second +}NetType; + + +//some definitions stolen from libpcap + +#ifndef BPF_MAJOR_VERSION + +/*! + \brief A BPF pseudo-assembly program. + + The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. +*/ +struct bpf_program +{ + UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. + struct bpf_insn* bf_insns; ///< A pointer to the first instruction of the program. +}; + +/*! + \brief A single BPF pseudo-instruction. + + bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. +*/ +struct bpf_insn +{ + USHORT code; ///< Instruction type and addressing mode. + UCHAR jt; ///< Jump if true + UCHAR jf; ///< Jump if false + int k; ///< Generic field used for various purposes. +}; + +/*! + \brief Structure that contains a couple of statistics values on the current capture. + + It is used by packet.dll to return statistics about a capture session. +*/ +struct bpf_stat +{ + UINT bs_recv; ///< Number of packets that the driver received from the network adapter + ///< from the beginning of the current capture. This value includes the packets + ///< lost by the driver. + UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. + ///< Basically, a packet is lost when the the buffer of the driver is full. + ///< In this situation the packet cannot be stored and the driver rejects it. + UINT ps_ifdrop; ///< drops by interface. XXX not yet supported + UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and + ///< thus reach the application. +}; + +/*! + \brief Packet header. + + This structure defines the header associated with every packet delivered to the application. +*/ +struct bpf_hdr +{ + struct timeval bh_tstamp; ///< The timestamp associated with the captured packet. + ///< It is stored in a TimeVal structure. + UINT bh_caplen; ///< Length of captured portion. The captured portion can be different + ///< from the original packet, because it is possible (with a proper filter) + ///< to instruct the driver to capture only a portion of the packets. + UINT bh_datalen; ///< Original length of packet + USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases, + ///< a padding could be added between the end of this structure and the packet + ///< data for performance reasons. This filed can be used to retrieve the actual data + ///< of the packet. +}; + +/*! + \brief Dump packet header. + + This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). + It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a + packet in a dump file. This makes straightforward sending WinPcap dump files to the network. +*/ +struct dump_bpf_hdr +{ + struct timeval ts; ///< Time stamp of the packet + UINT caplen; ///< Length of captured portion. The captured portion can smaller than the + ///< the original packet, because it is possible (with a proper filter) to + ///< instruct the driver to capture only a portion of the packets. + UINT len; ///< Length of the original packet (off wire). +}; + + +#endif + +struct bpf_stat; + +#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices +#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links +#define NMAX_PACKET 65535 + +/*! + \brief Addresses of a network adapter. + + This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with + an adapter. +*/ +typedef struct npf_if_addr +{ + struct sockaddr_storage IPAddress; ///< IP address. + struct sockaddr_storage SubnetMask; ///< Netmask for that address. + struct sockaddr_storage Broadcast; ///< Broadcast address. +}npf_if_addr; + + +#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. +#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. +#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. +#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. + + +typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API +typedef WAN_ADAPTER* PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API + +#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter +#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET +#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card +#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file +#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. +#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card +#define INFO_FLAG_NPFIM_DEVICE 32 + +/*! + \brief Describes an opened network adapter. + + This structure is the most important for the functioning of packet.dll, but the great part of its fields + should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters +*/ +typedef struct _ADAPTER +{ + HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver. + CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened. + int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated + ///< on the wire. + HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter. + ///< It can be passed to standard Win32 functions (like WaitForSingleObject + ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some + ///< data. It is particularly useful in GUI applications that need to wait + ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() + ///< function can be used to define the minimum amount of data in the kernel buffer + ///< that will cause the event to be signalled. + + UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and + ///< ReadEvent will be signaled, also if no packets were captured + CHAR Name[ADAPTER_NAME_LENGTH]; + PWAN_ADAPTER pWanAdapter; + UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. + +#ifdef HAVE_AIRPCAP_API + PAirpcapHandle AirpcapAd; +#endif // HAVE_AIRPCAP_API + +#ifdef HAVE_NPFIM_API + void* NpfImHandle; +#endif // HAVE_NPFIM_API + +#ifdef HAVE_DAG_API + dagc_t* pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter + PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card + struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure + unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry + DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). +#endif // HAVE_DAG_API +} ADAPTER, * LPADAPTER; + +/*! + \brief Structure that contains a group of packets coming from the driver. + + This structure defines the header associated with every packet delivered to the application. +*/ +typedef struct _PACKET +{ + HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications. + OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications. + PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for + ///< details about the organization of the data in this buffer + UINT Length; ///< Length of the buffer + DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data + ///< received by the last call to PacketReceivePacket() + BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications. +} PACKET, * LPPACKET; + +/*! + \brief Structure containing an OID request. + + It is used by the PacketRequest() function to send an OID to the interface card driver. + It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, + the list of the multicast groups defined on it, and so on. +*/ +struct _PACKET_OID_DATA +{ + ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h + ///< for a complete list of valid codes. + ULONG Length; ///< Length of the data field + UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received + ///< from the adapter. +}; +typedef struct _PACKET_OID_DATA PACKET_OID_DATA, * PPACKET_OID_DATA; + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * @} + */ + + /* + BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, + CHAR *Value, + UINT *pValueLen, + CHAR *DefaultVal); + BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, + WCHAR *Value, + UINT *pValueLen, + WCHAR *DefaultVal); + */ + + //--------------------------------------------------------------------------- + // EXPORTED FUNCTIONS + //--------------------------------------------------------------------------- + + PCHAR PacketGetVersion(); + PCHAR PacketGetDriverVersion(); + PCHAR PacketGetDriverName(); + BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject, int nbytes); + BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject, int nwrites); + BOOLEAN PacketSetMode(LPADAPTER AdapterObject, int mode); + BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject, int timeout); + BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program* fp); + BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior); + INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen); + BOOLEAN PacketGetStats(LPADAPTER AdapterObject, struct bpf_stat* s); + BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject, struct bpf_stat* s); + BOOLEAN PacketSetBuff(LPADAPTER AdapterObject, int dim); + BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType* type); + BOOLEAN PacketIsLoopbackAdapter(PCHAR AdapterName); + int PacketIsMonitorModeSupported(PCHAR AdapterName); + int PacketSetMonitorMode(PCHAR AdapterName, int mode); + int PacketGetMonitorMode(PCHAR AdapterName); + LPADAPTER PacketOpenAdapter(PCHAR AdapterName); + BOOLEAN PacketSendPacket(LPADAPTER AdapterObject, LPPACKET pPacket, BOOLEAN Sync); + INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync); + LPPACKET PacketAllocatePacket(void); + VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length); + VOID PacketFreePacket(LPPACKET lpPacket); + BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject, LPPACKET lpPacket, BOOLEAN Sync); + BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject, ULONG Filter); + BOOLEAN PacketGetAdapterNames(PCHAR pStr, PULONG BufferSize); + BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries); + BOOLEAN PacketRequest(LPADAPTER AdapterObject, BOOLEAN Set, PPACKET_OID_DATA OidData); + HANDLE PacketGetReadEvent(LPADAPTER AdapterObject); + BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void* name, int len); + BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks); + BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync); + BOOL PacketStopDriver(); + BOOL PacketStopDriver60(); + VOID PacketCloseAdapter(LPADAPTER lpAdapter); + BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength); + BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags); + PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject); + + // + // Used by PacketStartOemEx + // +#define PACKET_START_OEM_NO_NETMON 0x00000001 + +#ifdef __cplusplus +} +#endif + +#endif //__PACKET32 diff --git a/include/npcap/pcap-bpf.h b/include/npcap/pcap-bpf.h new file mode 100644 index 0000000..ebb64c3 --- /dev/null +++ b/include/npcap/pcap-bpf.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * For backwards compatibility. + * + * Note to OS vendors: do NOT get rid of this file! Some applications + * might expect to be able to include . + */ +#include diff --git a/include/npcap/pcap-namedb.h b/include/npcap/pcap-namedb.h new file mode 100644 index 0000000..d5908c9 --- /dev/null +++ b/include/npcap/pcap-namedb.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * For backwards compatibility. + * + * Note to OS vendors: do NOT get rid of this file! Some applications + * might expect to be able to include . + */ +#include diff --git a/include/npcap/pcap-stdinc.h b/include/npcap/pcap-stdinc.h new file mode 100644 index 0000000..a1be680 --- /dev/null +++ b/include/npcap/pcap-stdinc.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (C) 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef pcap_stdinc_h +#define pcap_stdinc_h + +/* + * Avoids a compiler warning in case this was already defined + * (someone defined _WINSOCKAPI_ when including 'windows.h', in order + * to prevent it from including 'winsock.h') + */ +#ifdef _WINSOCKAPI_ +#undef _WINSOCKAPI_ +#endif + +#include +#include +#include +#include + +#include + +#if defined(_MSC_VER) + /* + * MSVC. + */ + #if _MSC_VER >= 1800 + /* + * VS 2013 or newer; we have . + */ + #include + + #define u_int8_t uint8_t + #define u_int16_t uint16_t + #define u_int32_t uint32_t + #define u_int64_t uint64_t + #else + /* + * Earlier VS; we have to define this stuff ourselves. + */ + #ifndef HAVE_U_INT8_T + typedef unsigned char u_int8_t; + typedef signed char int8_t; + #endif + + #ifndef HAVE_U_INT16_T + typedef unsigned short u_int16_t; + typedef signed short int16_t; + #endif + + #ifndef HAVE_U_INT32_T + typedef unsigned int u_int32_t; + typedef signed int int32_t; + #endif + + #ifndef HAVE_U_INT64_T + #ifdef _MSC_EXTENSIONS + typedef unsigned _int64 u_int64_t; + typedef _int64 int64_t; + #else /* _MSC_EXTENSIONS */ + typedef unsigned long long u_int64_t; + typedef long long int64_t; + #endif + #endif + #endif +#elif defined(__MINGW32__) + #include +#endif + +#endif /* pcap_stdinc_h */ diff --git a/include/npcap/pcap.h b/include/npcap/pcap.h new file mode 100644 index 0000000..174e32d --- /dev/null +++ b/include/npcap/pcap.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * For backwards compatibility. + * + * Note to OS vendors: do NOT get rid of this file! Many applications + * expect to be able to include , and at least some of them + * go through contortions in their configure scripts to try to detect + * OSes that have "helpfully" moved pcap.h to without + * leaving behind a file. + */ +#include diff --git a/include/npcap/pcap/bluetooth.h b/include/npcap/pcap/bluetooth.h new file mode 100644 index 0000000..c5f378a --- /dev/null +++ b/include/npcap/pcap/bluetooth.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006 Paolo Abeni (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * bluetooth data struct + * By Paolo Abeni + */ + +#ifndef lib_pcap_bluetooth_h +#define lib_pcap_bluetooth_h + +/* + * Header prepended libpcap to each bluetooth h4 frame, + * fields are in network byte order + */ +typedef struct _pcap_bluetooth_h4_header { + u_int32_t direction; /* if first bit is set direction is incoming */ +} pcap_bluetooth_h4_header; + +/* + * Header prepended libpcap to each bluetooth linux monitor frame, + * fields are in network byte order + */ +typedef struct _pcap_bluetooth_linux_monitor_header { + u_int16_t adapter_id; + u_int16_t opcode; +} pcap_bluetooth_linux_monitor_header; + + +#endif diff --git a/include/npcap/pcap/bpf.h b/include/npcap/pcap/bpf.h new file mode 100644 index 0000000..78ad890 --- /dev/null +++ b/include/npcap/pcap/bpf.h @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + */ + +/* + * This is libpcap's cut-down version of bpf.h; it includes only + * the stuff needed for the code generator and the userland BPF + * interpreter, and the libpcap APIs for setting filters, etc.. + * + * "pcap-bpf.c" will include the native OS version, as it deals with + * the OS's BPF implementation. + * + * At least two programs found by Google Code Search explicitly includes + * (even though / includes it for you), + * so moving that stuff to would break the build for some + * programs. + */ + +/* + * If we've already included , don't re-define this stuff. + * We assume BSD-style multiple-include protection in , + * which is true of all but the oldest versions of FreeBSD and NetBSD, + * or Tru64 UNIX-style multiple-include protection (or, at least, + * Tru64 UNIX 5.x-style; I don't have earlier versions available to check), + * or AIX-style multiple-include protection (or, at least, AIX 5.x-style; + * I don't have earlier versions available to check), or QNX-style + * multiple-include protection (as per GitHub pull request #394). + * + * We do not check for BPF_MAJOR_VERSION, as that's defined by + * , which is directly or indirectly included in some + * programs that also include pcap.h, and doesn't + * define stuff we need. + * + * This also provides our own multiple-include protection. + */ +#if !defined(_NET_BPF_H_) && !defined(_NET_BPF_H_INCLUDED) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) +#define lib_pcap_bpf_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* BSD style release date */ +#define BPF_RELEASE 199606 + +#ifdef MSDOS /* must be 32-bit */ +typedef long bpf_int32; +typedef unsigned long bpf_u_int32; +#else +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#endif + +/* + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. + * + * Tcpdump's print-pflog.c uses this, so we define it here. + */ +#ifndef __NetBSD__ +#define BPF_ALIGNMENT sizeof(bpf_int32) +#else +#define BPF_ALIGNMENT sizeof(long) +#endif +#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + +/* + * Structure for "pcap_compile()", "pcap_setfilter()", etc.. + */ +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; + +#include + +/* + * The instruction encodings. + * + * Please inform tcpdump-workers@lists.tcpdump.org if you use any + * of the reserved values, so that we can note that they're used + * (and perhaps implement it in the reference BPF implementation + * and encourage its implementation elsewhere). + */ + +/* + * The upper 8 bits of the opcode aren't used. BSD/OS used 0x8000. + */ + +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +/* 0x18 reserved; used by BSD/OS */ +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 +/* 0xc0 reserved; used by BSD/OS */ +/* 0xe0 reserved; used by BSD/OS */ + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_MOD 0x90 +#define BPF_XOR 0xa0 +/* 0xb0 reserved */ +/* 0xc0 reserved */ +/* 0xd0 reserved */ +/* 0xe0 reserved */ +/* 0xf0 reserved */ + +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +/* 0x50 reserved; used on BSD/OS */ +/* 0x60 reserved */ +/* 0x70 reserved */ +/* 0x80 reserved */ +/* 0x90 reserved */ +/* 0xa0 reserved */ +/* 0xb0 reserved */ +/* 0xc0 reserved */ +/* 0xd0 reserved */ +/* 0xe0 reserved */ +/* 0xf0 reserved */ +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 +/* 0x18 reserved */ + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +/* 0x08 reserved */ +/* 0x10 reserved */ +/* 0x18 reserved */ +/* #define BPF_COP 0x20 NetBSD "coprocessor" extensions */ +/* 0x28 reserved */ +/* 0x30 reserved */ +/* 0x38 reserved */ +/* #define BPF_COPX 0x40 NetBSD "coprocessor" extensions */ +/* also used on BSD/OS */ +/* 0x48 reserved */ +/* 0x50 reserved */ +/* 0x58 reserved */ +/* 0x60 reserved */ +/* 0x68 reserved */ +/* 0x70 reserved */ +/* 0x78 reserved */ +#define BPF_TXA 0x80 +/* 0x88 reserved */ +/* 0x90 reserved */ +/* 0x98 reserved */ +/* 0xa0 reserved */ +/* 0xa8 reserved */ +/* 0xb0 reserved */ +/* 0xb8 reserved */ +/* 0xc0 reserved; used on BSD/OS */ +/* 0xc8 reserved */ +/* 0xd0 reserved */ +/* 0xd8 reserved */ +/* 0xe0 reserved */ +/* 0xe8 reserved */ +/* 0xf0 reserved */ +/* 0xf8 reserved */ + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; +}; + +/* + * Auxiliary data, for use when interpreting a filter intended for the + * Linux kernel when the kernel rejects the filter (requiring us to + * run it in userland). It contains VLAN tag information. + */ +struct bpf_aux_data { + u_short vlan_tag_present; + u_short vlan_tag; +}; + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +#if __STDC__ || defined(__cplusplus) +PCAP_API int bpf_validate(const struct bpf_insn *, int); +PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); +extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *); +#else +PCAP_API int bpf_validate(); +PCAP_API u_int bpf_filter(); +extern u_int bpf_filter_with_aux_data(); +#endif + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) */ diff --git a/include/npcap/pcap/can_socketcan.h b/include/npcap/pcap/can_socketcan.h new file mode 100644 index 0000000..68d2a13 --- /dev/null +++ b/include/npcap/pcap/can_socketcan.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_can_socketcan_h +#define lib_pcap_can_socketcan_h + +/* + * SocketCAN header, as per Documentation/networking/can.txt in the + * Linux source. + */ +typedef struct { + u_int32_t can_id; + u_int8_t payload_length; + u_int8_t pad; + u_int8_t reserved1; + u_int8_t reserved2; +} pcap_can_socketcan_hdr; + +#endif diff --git a/include/npcap/pcap/dlt.h b/include/npcap/pcap/dlt.h new file mode 100644 index 0000000..2d74713 --- /dev/null +++ b/include/npcap/pcap/dlt.h @@ -0,0 +1,1340 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + */ + +#ifndef lib_pcap_dlt_h +#define lib_pcap_dlt_h + +/* + * Link-layer header type codes. + * + * Do *NOT* add new values to this list without asking + * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run + * the risk of using a value that's already being used for some other + * purpose, and of having tools that read libpcap-format captures not + * being able to handle captures with your new DLT_ value, with no hope + * that they will ever be changed to do so (as that would destroy their + * ability to read captures using that value for that other purpose). + * + * See + * + * http://www.tcpdump.org/linktypes.html + * + * for detailed descriptions of some of these link-layer header types. + */ + +/* + * These are the types that are the same on all platforms, and that + * have been defined by for ages. + */ +#define DLT_NULL 0 /* BSD loopback encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* 802.5 Token Ring */ +#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are types that are different on some platforms, and that + * have been defined by for ages. We use #ifdefs to + * detect the BSDs that define them differently from the traditional + * libpcap + * + * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, + * but I don't know what the right #define is for BSD/OS. + */ +#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + +#ifdef __OpenBSD__ +#define DLT_RAW 14 /* raw IP */ +#else +#define DLT_RAW 12 /* raw IP */ +#endif + +/* + * Given that the only OS that currently generates BSD/OS SLIP or PPP + * is, well, BSD/OS, arguably everybody should have chosen its values + * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they + * didn't. So it goes. + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#ifndef DLT_SLIP_BSDOS +#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ +#endif +#else +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#endif + +/* + * 17 was used for DLT_PFLOG in OpenBSD; it no longer is. + * + * It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG + * as 117 so that pflog captures would use a link-layer header type + * value that didn't collide with any other values. On all + * platforms other than OpenBSD, we defined DLT_PFLOG as 117, + * and we mapped between LINKTYPE_PFLOG and DLT_PFLOG. + * + * OpenBSD eventually switched to using 117 for DLT_PFLOG as well. + * + * Don't use 17 for anything else. + */ + +/* + * 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and + * Mac OS X; don't use it for anything else. (FreeBSD uses 121, + * which collides with DLT_HHDLC, even though it doesn't use 18 + * for anything and doesn't appear to have ever used it for anything.) + * + * We define it as 18 on those platforms; it is, unfortunately, used + * for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC + * in general. As the packet format for it, like that for + * DLT_PFLOG, is not only OS-dependent but OS-version-dependent, + * we don't support printing it in tcpdump except on OSes that + * have the relevant header files, so it's not that useful on + * other platforms. + */ +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#define DLT_PFSYNC 18 +#endif + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * Apparently Redback uses this for its SmartEdge 400/800. I hope + * nobody else decided to use it, too. + */ +#define DLT_REDBACK_SMARTEDGE 32 + +/* + * These values are defined by NetBSD; other platforms should refrain from + * using them for other purposes, so that NetBSD savefiles with link + * types of 50 or 51 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + +/* + * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses + * a link-layer type of 99 for the tcpdump it supplies. The link-layer + * header has 6 bytes of unknown data, something that appears to be an + * Ethernet type, and 36 bytes that appear to be 0 in at least one capture + * I've seen. + */ +#define DLT_SYMANTEC_FIREWALL 99 + +/* + * Values between 100 and 103 are used in capture file headers as + * link-layer header type LINKTYPE_ values corresponding to DLT_ types + * that differ between platforms; don't use those values for new DLT_ + * new types. + */ + +/* + * Values starting with 104 are used for newly-assigned link-layer + * header type values; for those link-layer header types, the DLT_ + * value returned by pcap_datalink() and passed to pcap_open_dead(), + * and the LINKTYPE_ value that appears in capture files, are the + * same. + * + * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is + * the highest such value. + */ +#define DLT_MATCHING_MIN 104 + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, + * except when it isn't. (I.e., sometimes it's just raw IP, and + * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, + * so that we don't have to worry about the link-layer header.) + */ + +/* + * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides + * with other values. + * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header + * (DLCI, etc.). + */ +#define DLT_FRELAY 107 + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so + * we don't use 12 for it in OSes other than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_LOOP 12 +#else +#define DLT_LOOP 108 +#endif + +/* + * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's + * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other + * than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_ENC 13 +#else +#define DLT_ENC 109 +#endif + +/* + * Values between 110 and 112 are reserved for use in capture file headers + * as link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ types + * other than the corresponding DLT_ types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * Apple LocalTalk hardware. + */ +#define DLT_LTALK 114 + +/* + * Acorn Econet. + */ +#define DLT_ECONET 115 + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define DLT_IPFILTER 116 + +/* + * OpenBSD DLT_PFLOG. + */ +#define DLT_PFLOG 117 + +/* + * Registered for Cisco-internal use. + */ +#define DLT_CISCO_IOS 118 + +/* + * For 802.11 cards using the Prism II chips, with a link-layer + * header including Prism monitor mode information plus an 802.11 + * header. + */ +#define DLT_PRISM_HEADER 119 + +/* + * Reserved for Aironet 802.11 cards, with an Aironet link-layer header + * (see Doug Ambrisko's FreeBSD patches). + */ +#define DLT_AIRONET_HEADER 120 + +/* + * Sigh. + * + * 121 was reserved for Siemens HiPath HDLC on 2002-01-25, as + * requested by Tomas Kukosa. + * + * On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that + * assigned 121 as DLT_PFSYNC. In current versions, its libpcap + * does DLT_ <-> LINKTYPE_ mapping, mapping DLT_PFSYNC to a + * LINKTYPE_PFSYNC value of 246, so it should write out DLT_PFSYNC + * dump files with 246 as the link-layer header type. (Earlier + * versions might not have done mapping, in which case they would + * have written them out with a link-layer header type of 121.) + * + * OpenBSD, from which pf came, however, uses 18 for DLT_PFSYNC; + * its libpcap does no DLT_ <-> LINKTYPE_ mapping, so it would + * write out DLT_PFSYNC dump files with use 18 as the link-layer + * header type. + * + * NetBSD, DragonFly BSD, and Darwin also use 18 for DLT_PFSYNC; in + * current versions, their libpcaps do DLT_ <-> LINKTYPE_ mapping, + * mapping DLT_PFSYNC to a LINKTYPE_PFSYNC value of 246, so they + * should write out DLT_PFSYNC dump files with 246 as the link-layer + * header type. (Earlier versions might not have done mapping, + * in which case they'd work the same way OpenBSD does, writing + * them out with a link-layer header type of 18.) + * + * We'll define DLT_PFSYNC as: + * + * 18 on NetBSD, OpenBSD, DragonFly BSD, and Darwin; + * + * 121 on FreeBSD; + * + * 246 everywhere else. + * + * We'll define DLT_HHDLC as 121 on everything except for FreeBSD; + * anybody who wants to compile, on FreeBSD, code that uses DLT_HHDLC + * is out of luck. + * + * We'll define LINKTYPE_PFSYNC as 246 on *all* platforms, so that + * savefiles written using *this* code won't use 18 or 121 for PFSYNC, + * they'll all use 246. + * + * Code that uses pcap_datalink() to determine the link-layer header + * type of a savefile won't, when built and run on FreeBSD, be able + * to distinguish between LINKTYPE_PFSYNC and LINKTYPE_HHDLC capture + * files, as pcap_datalink() will give 121 for both of them. Code + * that doesn't, such as the code in Wireshark, will be able to + * distinguish between them. + * + * FreeBSD's libpcap won't map a link-layer header type of 18 - i.e., + * DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD, + * DragonFly BSD, and OS X - to DLT_PFSYNC, so code built with FreeBSD's + * libpcap won't treat those files as DLT_PFSYNC files. + * + * Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC; + * this means they can read DLT_HHDLC files, if any exist, but won't + * treat pcap files written by any older versions of FreeBSD libpcap that + * didn't map to 246 as DLT_PFSYNC files. + */ +#ifdef __FreeBSD__ +#define DLT_PFSYNC 121 +#else +#define DLT_HHDLC 121 +#endif + +/* + * This is for RFC 2625 IP-over-Fibre Channel. + * + * This is not for use with raw Fibre Channel, where the link-layer + * header starts with a Fibre Channel frame header; it's for IP-over-FC, + * where the link-layer header starts with an RFC 2625 Network_Header + * field. + */ +#define DLT_IP_OVER_FC 122 + +/* + * This is for Full Frontal ATM on Solaris with SunATM, with a + * pseudo-header followed by an AALn PDU. + * + * There may be other forms of Full Frontal ATM on other OSes, + * with different pseudo-headers. + * + * If ATM software returns a pseudo-header with VPI/VCI information + * (and, ideally, packet type information, e.g. signalling, ILMI, + * LANE, LLC-multiplexed traffic, etc.), it should not use + * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump + * and the like don't have to infer the presence or absence of a + * pseudo-header and the form of the pseudo-header. + */ +#define DLT_SUNATM 123 /* Solaris+SunATM */ + +/* + * Reserved as per request from Kent Dahlgren + * for private use. + */ +#define DLT_RIO 124 /* RapidIO */ +#define DLT_PCI_EXP 125 /* PCI Express */ +#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + +/* + * Header for 802.11 plus a number of bits of link-layer information + * including radio information, used by some recent BSD drivers as + * well as the madwifi Atheros driver for Linux. + */ +#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + +/* + * Reserved for the TZSP encapsulation, as per request from + * Chris Waters + * TZSP is a generic encapsulation for any other link type, + * which includes a means to include meta-information + * with the packet, e.g. signal strength and channel + * for 802.11 packets. + */ +#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + +/* + * BSD's ARCNET headers have the source host, destination host, + * and type at the beginning of the packet; that's what's handed + * up to userland via BPF. + * + * Linux's ARCNET headers, however, have a 2-byte offset field + * between the host IDs and the type; that's what's handed up + * to userland via PF_PACKET sockets. + * + * We therefore have to have separate DLT_ values for them. + */ +#define DLT_ARCNET_LINUX 129 /* ARCNET */ + +/* + * Juniper-private data link types, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MLPPP 130 +#define DLT_JUNIPER_MLFR 131 +#define DLT_JUNIPER_ES 132 +#define DLT_JUNIPER_GGSN 133 +#define DLT_JUNIPER_MFR 134 +#define DLT_JUNIPER_ATM2 135 +#define DLT_JUNIPER_SERVICES 136 +#define DLT_JUNIPER_ATM1 137 + +/* + * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund + * . The header that's presented is an Ethernet-like + * header: + * + * #define FIREWIRE_EUI64_LEN 8 + * struct firewire_header { + * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + * u_char firewire_shost[FIREWIRE_EUI64_LEN]; + * u_short firewire_type; + * }; + * + * with "firewire_type" being an Ethernet type value, rather than, + * for example, raw GASP frames being handed up. + */ +#define DLT_APPLE_IP_OVER_IEEE1394 138 + +/* + * Various SS7 encapsulations, as per a request from Jeff Morriss + * and subsequent discussions. + */ +#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ +#define DLT_MTP2 140 /* MTP2, without pseudo-header */ +#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ +#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + +/* + * DOCSIS MAC frames. + */ +#define DLT_DOCSIS 143 + +/* + * Linux-IrDA packets. Protocol defined at http://www.irda.org. + * Those packets include IrLAP headers and above (IrLMP...), but + * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy + * framing can be handled by the hardware and depend on the bitrate. + * This is exactly the format you would get capturing on a Linux-IrDA + * interface (irdaX), but not on a raw serial port. + * Note the capture is done in "Linux-cooked" mode, so each packet include + * a fake packet header (struct sll_header). This is because IrDA packet + * decoding is dependant on the direction of the packet (incomming or + * outgoing). + * When/if other platform implement IrDA capture, we may revisit the + * issue and define a real DLT_IRDA... + * Jean II + */ +#define DLT_LINUX_IRDA 144 + +/* + * Reserved for IBM SP switch and IBM Next Federation switch. + */ +#define DLT_IBM_SP 145 +#define DLT_IBM_SN 146 + +/* + * Reserved for private use. If you have some link-layer header type + * that you want to use within your organization, with the capture files + * using that link-layer header type not ever be sent outside your + * organization, you can use these values. + * + * No libpcap release will use these for any purpose, nor will any + * tcpdump release use them, either. + * + * Do *NOT* use these in capture files that you expect anybody not using + * your private versions of capture-file-reading tools to read; in + * particular, do *NOT* use them in products, otherwise you may find that + * people won't be able to use tcpdump, or snort, or Ethereal, or... to + * read capture files from your firewall/intrusion detection/traffic + * monitoring/etc. appliance, or whatever product uses that DLT_ value, + * and you may also find that the developers of those applications will + * not accept patches to let them read those files. + * + * Also, do not use them if somebody might send you a capture using them + * for *their* private type and tools using them for *your* private type + * would have to read them. + * + * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, + * as per the comment above, and use the type you're given. + */ +#define DLT_USER0 147 +#define DLT_USER1 148 +#define DLT_USER2 149 +#define DLT_USER3 150 +#define DLT_USER4 151 +#define DLT_USER5 152 +#define DLT_USER6 153 +#define DLT_USER7 154 +#define DLT_USER8 155 +#define DLT_USER9 156 +#define DLT_USER10 157 +#define DLT_USER11 158 +#define DLT_USER12 159 +#define DLT_USER13 160 +#define DLT_USER14 161 +#define DLT_USER15 162 + +/* + * For future use with 802.11 captures - defined by AbsoluteValue + * Systems to store a number of bits of link-layer information + * including radio information: + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt + * + * but it might be used by some non-AVS drivers now or in the + * future. + */ +#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MONITOR 164 + +/* + * BACnet MS/TP frames. + */ +#define DLT_BACNET_MS_TP 165 + +/* + * Another PPP variant as per request from Karsten Keil . + * + * This is used in some OSes to allow a kernel socket filter to distinguish + * between incoming and outgoing packets, on a socket intended to + * supply pppd with outgoing packets so it can do dial-on-demand and + * hangup-on-lack-of-demand; incoming packets are filtered out so they + * don't cause pppd to hold the connection up (you don't want random + * input packets such as port scans, packets from old lost connections, + * etc. to force the connection to stay up). + * + * The first byte of the PPP header (0xff03) is modified to accomodate + * the direction - 0x00 = IN, 0x01 = OUT. + */ +#define DLT_PPP_PPPD 166 + +/* + * Names for backwards compatibility with older versions of some PPP + * software; new software should use DLT_PPP_PPPD. + */ +#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD +#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, cookies, etc.. + */ +#define DLT_JUNIPER_PPPOE 167 +#define DLT_JUNIPER_PPPOE_ATM 168 + +#define DLT_GPRS_LLC 169 /* GPRS LLC */ +#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ +#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + +/* + * Requested by Oolan Zimmer for use in Gcom's T1/E1 line + * monitoring equipment. + */ +#define DLT_GCOM_T1E1 172 +#define DLT_GCOM_SERIAL 173 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_ is used + * for internal communication to Physical Interface Cards (PIC) + */ +#define DLT_JUNIPER_PIC_PEER 174 + +/* + * Link types requested by Gregor Maier of Endace + * Measurement Systems. They add an ERF header (see + * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * the link-layer header. + */ +#define DLT_ERF_ETH 175 /* Ethernet */ +#define DLT_ERF_POS 176 /* Packet-over-SONET */ + +/* + * Requested by Daniele Orlandi for raw LAPD + * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header + * includes additional information before the LAPD header, so it's + * not necessarily a generic LAPD header. + */ +#define DLT_LINUX_LAPD 177 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ are used for prepending meta-information + * like interface index, interface name + * before standard Ethernet, PPP, Frelay & C-HDLC Frames + */ +#define DLT_JUNIPER_ETHER 178 +#define DLT_JUNIPER_PPP 179 +#define DLT_JUNIPER_FRELAY 180 +#define DLT_JUNIPER_CHDLC 181 + +/* + * Multi Link Frame Relay (FRF.16) + */ +#define DLT_MFR 182 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * voice Adapter Card (PIC) + */ +#define DLT_JUNIPER_VP 183 + +/* + * Arinc 429 frames. + * DLT_ requested by Gianluca Varenni . + * Every frame contains a 32bit A429 label. + * More documentation on Arinc 429 can be found at + * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + */ +#define DLT_A429 184 + +/* + * Arinc 653 Interpartition Communication messages. + * DLT_ requested by Gianluca Varenni . + * Please refer to the A653-1 standard for more information. + */ +#define DLT_A653_ICM 185 + +/* + * This used to be "USB packets, beginning with a USB setup header; + * requested by Paolo Abeni ." + * + * However, that header didn't work all that well - it left out some + * useful information - and was abandoned in favor of the DLT_USB_LINUX + * header. + * + * This is now used by FreeBSD for its BPF taps for USB; that has its + * own headers. So it is written, so it is done. + * + * For source-code compatibility, we also define DLT_USB to have this + * value. We do it numerically so that, if code that includes this + * file (directly or indirectly) also includes an OS header that also + * defines DLT_USB as 186, we don't get a redefinition warning. + * (NetBSD 7 does that.) + */ +#define DLT_USB_FREEBSD 186 +#define DLT_USB 186 + +/* + * Bluetooth HCI UART transport layer (part H:4); requested by + * Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4 187 + +/* + * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz + * . + */ +#define DLT_IEEE802_16_MAC_CPS 188 + +/* + * USB packets, beginning with a Linux USB header; requested by + * Paolo Abeni . + */ +#define DLT_USB_LINUX 189 + +/* + * Controller Area Network (CAN) v. 2.0B packets. + * DLT_ requested by Gianluca Varenni . + * Used to dump CAN packets coming from a CAN Vector board. + * More documentation on the CAN v2.0B frames can be found at + * http://www.can-cia.org/downloads/?269 + */ +#define DLT_CAN20B 190 + +/* + * IEEE 802.15.4, with address fields padded, as is done by Linux + * drivers; requested by Juergen Schimmer. + */ +#define DLT_IEEE802_15_4_LINUX 191 + +/* + * Per Packet Information encapsulated packets. + * DLT_ requested by Gianluca Varenni . + */ +#define DLT_PPI 192 + +/* + * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; + * requested by Charles Clancy. + */ +#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * integrated service module (ISM). + */ +#define DLT_JUNIPER_ISM 194 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing); requested by Mikko Saarnivala . + * For this one, we expect the FCS to be present at the end of the frame; + * if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used. + */ +#define DLT_IEEE802_15_4 195 + +/* + * Various link-layer types, with a pseudo-header, for SITA + * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). + */ +#define DLT_SITA 196 + +/* + * Various link-layer types, with a pseudo-header, for Endace DAG cards; + * encapsulates Endace ERF records. Requested by Stephen Donnelly + * . + */ +#define DLT_ERF 197 + +/* + * Special header prepended to Ethernet packets when capturing from a + * u10 Networks board. Requested by Phil Mulholland + * . + */ +#define DLT_RAIF1 198 + +/* + * IPMB packet for IPMI, beginning with the I2C slave address, followed + * by the netFn and LUN, etc.. Requested by Chanthy Toeung + * . + */ +#define DLT_IPMB 199 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for capturing data on a secure tunnel interface. + */ +#define DLT_JUNIPER_ST 200 + +/* + * Bluetooth HCI UART transport layer (part H:4), with pseudo-header + * that includes direction information; requested by Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + +/* + * AX.25 packet with a 1-byte KISS header; see + * + * http://www.ax25.net/kiss.htm + * + * as per Richard Stearn . + */ +#define DLT_AX25_KISS 202 + +/* + * LAPD packets from an ISDN channel, starting with the address field, + * with no pseudo-header. + * Requested by Varuna De Silva . + */ +#define DLT_LAPD 203 + +/* + * Variants of various link-layer headers, with a one-byte direction + * pseudo-header prepended - zero means "received by this host", + * non-zero (any non-zero value) means "sent by this host" - as per + * Will Barker . + */ +#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ +#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ +#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ +#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + +/* + * 208 is reserved for an as-yet-unspecified proprietary link-layer + * type, as requested by Will Barker. + */ + +/* + * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman + * . + */ +#define DLT_IPMB_LINUX 209 + +/* + * FlexRay automotive bus - http://www.flexray.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_FLEXRAY 210 + +/* + * Media Oriented Systems Transport (MOST) bus for multimedia + * transport - http://www.mostcooperation.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_MOST 211 + +/* + * Local Interconnect Network (LIN) bus for vehicle networks - + * http://www.lin-subbus.org/ - as requested by Hannes Kaelber + * . + */ +#define DLT_LIN 212 + +/* + * X2E-private data link type used for serial line capture, + * as requested by Hannes Kaelber . + */ +#define DLT_X2E_SERIAL 213 + +/* + * X2E-private data link type used for the Xoraya data logger + * family, as requested by Hannes Kaelber . + */ +#define DLT_X2E_XORAYA 214 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), but with the PHY-level data for non-ASK PHYs (4 octets + * of 0 as preamble, one octet of SFD, one octet of frame length+ + * reserved bit, and then the MAC-layer data, starting with the + * frame control field). + * + * Requested by Max Filippov . + */ +#define DLT_IEEE802_15_4_NONASK_PHY 215 + +/* + * David Gibson requested this for + * captures from the Linux kernel /dev/input/eventN devices. This + * is used to communicate keystrokes and mouse movements from the + * Linux kernel to display systems, such as Xorg. + */ +#define DLT_LINUX_EVDEV 216 + +/* + * GSM Um and Abis interfaces, preceded by a "gsmtap" header. + * + * Requested by Harald Welte . + */ +#define DLT_GSMTAP_UM 217 +#define DLT_GSMTAP_ABIS 218 + +/* + * MPLS, with an MPLS label as the link-layer header. + * Requested by Michele Marchetto on behalf + * of OpenBSD. + */ +#define DLT_MPLS 219 + +/* + * USB packets, beginning with a Linux USB header, with the USB header + * padded to 64 bytes; required for memory-mapped access. + */ +#define DLT_USB_LINUX_MMAPPED 220 + +/* + * DECT packets, with a pseudo-header; requested by + * Matthias Wenzel . + */ +#define DLT_DECT 221 + +/* + * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" + * Date: Mon, 11 May 2009 11:18:30 -0500 + * + * DLT_AOS. We need it for AOS Space Data Link Protocol. + * I have already written dissectors for but need an OK from + * legal before I can submit a patch. + * + */ +#define DLT_AOS 222 + +/* + * Wireless HART (Highway Addressable Remote Transducer) + * From the HART Communication Foundation + * IES/PAS 62591 + * + * Requested by Sam Roberts . + */ +#define DLT_WIHART 223 + +/* + * Fibre Channel FC-2 frames, beginning with a Frame_Header. + * Requested by Kahou Lei . + */ +#define DLT_FC_2 224 + +/* + * Fibre Channel FC-2 frames, beginning with an encoding of the + * SOF, and ending with an encoding of the EOF. + * + * The encodings represent the frame delimiters as 4-byte sequences + * representing the corresponding ordered sets, with K28.5 + * represented as 0xBC, and the D symbols as the corresponding + * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, + * is represented as 0xBC 0xB5 0x55 0x55. + * + * Requested by Kahou Lei . + */ +#define DLT_FC_2_WITH_FRAME_DELIMS 225 + +/* + * Solaris ipnet pseudo-header; requested by Darren Reed . + * + * The pseudo-header starts with a one-byte version number; for version 2, + * the pseudo-header is: + * + * struct dl_ipnetinfo { + * u_int8_t dli_version; + * u_int8_t dli_family; + * u_int16_t dli_htype; + * u_int32_t dli_pktlen; + * u_int32_t dli_ifindex; + * u_int32_t dli_grifindex; + * u_int32_t dli_zsrc; + * u_int32_t dli_zdst; + * }; + * + * dli_version is 2 for the current version of the pseudo-header. + * + * dli_family is a Solaris address family value, so it's 2 for IPv4 + * and 26 for IPv6. + * + * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing + * packets, and 2 for packets arriving from another zone on the same + * machine. + * + * dli_pktlen is the length of the packet data following the pseudo-header + * (so the captured length minus dli_pktlen is the length of the + * pseudo-header, assuming the entire pseudo-header was captured). + * + * dli_ifindex is the interface index of the interface on which the + * packet arrived. + * + * dli_grifindex is the group interface index number (for IPMP interfaces). + * + * dli_zsrc is the zone identifier for the source of the packet. + * + * dli_zdst is the zone identifier for the destination of the packet. + * + * A zone number of 0 is the global zone; a zone number of 0xffffffff + * means that the packet arrived from another host on the network, not + * from another zone on the same machine. + * + * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates + * which of those it is. + */ +#define DLT_IPNET 226 + +/* + * CAN (Controller Area Network) frames, with a pseudo-header as supplied + * by Linux SocketCAN, and with multi-byte numerical fields in that header + * in big-endian byte order. + * + * See Documentation/networking/can.txt in the Linux source. + * + * Requested by Felix Obenhuber . + */ +#define DLT_CAN_SOCKETCAN 227 + +/* + * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies + * whether it's v4 or v6. Requested by Darren Reed . + */ +#define DLT_IPV4 228 +#define DLT_IPV6 229 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), and with no FCS at the end of the frame; requested by + * Jon Smirl . + */ +#define DLT_IEEE802_15_4_NOFCS 230 + +/* + * Raw D-Bus: + * + * http://www.freedesktop.org/wiki/Software/dbus + * + * messages: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages + * + * starting with the endianness flag, followed by the message type, etc., + * but without the authentication handshake before the message sequence: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * + * Requested by Martin Vidner . + */ +#define DLT_DBUS 231 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_VS 232 +#define DLT_JUNIPER_SRX_E2E 233 +#define DLT_JUNIPER_FIBRECHANNEL 234 + +/* + * DVB-CI (DVB Common Interface for communication between a PC Card + * module and a DVB receiver). See + * + * http://www.kaiser.cx/pcap-dvbci.html + * + * for the specification. + * + * Requested by Martin Kaiser . + */ +#define DLT_DVB_CI 235 + +/* + * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but + * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel + * . + */ +#define DLT_MUX27010 236 + +/* + * STANAG 5066 D_PDUs. Requested by M. Baris Demiray + * . + */ +#define DLT_STANAG_5066_D_PDU 237 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_ATM_CEMIC 238 + +/* + * NetFilter LOG messages + * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) + * + * Requested by Jakub Zawadzki + */ +#define DLT_NFLOG 239 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and always + * with the payload including the FCS, as supplied by their + * netANALYZER hardware and software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER 240 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and FCS and + * with the Ethernet header preceded by 7 bytes of preamble and + * 1 byte of SFD, as supplied by their netANALYZER hardware and + * software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER_TRANSPARENT 241 + +/* + * IP-over-InfiniBand, as specified by RFC 4391. + * + * Requested by Petr Sumbera . + */ +#define DLT_IPOIB 242 + +/* + * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). + * + * Requested by Guy Martin . + */ +#define DLT_MPEG_2_TS 243 + +/* + * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as + * used by their ng40 protocol tester. + * + * Requested by Jens Grimmer . + */ +#define DLT_NG40 244 + +/* + * Pseudo-header giving adapter number and flags, followed by an NFC + * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, + * as specified by NFC Forum Logical Link Control Protocol Technical + * Specification LLCP 1.1. + * + * Requested by Mike Wakerly . + */ +#define DLT_NFC_LLCP 245 + +/* + * 246 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. + * + * DLT_PFSYNC has different values on different platforms, and all of + * them collide with something used elsewhere. On platforms that + * don't already define it, define it as 246. + */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) +#define DLT_PFSYNC 246 +#endif + +/* + * Raw InfiniBand packets, starting with the Local Routing Header. + * + * Requested by Oren Kladnitsky . + */ +#define DLT_INFINIBAND 247 + +/* + * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). + * + * Requested by Michael Tuexen . + */ +#define DLT_SCTP 248 + +/* + * USB packets, beginning with a USBPcap header. + * + * Requested by Tomasz Mon + */ +#define DLT_USBPCAP 249 + +/* + * Schweitzer Engineering Laboratories "RTAC" product serial-line + * packets. + * + * Requested by Chris Bontje . + */ +#define DLT_RTAC_SERIAL 250 + +/* + * Bluetooth Low Energy air interface link-layer packets. + * + * Requested by Mike Kershaw . + */ +#define DLT_BLUETOOTH_LE_LL 251 + +/* + * DLT type for upper-protocol layer PDU saves from wireshark. + * + * the actual contents are determined by two TAGs stored with each + * packet: + * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the + * original packet. + * + * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector + * that can make sense of the data stored. + */ +#define DLT_WIRESHARK_UPPER_PDU 252 + +/* + * DLT type for the netlink protocol (nlmon devices). + */ +#define DLT_NETLINK 253 + +/* + * Bluetooth Linux Monitor headers for the BlueZ stack. + */ +#define DLT_BLUETOOTH_LINUX_MONITOR 254 + +/* + * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as + * captured by Ubertooth. + */ +#define DLT_BLUETOOTH_BREDR_BB 255 + +/* + * Bluetooth Low Energy link layer packets, as captured by Ubertooth. + */ +#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 + +/* + * PROFIBUS data link layer. + */ +#define DLT_PROFIBUS_DL 257 + +/* + * Apple's DLT_PKTAP headers. + * + * Sadly, the folks at Apple either had no clue that the DLT_USERn values + * are for internal use within an organization and partners only, and + * didn't know that the right way to get a link-layer header type is to + * ask tcpdump.org for one, or knew and didn't care, so they just + * used DLT_USER2, which causes problems for everything except for + * their version of tcpdump. + * + * So I'll just give them one; hopefully this will show up in a + * libpcap release in time for them to get this into 10.10 Big Sur + * or whatever Mavericks' successor is called. LINKTYPE_PKTAP + * will be 258 *even on OS X*; that is *intentional*, so that + * PKTAP files look the same on *all* OSes (different OSes can have + * different numerical values for a given DLT_, but *MUST NOT* have + * different values for what goes in a file, as files can be moved + * between OSes!). + * + * When capturing, on a system with a Darwin-based OS, on a device + * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this + * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, + * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, + * binary compatibility with Mavericks is preserved for programs using + * this version of libpcap. This does mean that if you were using + * DLT_USER2 for some capture device on OS X, you can't do so with + * this version of libpcap, just as you can't with Apple's libpcap - + * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't + * be able to distinguish between PKTAP and whatever you were using + * DLT_USER2 for. + * + * If the program saves the capture to a file using this version of + * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be + * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. + * That way, the file will *not* be a DLT_USER2 file. That means + * that the latest version of tcpdump, when built with this version + * of libpcap, and sufficiently recent versions of Wireshark will + * be able to read those files and interpret them correctly; however, + * Apple's version of tcpdump in OS X 10.9 won't be able to handle + * them. (Hopefully, Apple will pick up this version of libpcap, + * and the corresponding version of tcpdump, so that tcpdump will + * be able to handle the old LINKTYPE_USER2 captures *and* the new + * LINKTYPE_PKTAP captures.) + */ +#ifdef __APPLE__ +#define DLT_PKTAP DLT_USER2 +#else +#define DLT_PKTAP 258 +#endif + +/* + * Ethernet packets preceded by a header giving the last 6 octets + * of the preamble specified by 802.3-2012 Clause 65, section + * 65.1.3.2 "Transmit". + */ +#define DLT_EPON 259 + +/* + * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" + * in the PICMG HPM.2 specification. + */ +#define DLT_IPMI_HPM_2 260 + +/* + * per Joshua Wright , formats for Zwave captures. + */ +#define DLT_ZWAVE_R1_R2 261 +#define DLT_ZWAVE_R3 262 + +/* + * per Steve Karg , formats for Wattstopper + * Digital Lighting Management room bus serial protocol captures. + */ +#define DLT_WATTSTOPPER_DLM 263 + +/* + * ISO 14443 contactless smart card messages. + */ +#define DLT_ISO_14443 264 + +/* + * Radio data system (RDS) groups. IEC 62106. + * Per Jonathan Brucker . + */ +#define DLT_RDS 265 + +/* + * In case the code that includes this file (directly or indirectly) + * has also included OS files that happen to define DLT_MATCHING_MAX, + * with a different value (perhaps because that OS hasn't picked up + * the latest version of our DLT definitions), we undefine the + * previous value of DLT_MATCHING_MAX. + */ +#ifdef DLT_MATCHING_MAX +#undef DLT_MATCHING_MAX +#endif +#define DLT_MATCHING_MAX 265 /* highest value in the "matching" range */ + +/* + * DLT and savefile link type values are split into a class and + * a member of that class. A class value of 0 indicates a regular + * DLT_/LINKTYPE_ value. + */ +#define DLT_CLASS(x) ((x) & 0x03ff0000) + +/* + * NetBSD-specific generic "raw" link type. The class value indicates + * that this is the generic raw type, and the lower 16 bits are the + * address family we're dealing with. Those values are NetBSD-specific; + * do not assume that they correspond to AF_ values for your operating + * system. + */ +#define DLT_CLASS_NETBSD_RAWAF 0x02240000 +#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) +#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) +#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + +#endif /* !defined(lib_pcap_dlt_h) */ diff --git a/include/npcap/pcap/export-defs.h b/include/npcap/pcap/export-defs.h new file mode 100644 index 0000000..a235057 --- /dev/null +++ b/include/npcap/pcap/export-defs.h @@ -0,0 +1,108 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_export_defs_h +#define lib_pcap_export_defs_h + +/* + * PCAP_API_DEF must be used when defining *data* exported from + * libpcap. It can be used when defining *functions* exported + * from libpcap, but it doesn't have to be used there. It + * should not be used in declarations in headers. + * + * PCAP_API must be used when *declaring* data or functions + * exported from libpcap; PCAP_API_DEF won't work on all platforms. + */ + +/* + * Check whether this is GCC major.minor or a later release, or some + * compiler that claims to be "just like GCC" of that version or a + * later release. + */ +#define IS_AT_LEAST_GNUC_VERSION(major, minor) \ + (defined(__GNUC__) && \ + (__GNUC__ > (major) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))) + +#if defined(_WIN32) + #ifdef BUILDING_PCAP + /* + * We're compiling libpcap, so we should export functions in our + * API. + */ + #define PCAP_API_DEF __declspec(dllexport) + #else + #define PCAP_API_DEF __declspec(dllimport) + #endif +#elif defined(MSDOS) + /* XXX - does this need special treatment? */ + #define PCAP_API_DEF +#else /* UN*X */ + #ifdef BUILDING_PCAP + /* + * We're compiling libpcap, so we should export functions in our API. + * The compiler might be configured not to export functions from a + * shared library by default, so we might have to explicitly mark + * functions as exported. + */ + #if IS_AT_LEAST_GNUC_VERSION(3, 4) + /* + * GCC 3.4 or later, or some compiler asserting compatibility with + * GCC 3.4 or later, so we have __attribute__((visibility()). + */ + #define PCAP_API_DEF __attribute__((visibility("default"))) + #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) + /* + * Sun C 5.5 or later, so we have __global. + * (Sun C 5.9 and later also have __attribute__((visibility()), + * but there's no reason to prefer it with Sun C.) + */ + #define PCAP_API_DEF __global + #else + /* + * We don't have anything to say. + */ + #define PCAP_API_DEF + #endif + #else + /* + * We're not building libpcap. + */ + #define PCAP_API_DEF + #endif +#endif /* _WIN32/MSDOS/UN*X */ + +#define PCAP_API PCAP_API_DEF extern + +#endif /* lib_pcap_export_defs_h */ diff --git a/include/npcap/pcap/ipnet.h b/include/npcap/pcap/ipnet.h new file mode 100644 index 0000000..5330847 --- /dev/null +++ b/include/npcap/pcap/ipnet.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */ +#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */ + +#define IPNET_OUTBOUND 1 +#define IPNET_INBOUND 2 diff --git a/include/npcap/pcap/namedb.h b/include/npcap/pcap/namedb.h new file mode 100644 index 0000000..73fb40a --- /dev/null +++ b/include/npcap/pcap/namedb.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_namedb_h +#define lib_pcap_namedb_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * As returned by the pcap_next_etherent() + * XXX this stuff doesn't belong in this interface, but this + * library already must do name to address translation, so + * on systems that don't have support for /etc/ethers, we + * export these hooks since they're already being used by + * some applications (such as tcpdump) and already being + * marked as exported in some OSes offering libpcap (such + * as Debian). + */ +struct pcap_etherent { + u_char addr[6]; + char name[122]; +}; +#ifndef PCAP_ETHERS_FILE +#define PCAP_ETHERS_FILE "/etc/ethers" +#endif +PCAP_API struct pcap_etherent *pcap_next_etherent(FILE *); +PCAP_API u_char *pcap_ether_hostton(const char*); +PCAP_API u_char *pcap_ether_aton(const char *); + +PCAP_API bpf_u_int32 **pcap_nametoaddr(const char *); +#ifdef INET6 +PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *); +#endif +PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *); + +PCAP_API int pcap_nametoport(const char *, int *, int *); +PCAP_API int pcap_nametoportrange(const char *, int *, int *, int *); +PCAP_API int pcap_nametoproto(const char *); +PCAP_API int pcap_nametoeproto(const char *); +PCAP_API int pcap_nametollc(const char *); +/* + * If a protocol is unknown, PROTO_UNDEF is returned. + * Also, pcap_nametoport() returns the protocol along with the port number. + * If there are ambiguous entried in /etc/services (i.e. domain + * can be either tcp or udp) PROTO_UNDEF is returned. + */ +#define PROTO_UNDEF -1 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/npcap/pcap/nflog.h b/include/npcap/pcap/nflog.h new file mode 100644 index 0000000..a3867cd --- /dev/null +++ b/include/npcap/pcap/nflog.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, Petar Alilovic, + * Faculty of Electrical Engineering and Computing, University of Zagreb + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef lib_pcap_nflog_h +#define lib_pcap_nflog_h + +/* + * Structure of an NFLOG header and TLV parts, as described at + * http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html + * + * The NFLOG header is big-endian. + * + * The TLV length and type are in host byte order. The value is either + * big-endian or is an array of bytes in some externally-specified byte + * order (text string, link-layer address, link-layer header, packet + * data, etc.). + */ +typedef struct nflog_hdr { + u_int8_t nflog_family; /* address family */ + u_int8_t nflog_version; /* version */ + u_int16_t nflog_rid; /* resource ID */ +} nflog_hdr_t; + +typedef struct nflog_tlv { + u_int16_t tlv_length; /* tlv length */ + u_int16_t tlv_type; /* tlv type */ + /* value follows this */ +} nflog_tlv_t; + +typedef struct nflog_packet_hdr { + u_int16_t hw_protocol; /* hw protocol */ + u_int8_t hook; /* netfilter hook */ + u_int8_t pad; /* padding to 32 bits */ +} nflog_packet_hdr_t; + +typedef struct nflog_hwaddr { + u_int16_t hw_addrlen; /* address length */ + u_int16_t pad; /* padding to 32-bit boundary */ + u_int8_t hw_addr[8]; /* address, up to 8 bytes */ +} nflog_hwaddr_t; + +typedef struct nflog_timestamp { + u_int64_t sec; + u_int64_t usec; +} nflog_timestamp_t; + +/* + * TLV types. + */ +#define NFULA_PACKET_HDR 1 /* nflog_packet_hdr_t */ +#define NFULA_MARK 2 /* packet mark from skbuff */ +#define NFULA_TIMESTAMP 3 /* nflog_timestamp_t for skbuff's time stamp */ +#define NFULA_IFINDEX_INDEV 4 /* ifindex of device on which packet received (possibly bridge group) */ +#define NFULA_IFINDEX_OUTDEV 5 /* ifindex of device on which packet transmitted (possibly bridge group) */ +#define NFULA_IFINDEX_PHYSINDEV 6 /* ifindex of physical device on which packet received (not bridge group) */ +#define NFULA_IFINDEX_PHYSOUTDEV 7 /* ifindex of physical device on which packet transmitted (not bridge group) */ +#define NFULA_HWADDR 8 /* nflog_hwaddr_t for hardware address */ +#define NFULA_PAYLOAD 9 /* packet payload */ +#define NFULA_PREFIX 10 /* text string - null-terminated, count includes NUL */ +#define NFULA_UID 11 /* UID owning socket on which packet was sent/received */ +#define NFULA_SEQ 12 /* sequence number of packets on this NFLOG socket */ +#define NFULA_SEQ_GLOBAL 13 /* sequence number of pakets on all NFLOG sockets */ +#define NFULA_GID 14 /* GID owning socket on which packet was sent/received */ +#define NFULA_HWTYPE 15 /* ARPHRD_ type of skbuff's device */ +#define NFULA_HWHEADER 16 /* skbuff's MAC-layer header */ +#define NFULA_HWLEN 17 /* length of skbuff's MAC-layer header */ + +#endif diff --git a/include/npcap/pcap/pcap.h b/include/npcap/pcap/pcap.h new file mode 100644 index 0000000..7f92a37 --- /dev/null +++ b/include/npcap/pcap/pcap.h @@ -0,0 +1,538 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_pcap_h +#define lib_pcap_pcap_h + +#include + +#if defined(_WIN32) + #include +#elif defined(MSDOS) + #include + #include /* u_int, u_char etc. */ +#else /* UN*X */ + #include + #include +#endif /* _WIN32/MSDOS/UN*X */ + +#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Version number of the current version of the pcap file format. + * + * NOTE: this is *NOT* the version number of the libpcap library. + * To fetch the version information for the version of libpcap + * you're using, use pcap_lib_version(). + */ +#define PCAP_VERSION_MAJOR 2 +#define PCAP_VERSION_MINOR 4 + +#define PCAP_ERRBUF_SIZE 256 + +/* + * Compatibility for systems that have a bpf.h that + * predates the bpf typedefs for 64-bit support. + */ +#if BPF_RELEASE - 0 < 199406 +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#endif + +typedef struct pcap pcap_t; +typedef struct pcap_dumper pcap_dumper_t; +typedef struct pcap_if pcap_if_t; +typedef struct pcap_addr pcap_addr_t; + +/* + * The first record in the file contains saved values for some + * of the flags used in the printout phases of tcpdump. + * Many fields here are 32 bit ints so compilers won't insert unwanted + * padding; these files need to be interchangeable across architectures. + * + * Do not change the layout of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * + * Also, do not change the interpretation of any of the members of this + * structure, in any way (this includes using values other than + * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" + * field). + * + * Instead: + * + * introduce a new structure for the new format, if the layout + * of the structure changed; + * + * send mail to "tcpdump-workers@lists.tcpdump.org", requesting + * a new magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed file + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old file header as well as files with the new file header + * (using the magic number to determine the header format). + * + * Then supply the changes by forking the branch at + * + * https://github.com/the-tcpdump-group/libpcap/issues + * + * and issuing a pull request, so that future versions of libpcap and + * programs that use it (such as tcpdump) will be able to read your new + * capture file format. + */ +struct pcap_file_header { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ +}; + +/* + * Macros for the value returned by pcap_datalink_ext(). + * + * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro + * gives the FCS length of packets in the capture. + */ +#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) +#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) +#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + +typedef enum { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT +} pcap_direction_t; + +/* + * Generic per-packet information, as supplied by libpcap. + * + * The time stamp can and should be a "struct timeval", regardless of + * whether your system supports 32-bit tv_sec in "struct timeval", + * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit + * and 64-bit applications. The on-disk format of savefiles uses 32-bit + * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit + * and 64-bit versions of libpcap, even if they're on the same platform, + * should supply the appropriate version of "struct timeval", even if + * that's not what the underlying packet capture mechanism supplies. + */ +struct pcap_pkthdr { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ +}; + +/* + * As returned by the pcap_stats() + */ +struct pcap_stat { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */ +#if defined(_WIN32) && defined(HAVE_REMOTE) + u_int ps_capt; /* number of packets that reach the application */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ +#endif /* _WIN32 && HAVE_REMOTE */ +}; + +#ifdef MSDOS +/* + * As returned by the pcap_stats_ex() + */ +struct pcap_stat_ex { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; + + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ + + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; +#endif + +/* + * Item in a list of interfaces. + */ +struct pcap_if { + struct pcap_if *next; + char *name; /* name to hand to "pcap_open_live()" */ + char *description; /* textual description of interface, or NULL */ + struct pcap_addr *addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ +}; + +#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ +#define PCAP_IF_UP 0x00000002 /* interface is up */ +#define PCAP_IF_RUNNING 0x00000004 /* interface is running */ + +/* + * Representation of an interface address. + */ +struct pcap_addr { + struct pcap_addr *next; + struct sockaddr *addr; /* address */ + struct sockaddr *netmask; /* netmask for that address */ + struct sockaddr *broadaddr; /* broadcast address for that address */ + struct sockaddr *dstaddr; /* P2P destination address for that address */ +}; + +typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, + const u_char *); + +/* + * Error codes for the pcap API. + * These will all be negative, so you can check for the success or + * failure of a call that returns these codes by checking for a + * negative value. + */ +#define PCAP_ERROR -1 /* generic error code */ +#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ +#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ +#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ +#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ +#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ +#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ +#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ +#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ +#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */ +#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */ +#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12 /* the requested time stamp precision is not supported */ + +/* + * Warning codes for the pcap API. + * These will all be positive and non-zero, so they won't look like + * errors. + */ +#define PCAP_WARNING 1 /* generic warning code */ +#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ +#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */ + +/* + * Value to pass to pcap_compile() as the netmask if you don't know what + * the netmask is. + */ +#define PCAP_NETMASK_UNKNOWN 0xffffffff + +PCAP_API char *pcap_lookupdev(char *); +PCAP_API int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + +PCAP_API pcap_t *pcap_create(const char *, char *); +PCAP_API int pcap_set_snaplen(pcap_t *, int); +PCAP_API int pcap_set_promisc(pcap_t *, int); +PCAP_API int pcap_can_set_rfmon(pcap_t *); +PCAP_API int pcap_set_rfmon(pcap_t *, int); +PCAP_API int pcap_set_timeout(pcap_t *, int); +PCAP_API int pcap_set_tstamp_type(pcap_t *, int); +PCAP_API int pcap_set_immediate_mode(pcap_t *, int); +PCAP_API int pcap_set_buffer_size(pcap_t *, int); +PCAP_API int pcap_set_tstamp_precision(pcap_t *, int); +PCAP_API int pcap_get_tstamp_precision(pcap_t *); +PCAP_API int pcap_activate(pcap_t *); + +PCAP_API int pcap_list_tstamp_types(pcap_t *, int **); +PCAP_API void pcap_free_tstamp_types(int *); +PCAP_API int pcap_tstamp_type_name_to_val(const char *); +PCAP_API const char *pcap_tstamp_type_val_to_name(int); +PCAP_API const char *pcap_tstamp_type_val_to_description(int); + +/* + * Time stamp types. + * Not all systems and interfaces will necessarily support all of these. + * + * A system that supports PCAP_TSTAMP_HOST is offering time stamps + * provided by the host machine, rather than by the capture device, + * but not committing to any characteristics of the time stamp; + * it will not offer any of the PCAP_TSTAMP_HOST_ subtypes. + * + * PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine, + * that's low-precision but relatively cheap to fetch; it's normally done + * using the system clock, so it's normally synchronized with times you'd + * fetch from system calls. + * + * PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine, + * that's high-precision; it might be more expensive to fetch. It might + * or might not be synchronized with the system clock, and might have + * problems with time stamps for packets received on different CPUs, + * depending on the platform. + * + * PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the + * capture device; it's synchronized with the system clock. + * + * PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by + * the capture device; it's not synchronized with the system clock. + * + * Note that time stamps synchronized with the system clock can go + * backwards, as the system clock can go backwards. If a clock is + * not in sync with the system clock, that could be because the + * system clock isn't keeping accurate time, because the other + * clock isn't keeping accurate time, or both. + * + * Note that host-provided time stamps generally correspond to the + * time when the time-stamping code sees the packet; this could + * be some unknown amount of time after the first or last bit of + * the packet is received by the network adapter, due to batching + * of interrupts for packet arrival, queueing delays, etc.. + */ +#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */ +#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */ +#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */ +#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */ +#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */ + +/* + * Time stamp resolution types. + * Not all systems and interfaces will necessarily support all of these + * resolutions when doing live captures; all of them can be requested + * when reading a savefile. + */ +#define PCAP_TSTAMP_PRECISION_MICRO 0 /* use timestamps with microsecond precision, default */ +#define PCAP_TSTAMP_PRECISION_NANO 1 /* use timestamps with nanosecond precision */ + +PCAP_API pcap_t *pcap_open_live(const char *, int, int, int, char *); +PCAP_API pcap_t *pcap_open_dead(int, int); +PCAP_API pcap_t *pcap_open_dead_with_tstamp_precision(int, int, u_int); +PCAP_API pcap_t *pcap_open_offline_with_tstamp_precision(const char *, u_int, char *); +PCAP_API pcap_t *pcap_open_offline(const char *, char *); +#ifdef _WIN32 + PCAP_API pcap_t *pcap_hopen_offline_with_tstamp_precision(intptr_t, u_int, char *); + PCAP_API pcap_t *pcap_hopen_offline(intptr_t, char *); + /* + * If we're building libpcap, these are internal routines in savefile.c, + * so we mustn't define them as macros. + */ + #ifndef BUILDING_PCAP + #define pcap_fopen_offline_with_tstamp_precision(f,p,b) \ + pcap_hopen_offline_with_tstamp_precision(_get_osfhandle(_fileno(f)), p, b) + #define pcap_fopen_offline(f,b) \ + pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) + #endif +#else /*_WIN32*/ + PCAP_API pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *); + PCAP_API pcap_t *pcap_fopen_offline(FILE *, char *); +#endif /*_WIN32*/ + +PCAP_API void pcap_close(pcap_t *); +PCAP_API int pcap_loop(pcap_t *, int, pcap_handler, u_char *); +PCAP_API int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); +PCAP_API const u_char *pcap_next(pcap_t *, struct pcap_pkthdr *); +PCAP_API int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); +PCAP_API void pcap_breakloop(pcap_t *); +PCAP_API int pcap_stats(pcap_t *, struct pcap_stat *); +PCAP_API int pcap_setfilter(pcap_t *, struct bpf_program *); +PCAP_API int pcap_setdirection(pcap_t *, pcap_direction_t); +PCAP_API int pcap_getnonblock(pcap_t *, char *); +PCAP_API int pcap_setnonblock(pcap_t *, int, char *); +PCAP_API int pcap_inject(pcap_t *, const void *, size_t); +PCAP_API int pcap_sendpacket(pcap_t *, const u_char *, int); +PCAP_API const char *pcap_statustostr(int); +PCAP_API const char *pcap_strerror(int); +PCAP_API char *pcap_geterr(pcap_t *); +PCAP_API void pcap_perror(pcap_t *, const char *); +PCAP_API int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, + bpf_u_int32); +PCAP_API int pcap_compile_nopcap(int, int, struct bpf_program *, + const char *, int, bpf_u_int32); +PCAP_API void pcap_freecode(struct bpf_program *); +PCAP_API int pcap_offline_filter(const struct bpf_program *, + const struct pcap_pkthdr *, const u_char *); +PCAP_API int pcap_datalink(pcap_t *); +PCAP_API int pcap_datalink_ext(pcap_t *); +PCAP_API int pcap_list_datalinks(pcap_t *, int **); +PCAP_API int pcap_set_datalink(pcap_t *, int); +PCAP_API void pcap_free_datalinks(int *); +PCAP_API int pcap_datalink_name_to_val(const char *); +PCAP_API const char *pcap_datalink_val_to_name(int); +PCAP_API const char *pcap_datalink_val_to_description(int); +PCAP_API int pcap_snapshot(pcap_t *); +PCAP_API int pcap_is_swapped(pcap_t *); +PCAP_API int pcap_major_version(pcap_t *); +PCAP_API int pcap_minor_version(pcap_t *); + +/* XXX */ +PCAP_API FILE *pcap_file(pcap_t *); +PCAP_API int pcap_fileno(pcap_t *); + +#ifdef _WIN32 + PCAP_API int pcap_wsockinit(void); +#endif + +PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); +PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); +PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *); +PCAP_API FILE *pcap_dump_file(pcap_dumper_t *); +PCAP_API long pcap_dump_ftell(pcap_dumper_t *); +PCAP_API int pcap_dump_flush(pcap_dumper_t *); +PCAP_API void pcap_dump_close(pcap_dumper_t *); +PCAP_API void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + +PCAP_API int pcap_findalldevs(pcap_if_t **, char *); +PCAP_API void pcap_freealldevs(pcap_if_t *); + +PCAP_API const char *pcap_lib_version(void); + +/* + * On at least some versions of NetBSD and QNX, we don't want to declare + * bpf_filter() here, as it's also be declared in , with a + * different signature, but, on other BSD-flavored UN*Xes, it's not + * declared in , so we *do* want to declare it here, so it's + * declared when we build pcap-bpf.c. + */ +#if !defined(__NetBSD__) && !defined(__QNX__) + PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); +#endif +PCAP_API int bpf_validate(const struct bpf_insn *f, int len); +PCAP_API char *bpf_image(const struct bpf_insn *, int); +PCAP_API void bpf_dump(const struct bpf_program *, int); + +#if defined(_WIN32) + + /* + * Win32 definitions + */ + + /*! + \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). + */ + struct pcap_send_queue + { + u_int maxlen; /* Maximum size of the the queue, in bytes. This + variable contains the size of the buffer field. */ + u_int len; /* Current size of the queue, in bytes. */ + char *buffer; /* Buffer containing the packets to be sent. */ + }; + + typedef struct pcap_send_queue pcap_send_queue; + + /*! + \brief This typedef is a support for the pcap_get_airpcap_handle() function + */ + #if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle *PAirpcapHandle; + #endif + + PCAP_API int pcap_setbuff(pcap_t *p, int dim); + PCAP_API int pcap_setmode(pcap_t *p, int mode); + PCAP_API int pcap_setmintocopy(pcap_t *p, int size); + + PCAP_API HANDLE pcap_getevent(pcap_t *p); + + PCAP_API int pcap_oid_get_request(pcap_t *, bpf_u_int32, void *, size_t *); + PCAP_API int pcap_oid_set_request(pcap_t *, bpf_u_int32, const void *, size_t *); + + PCAP_API pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); + + PCAP_API void pcap_sendqueue_destroy(pcap_send_queue* queue); + + PCAP_API int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + + PCAP_API u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); + + PCAP_API struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); + + PCAP_API int pcap_setuserbuffer(pcap_t *p, int size); + + PCAP_API int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); + + PCAP_API int pcap_live_dump_ended(pcap_t *p, int sync); + + PCAP_API int pcap_start_oem(char* err_str, int flags); + + PCAP_API PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); + + #define MODE_CAPT 0 + #define MODE_STAT 1 + #define MODE_MON 2 + +#elif defined(MSDOS) + + /* + * MS-DOS definitions + */ + + PCAP_API int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); + PCAP_API void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); + PCAP_API u_long pcap_mac_packets (void); + +#else /* UN*X */ + + /* + * UN*X definitions + */ + + PCAP_API int pcap_get_selectable_fd(pcap_t *); + +#endif /* _WIN32/MSDOS/UN*X */ + +#ifdef HAVE_REMOTE + /* Includes most of the public stuff that is needed for the remote capture */ + #include +#endif /* HAVE_REMOTE */ + +#ifdef __cplusplus +} +#endif + +#endif /* lib_pcap_pcap_h */ diff --git a/include/npcap/pcap/sll.h b/include/npcap/pcap/sll.h new file mode 100644 index 0000000..b46d15f --- /dev/null +++ b/include/npcap/pcap/sll.h @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * For captures on Linux cooked sockets, we construct a fake header + * that includes: + * + * a 2-byte "packet type" which is one of: + * + * LINUX_SLL_HOST packet was sent to us + * LINUX_SLL_BROADCAST packet was broadcast + * LINUX_SLL_MULTICAST packet was multicast + * LINUX_SLL_OTHERHOST packet was sent to somebody else + * LINUX_SLL_OUTGOING packet was sent *by* us; + * + * a 2-byte Ethernet protocol field; + * + * a 2-byte link-layer type; + * + * a 2-byte link-layer address length; + * + * an 8-byte source link-layer address, whose actual length is + * specified by the previous value. + * + * All fields except for the link-layer address are in network byte order. + * + * DO NOT change the layout of this structure, or change any of the + * LINUX_SLL_ values below. If you must change the link-layer header + * for a "cooked" Linux capture, introduce a new DLT_ type (ask + * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it + * a value that collides with a value already being used), and use the + * new header in captures of that type, so that programs that can + * handle DLT_LINUX_SLL captures will continue to handle them correctly + * without any change, and so that capture files with different headers + * can be told apart and programs that read them can dissect the + * packets in them. + */ + +#ifndef lib_pcap_sll_h +#define lib_pcap_sll_h + +/* + * A DLT_LINUX_SLL fake link-layer header. + */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ + +struct sll_header { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ +}; + +/* + * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the + * PACKET_ values on Linux, but are defined here so that they're + * available even on systems other than Linux, and so that they + * don't change even if the PACKET_ values change. + */ +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 + +/* + * The LINUX_SLL_ values for "sll_protocol"; these correspond to the + * ETH_P_ values on Linux, but are defined here so that they're + * available even on systems other than Linux. We assume, for now, + * that the ETH_P_ values won't change in Linux; if they do, then: + * + * if we don't translate them in "pcap-linux.c", capture files + * won't necessarily be readable if captured on a system that + * defines ETH_P_ values that don't match these values; + * + * if we do translate them in "pcap-linux.c", that makes life + * unpleasant for the BPF code generator, as the values you test + * for in the kernel aren't the values that you test for when + * reading a capture file, so the fixup code run on BPF programs + * handed to the kernel ends up having to do more work. + * + * Add other values here as necessary, for handling packet types that + * might show up on non-Ethernet, non-802.x networks. (Not all the ones + * in the Linux "if_ether.h" will, I suspect, actually show up in + * captures.) + */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_CAN 0x000C /* CAN frames, with SocketCAN pseudo-headers */ +#define LINUX_SLL_P_CANFD 0x000D /* CAN FD frames, with SocketCAN pseudo-headers */ + +#endif diff --git a/include/npcap/pcap/usb.h b/include/npcap/pcap/usb.h new file mode 100644 index 0000000..26a9046 --- /dev/null +++ b/include/npcap/pcap/usb.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2006 Paolo Abeni (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Basic USB data struct + * By Paolo Abeni + */ + +#ifndef lib_pcap_usb_h +#define lib_pcap_usb_h + +/* + * possible transfer mode + */ +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 + +/* + * possible event type + */ +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' + +/* + * USB setup header as defined in USB specification. + * Appears at the front of each Control S-type packet in DLT_USB captures. + */ +typedef struct _usb_setup { + u_int8_t bmRequestType; + u_int8_t bRequest; + u_int16_t wValue; + u_int16_t wIndex; + u_int16_t wLength; +} pcap_usb_setup; + +/* + * Information from the URB for Isochronous transfers. + */ +typedef struct _iso_rec { + int32_t error_count; + int32_t numdesc; +} iso_rec; + +/* + * Header prepended by linux kernel to each event. + * Appears at the front of each packet in DLT_USB_LINUX captures. + */ +typedef struct _usb_header { + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag;/*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; +} pcap_usb_header; + +/* + * Header prepended by linux kernel to each event for the 2.6.31 + * and later kernels; for the 2.6.21 through 2.6.30 kernels, the + * "iso_rec" information, and the fields starting with "interval" + * are zeroed-out padding fields. + * + * Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures. + */ +typedef struct _usb_header_mmapped { + u_int64_t id; + u_int8_t event_type; + u_int8_t transfer_type; + u_int8_t endpoint_number; + u_int8_t device_address; + u_int16_t bus_id; + char setup_flag;/*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + u_int32_t urb_len; + u_int32_t data_len; /* amount of urb data really present in this event*/ + union { + pcap_usb_setup setup; + iso_rec iso; + } s; + int32_t interval; /* for Interrupt and Isochronous events */ + int32_t start_frame; /* for Isochronous events */ + u_int32_t xfer_flags; /* copy of URB's transfer flags */ + u_int32_t ndesc; /* number of isochronous descriptors */ +} pcap_usb_header_mmapped; + +/* + * Isochronous descriptors; for isochronous transfers there might be + * one or more of these at the beginning of the packet data. The + * number of descriptors is given by the "ndesc" field in the header; + * as indicated, in older kernels that don't put the descriptors at + * the beginning of the packet, that field is zeroed out, so that field + * can be trusted even in captures from older kernels. + */ +typedef struct _usb_isodesc { + int32_t status; + u_int32_t offset; + u_int32_t len; + u_int8_t pad[4]; +} usb_isodesc; + +#endif diff --git a/include/npcap/pcap/vlan.h b/include/npcap/pcap/vlan.h new file mode 100644 index 0000000..021f612 --- /dev/null +++ b/include/npcap/pcap/vlan.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_vlan_h +#define lib_pcap_vlan_h + +struct vlan_tag { + u_int16_t vlan_tpid; /* ETH_P_8021Q */ + u_int16_t vlan_tci; /* VLAN TCI */ +}; + +#define VLAN_TAG_LEN 4 + +#endif diff --git a/include/npcap/remote-ext.h b/include/npcap/remote-ext.h new file mode 100644 index 0000000..ed2f9bb --- /dev/null +++ b/include/npcap/remote-ext.h @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef __REMOTE_EXT_H__ +#define __REMOTE_EXT_H__ + + +#ifndef HAVE_REMOTE +#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h +#endif + +/*// Definition for Microsoft Visual Studio */ +#if _MSC_VER > 1000 +#pragma once +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * \file remote-ext.h + * + * The goal of this file it to include most of the new definitions that should be + * placed into the pcap.h file. + * + * It includes all new definitions (structures and functions like pcap_open(). + * Some of the functions are not really a remote feature, but, right now, + * they are placed here. + */ + + + +/*// All this stuff is public */ +/* + * \addtogroup remote_struct + * \{ + */ + + + + +/* + * \brief Defines the maximum buffer size in which address, port, interface names are kept. + * + * In case the adapter name or such is larger than this value, it is truncated. + * This is not used by the user; however it must be aware that an hostname / interface + * name longer than this value will be truncated. + */ +#define PCAP_BUF_SIZE 1024 + + +/* + * \addtogroup remote_source_ID + * \{ + */ + + +/* + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a file, i.e. the user want to open a capture from a local file. + */ +#define PCAP_SRC_FILE 2 +/* + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a local interface, i.e. the user want to open a capture from + * a local interface. This does not involve the RPCAP protocol. + */ +#define PCAP_SRC_IFLOCAL 3 +/* + * \brief Internal representation of the type of source in use (file, + * remote/local interface). + * + * This indicates a remote interface, i.e. the user want to open a capture from + * an interface on a remote host. This does involve the RPCAP protocol. + */ +#define PCAP_SRC_IFREMOTE 4 + +/* + * \} + */ + + + +/* \addtogroup remote_source_string + * + * The formats allowed by the pcap_open() are the following: + * - file://path_and_filename [opens a local file] + * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] + * - rpcap://host/devicename [opens the selected device available on a remote host] + * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] + * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] + * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] + * + * The formats allowed by the pcap_findalldevs_ex() are the following: + * - file://folder/ [lists all the files in the given folder] + * - rpcap:// [lists all local adapters] + * - rpcap://host:port/ [lists the devices available on a remote host] + * + * Referring to the 'host' and 'port' parameters, they can be either numeric or literal. Since + * IPv6 is fully supported, these are the allowed formats: + * + * - host (literal): e.g. host.foo.bar + * - host (numeric IPv4): e.g. 10.11.12.13 + * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] + * - host (numeric IPv6): e.g. [1:2:3::4] + * - port: can be either numeric (e.g. '80') or literal (e.g. 'http') + * + * Here you find some allowed examples: + * - rpcap://host.foo.bar/devicename [everything literal, no port number] + * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] + * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] + * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] + * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] + * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] + * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] + * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] + * + * \{ + */ + + +/* + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a local file. + */ +#define PCAP_SRC_FILE_STRING "file://" +/* + * \brief String that will be used to determine the type of source in use (file, + * remote/local interface). + * + * This string will be prepended to the interface name in order to create a string + * that contains all the information required to open the source. + * + * This string indicates that the user wants to open a capture from a network interface. + * This string does not necessarily involve the use of the RPCAP protocol. If the + * interface required resides on the local host, the RPCAP protocol is not involved + * and the local functions are used. + */ +#define PCAP_SRC_IF_STRING "rpcap://" + +/* + * \} + */ + + + + + +/* + * \addtogroup remote_open_flags + * \{ + */ + +/* + * \brief Defines if the adapter has to go in promiscuous mode. + * + * It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. + * Note that even if this parameter is false, the interface could well be in promiscuous + * mode for some other reason (for example because another capture process with + * promiscuous mode enabled is currently using that interface). + * On on Linux systems with 2.2 or later kernels (that have the "any" device), this + * flag does not work on the "any" device; if an argument of "any" is supplied, + * the 'promisc' flag is ignored. + */ +#define PCAP_OPENFLAG_PROMISCUOUS 1 + +/* + * \brief Defines if the data transfer (in case of a remote + * capture) has to be done with UDP protocol. + * + * If it is '1' if you want a UDP data connection, '0' if you want + * a TCP data connection; control connection is always TCP-based. + * A UDP connection is much lighter, but it does not guarantee that all + * the captured packets arrive to the client workstation. Moreover, + * it could be harmful in case of network congestion. + * This flag is meaningless if the source is not a remote interface. + * In that case, it is simply ignored. + */ +#define PCAP_OPENFLAG_DATATX_UDP 2 + + +/* + * \brief Defines if the remote probe will capture its own generated traffic. + * + * In case the remote probe uses the same interface to capture traffic and to send + * data back to the caller, the captured traffic includes the RPCAP traffic as well. + * If this flag is turned on, the RPCAP traffic is excluded from the capture, so that + * the trace returned back to the collector is does not include this traffic. + */ +#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 + +/* + * \brief Defines if the local adapter will capture its own generated traffic. + * + * This flag tells the underlying capture driver to drop the packets that were sent by itself. + * This is useful when building applications like bridges, that should ignore the traffic + * they just sent. + */ +#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 + +/* + * \brief This flag configures the adapter for maximum responsiveness. + * + * In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before + * copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, + * i.e. better performance, which is good for applications like sniffers. If the user sets the + * PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application + * is ready to receive them. This is suggested for real time applications (like, for example, a bridge) + * that need the best responsiveness. + */ +#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 + +/* + * \} + */ + + +/* + * \addtogroup remote_samp_methods + * \{ + */ + +/* + *\brief No sampling has to be done on the current capture. + * + * In this case, no sampling algorithms are applied to the current capture. + */ +#define PCAP_SAMP_NOSAMP 0 + +/* + * \brief It defines that only 1 out of N packets must be returned to the user. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the + * number of packets (minus 1) that must be discarded before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller, while + * the following 9 are discarded. + */ +#define PCAP_SAMP_1_EVERY_N 1 + +/* + * \brief It defines that we have to return 1 packet every N milliseconds. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting + * time' in milliseconds before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the caller; the next + * returned one will be the first packet that arrives when 10ms have elapsed. + */ +#define PCAP_SAMP_FIRST_AFTER_N_MS 2 + +/* + * \} + */ + + +/* + * \addtogroup remote_auth_methods + * \{ + */ + +/* + * \brief It defines the NULL authentication. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + * The 'NULL' authentication has to be equal to 'zero', so that old applications + * can just put every field of struct pcap_rmtauth to zero, and it does work. + */ +#define RPCAP_RMTAUTH_NULL 0 +/* + * \brief It defines the username/password authentication. + * + * With this type of authentication, the RPCAP protocol will use the username/ + * password provided to authenticate the user on the remote machine. If the + * authentication is successful (and the user has the right to open network devices) + * the RPCAP connection will continue; otherwise it will be dropped. + * + * This value has to be used within the 'type' member of the pcap_rmtauth structure. + */ +#define RPCAP_RMTAUTH_PWD 1 + +/* + * \} + */ + + + + +/* + * \brief This structure keeps the information needed to autheticate + * the user on a remote machine. + * + * The remote machine can either grant or refuse the access according + * to the information provided. + * In case the NULL authentication is required, both 'username' and + * 'password' can be NULL pointers. + * + * This structure is meaningless if the source is not a remote interface; + * in that case, the functions which requires such a structure can accept + * a NULL pointer as well. + */ +struct pcap_rmtauth +{ + /* + * \brief Type of the authentication required. + * + * In order to provide maximum flexibility, we can support different types + * of authentication based on the value of this 'type' variable. The currently + * supported authentication methods are defined into the + * \link remote_auth_methods Remote Authentication Methods Section\endlink. + */ + int type; + /* + * \brief Zero-terminated string containing the username that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char *username; + /* + * \brief Zero-terminated string containing the password that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char *password; +}; + + +/* + * \brief This structure defines the information related to sampling. + * + * In case the sampling is requested, the capturing device should read + * only a subset of the packets coming from the source. The returned packets depend + * on the sampling parameters. + * + * \warning The sampling process is applied after the filtering process. + * In other words, packets are filtered first, then the sampling process selects a + * subset of the 'filtered' packets and it returns them to the caller. + */ +struct pcap_samp +{ + /* + * Method used for sampling. Currently, the supported methods are listed in the + * \link remote_samp_methods Sampling Methods Section\endlink. + */ + int method; + + /* + * This value depends on the sampling method defined. For its meaning, please check + * at the \link remote_samp_methods Sampling Methods Section\endlink. + */ + int value; +}; + + + + +// Maximum length of an host name (needed for the RPCAP active mode) +#define RPCAP_HOSTLIST_SIZE 1024 + + +/* + * \} + */ // end of public documentation + + +// Exported functions + + + +/* + * \name New WinPcap functions + * + * This section lists the new functions that are able to help considerably in writing + * WinPcap programs because of their easiness of use. + */ +// \{ +PCAP_API pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); +PCAP_API int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf); +PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf); +PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); +PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p); + +// \} +// End of new WinPcap functions + +/* + * \name Remote Capture functions + */ + +/* + * Some minor differences between UN*X sockets and and Winsock sockets. + */ +#ifndef _WIN32 + /*! + * \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's + * a file descriptor, and therefore a signed integer. + * We define SOCKET to be a signed integer on UN*X, so that it can + * be used on both platforms. + */ + #define SOCKET int + + /*! + * \brief In Winsock, the error return if socket() fails is INVALID_SOCKET; + * in UN*X, it's -1. + * We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on + * both platforms. + */ + #define INVALID_SOCKET -1 +#endif + +// \{ +PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf); +PCAP_API int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf); +PCAP_API int pcap_remoteact_close(const char *host, char *errbuf); +PCAP_API void pcap_remoteact_cleanup(); +// \} +// End of remote capture functions + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d448fe..3094893 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,3 @@ -cmake_minimum_required(VERSION 3.1) -project(gsplus VERSION 0.14) - -# -# cmake -DCMAKE_BUILD_TYPE=Release -# INCLUDE (CheckFunctionExists) INCLUDE (CheckLibraryExists) @@ -20,22 +14,36 @@ 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( - -O2 -Wall -fomit-frame-pointer + -Wall -fomit-frame-pointer ) endif() -if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") +if(__GCC__) add_compile_options( - -O2 -Wall -fomit-frame-pointer + -Wall -fomit-frame-pointer ) endif() - TEST_BIG_ENDIAN(IS_BIG_ENDIAN) if(NOT IS_BIG_ENDIAN) add_definitions(-DGSPLUS_LITTLE_ENDIAN) @@ -45,14 +53,30 @@ endif() pkg_check_modules(SDL2 sdl2) pkg_check_modules(FREETYPE2 freetype2) + +find_program(PERL perl) +find_program(RE2C re2c) + +if (RE2C-NOTFOUND) + message(FATAL_ERROR "unable to find re2c") +endif() + +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(DEBUGGER "Enable the debugger" ON) -option(HOST_FST "Enable host fst support" ON) +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_STATIC "Enable static link" OFF) +set(READLINE "AUTO" CACHE STRING "Readline library (AUTO, NONE, READLINE, LIBEDIT)") 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( @@ -76,17 +100,30 @@ add_custom_command( WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) -if(CYGWIN OR MSYS) - set(WIN32 1) - add_definitions(-DWIN32 -D_WIN32) -endif() +add_custom_command( + OUTPUT debug_shell.c + COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_shell.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_shell.re2c" + MAIN_DEPENDENCY debug_shell.re2c +) -if(WIN32) - add_definitions(-D__USE_W32_SOCKETS -D_WINSOCK2API_) -endif() +add_custom_command( + OUTPUT debug_template.c + COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_template.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_template.re2c" + MAIN_DEPENDENCY debug_template.re2c +) -if(MSVC) - add_definitions(-D_CRT_SECURE_NO_WARNINGS) + +add_custom_command( + OUTPUT debug_sweet16.c + COMMAND re2c -W -o ${CMAKE_CURRENT_BINARY_DIR}/debug_sweet16.c "${CMAKE_CURRENT_SOURCE_DIR}/debug_sweet16.re2c" + MAIN_DEPENDENCY debug_sweet16.re2c +) + +if (WITH_STATIC) + if(__CLANG__ OR __GCC__) + #add_link_options(-static) # 3.13 + link_libraries(-static) + endif() endif() @@ -94,7 +131,8 @@ add_executable(to_pro to_pro.c) add_executable(partls partls.c) add_subdirectory(atbridge) -add_subdirectory(tfe) +#add_subdirectory(tfe) +add_subdirectory(rawnet) if (DRIVER MATCHES "SDL") set(driver_code sdl2_driver.c sdl2snd_driver.c) @@ -103,7 +141,7 @@ elseif(DRIVER MATCHES "X11") elseif(DRIVER MATCHES "FB") set(driver_code fbdriver.c) elseif(DRIVER MATCHES "WIN32") - set(driver_code scc_windriver.c win32snd_driver.c win_console.c win_generic.c) + set(driver_code win32snd_driver.c win_console.c win_generic.c) elseif(DRIVER MATCHES "HEADLESS") set(driver_code headless_driver.c) else() @@ -128,32 +166,83 @@ 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 dis.c engine_c.c scc.c iwm.c + 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 - $<$:debug.c> - $<$:${host_fst_code}> + disasm.c + debug_shell.c + debug_template.c + debug_sweet16.c + + $<$:debug.c> + $<$:${host_fst_code}> ${driver_code} ${generated_headers} + + $<$:scc_windriver.c> $<$:win32.rc> - $<$:gsp_icon.icns> + $<$:assets/gsp_icon.icns> + $<$:assets/GSBug.Templates> + $<$:assets/NList.Data> $<$:fix_mac_menu.m> ) SET_SOURCE_FILES_PROPERTIES( - gsp_icon.icns + assets/gsp_icon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources - ) +) -target_link_libraries(GSplus atbridge) -target_link_libraries(GSplus tfe) +SET_SOURCE_FILES_PROPERTIES( + assets/GSBug.Templates + assets/NList.Data + PROPERTIES + MACOSX_PACKAGE_LOCATION Resources +) -if (DRIVER MATCHES "WIN32") + +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) + +add_library(x_readline readline.c) +if (READLINE MATCHES "AUTO") + if (CMAKE_SYSTEM_NAME MATCHES "(Darwin|FreeBSD|OpenBSD|NetBSD)") + set(READLINE "LIBEDIT") + endif() + if (CMAKE_SYSTEM_NAME MATCHES "Linux") + set(READLINE "READLINE") + endif() +endif() +if(READLINE MATCHES "READLINE") + target_compile_definitions(x_readline PRIVATE USE_READLINE) + target_link_libraries(x_readline PUBLIC readline) +elseif(READLINE MATCHES "LIBEDIT") + target_compile_definitions(x_readline PRIVATE USE_LIBEDIT) + target_link_libraries(x_readline PUBLIC edit) +endif() + +target_link_libraries(GSplus x_readline) + +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 ) @@ -165,26 +254,24 @@ if (DRIVER MATCHES "SDL") endif() if (APPLE) - target_link_libraries(GSplus "-framework Cocoa -framework vmnet") + target_link_libraries(GSplus "-framework Cocoa") endif() if (TOGGLE_STATUS) - target_compile_options(GSplus PUBLIC -DTOGGLE_STATUS) + target_compile_definitions(GSplus PUBLIC TOGGLE_STATUS) 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 AND CMAKE_BUILD_TYPE MATCHES "Release") -# add_custom_command(TARGET GSplus -# POST_BUILD -# COMMAND dylibbundler -od -b -x GSplus.app/Contents/MacOS/GSplus -d GSplus.app/Contents/libs -# #COMMAND cp to_pro partls GSplus.app/Contents/Resources/ -# COMMENT bundling libraries... -# ) -# endif() if (APPLE) add_custom_target(bundle @@ -192,4 +279,9 @@ if (APPLE) 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/Makefile b/src/Makefile index 7da45aa..5d361a4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,196 +1,14 @@ -# GSplus central makefile - you need a 'vars' file linked/copied from a 'vars_xxx' template to build. -#@todo: check for vars file and do something useful if missing :P -#@todo: remove all packaging junk and move to packaging scripts in CI -OBJECTS1 = adb.o clock.o config.o debug.o dis.o engine_c.o scc.o iwm.o \ - joystick_driver.o moremem.o paddles.o parallel.o printer.o sim65816.o \ - smartport.o sound.o sound_driver.o video.o scc_socket_driver.o glog.o \ - imagewriter.o scc_imagewriter.o scc_llap.o options.o -ATOBJ = atbridge/aarp.o atbridge/atbridge.o atbridge/elap.o atbridge/llap.o atbridge/port.o -PCAPOBJ = atbridge/pcap_delay.o -TFEOBJ = tfe/tfe.o tfe/tfearch.o tfe/tfesupp.o -FSTOBJ = unix_host_common.o host_common.o host_fst.o host_mli.o -include vars +.PHONY: rtfm +rtfm: + @echo "" + @echo "CMAKE IS NOW USED AS THE BUILD SYSTEM" + @echo " (YES I'M YELLING)" + @echo "" + @echo "(from top level directory)" + @echo " mkdir build" + @echo " cd build" + @echo " cmake .." + @echo " make" + @echo "" -.SUFFIXES: .dep .proto - -AS = $(CC) - -XLIBS = -L/usr/X11R6/lib -PERL = perl - -all: $(TARGET) - -clean: - - rm -f $(OBJECTS) - - rm -f $(TARGET) - - rm -f compile_time.o - - rm -f 8inst_c.h - - rm -f 16inst_c.h - -specials: 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s - -specials_clean: - rm -f 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s - -# Linux/OSX/RPi SDL builds -gsplus: $(OBJECTS) compile_time.o - $(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) - echo $(OBJECTS) - cp gsplus .. - -# Linux/OSX XWindows builds -gsplusx: $(OBJECTS) compile_time.o - $(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(XLIBS) $(EXTRA_LIBS) -lX11 - echo $(OBJECTS) - mv gsplusx .. - -# NOT CURRENTLY SUPPORTED -# Linux framebuffer builds: -gsplusfb: $(OBJECTS) compile_time.o - $(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) - echo $(OBJECTS) - mv gsplusfb .. - -# Mingw32 / Cygwin builds: The Win32 API version -gsplus32.exe: $(OBJECTS) compile_time.o - g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32 - #mkdir -p ../GSplus.app/lib - #cp -f gsplus.exe ../GSplus.app/GSplus.exe - #cp -f ../config.template ../GSplus.app/config.txt - #cp -f ../lib/*.ttf ../GSplus.app/lib - #cp -f ../lib/arch/win32/*.dll ../GSplus.app - #cp -f ../lib/NoBoot.po ../GSplus.app - #cp -f GSplus.bat ../GSplus.app/GSplus.bat - #cp -f parallel.rom ../GSplus.app - #cp -f ../COPYING.txt ../GSplus.app - cp gsplus32.exe .. - -# Mingw32 / Cygwin builds: The SDL version (builds, but non-functioning) -gsplus.exe: $(OBJECTS) compile_time.o - #g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32 - #g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -mwindows - g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32 - cp gsplus.exe .. - -# NOT CURRENTLY SUPPORTED -# Mac build - old style (deprecated) -gsportmac: $(OBJECTS) compile_time.o - $(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o gsport $(EXTRA_LIBS) - mkdir -p ../GSport.app/Contents/Resources/English.lproj/main.nib - mkdir -p ../GSport.app/Contents/MacOS - mv gsport ../GSport.app/Contents/MacOS/GSport - echo "APPL????" > ../GSport.app/Contents/PkgInfo - cp -f arch/mac/Info.plist ../GSport.app/Contents/ - cp -f arch/mac/info.nib ../GSport.app/Contents/Resources/English.lproj/main.nib - cp -f arch/mac/classes.nib ../GSport.app/Contents/Resources/English.lproj/main.nib - cp -f arch/mac/objects.xib ../GSport.app/Contents/Resources/English.lproj/main.nib - cp -f arch/mac/gsporticon.icns ../GSport.app/Contents/Resources/ - cp -f arch/mac/525.icns ../GSport.app/Contents/Resources/ - cp -f arch/mac/2mg.icns ../GSport.app/Contents/Resources/ - touch '../GSport.app/Icon?' - rm -rf ../GSportDmg - mkdir ../GSportDmg - mkdir ../GSportDmg/GSport - cp ../COPYING.txt ../GSportDmg/GSport - cp -f parallel.rom ../GSportDmg/GSport - cp -f ../lib/NoBoot.po ../GSportDmg/GSport - mv ../GSport.app ../GSportDmg/GSport - cp -f ../config.template ../GSportDmg/GSport/config.txt - cp ../GSport.html ../GSportDmg/GSport/GSport.html - arch/mac/makedmg.sh .. GSportDmg GSport GSport 7 - -8inst_c.h: instable.h - $(PERL) make_inst c 8 instable.h > 8inst_c.h - -16inst_c.h: instable.h - $(PERL) make_inst c 16 instable.h > 16inst_c.h - -size_c.h: size_tab.h - $(PERL) make_size c size_tab.h > size_c.h - -engine_c.o: 8inst_c.h 16inst_c.h size_c.h - -8inst_s.h: instable.h - $(PERL) make_inst s 8 instable.h > 8inst_s.h - -16inst_s.h: instable.h - $(PERL) make_inst s 16 instable.h > 16inst_s.h - -size_s.h: size_tab.h - $(PERL) make_size s size_tab.h > size_s.h - -8size_s.h: size_tab.h - $(PERL) make_size 8 size_tab.h > 8size_s.h - -16size_s.h: size_tab.h - $(PERL) make_size 16 size_tab.h > 16size_s.h - -engine_s.o: 8inst_s.h 16inst_s.h 8size_s.h 16size_s.h size_s.h - -.s.o: - $(AS) -c $(OPTS) -I. $*.s - -.c.o: - $(CC) $(CCOPTS) $(XOPTS) -c $(OPTS) -I. -o $*.o $*.c - -.cpp.o: - $(CC) $(CPPOPTS) $(XOPTS) -c $(OPTS) -I. $*.cpp - -.cpp.O: - $(CC) $(CCOPTS) $(XOPTS) -c $(OPTS) -I. $*.c - -partls: partls.c - cc $(CCOPTS) $(XOPTS) $(OPTS) -o partls partls.c - -to_pro: prodos.h prodos_protos.h to_pro.c - cc $(CCOPTS) $(XOPTS) $(OPTS) -o to_pro to_pro.c - -gsplus32.o: win32.rc winresource.h - windres win32.rc -o gsplus32.o - -compile_time.o: $(OBJECTS) - - -# dependency stuff -adb.o: adb.c adb.h defc.h defcomm.h iwm.h protos.h -atbridge/aarp.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/elap.h atbridge/aarp.h atbridge/elap_defs.h -atbridge/atbridge.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/elap.h atbridge/llap.h atbridge/aarp.h -atbridge/elap.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/elap.h atbridge/aarp.h atbridge/elap_defs.h atbridge/pcap_delay.h -atbridge/llap.o: defc.h atbridge/atbridge.h atbridge/port.h atbridge/llap.h -atbridge/port.o: atbridge/atalk.h atbridge/port.h -atbridge/pcap_delay.o: atbridge/pcap_delay.h -engine_c.o: engine_c.c defc.h defcomm.h iwm.h protos.h protos_engine_c.h size_c.h op_routs.h defs_instr.h 8inst_c.h 16inst_c.h -clock.o: clock.c defc.h defcomm.h iwm.h protos.h -compile_time.o: compile_time.c -config.o: config.c defc.h defcomm.h iwm.h protos.h config.h -dis.o: dis.c defc.h defcomm.h iwm.h protos.h disas.h -scc.o: scc.c defc.h defcomm.h iwm.h protos.h scc.h -scc_llap.o: atbridge/atbridge.h atbridge/llap.h defc.h scc.h -scc_socket_driver.o: scc_socket_driver.c defc.h defcomm.h iwm.h protos.h scc.h -scc_windriver.o: scc_windriver.c defc.h defcomm.h iwm.h protos.h scc.h -scc_macdriver.o: scc_macdriver.c defc.h defcomm.h iwm.h protos.h scc.h -scc_imagewriter.o: scc_imagewriter.c defc.h defcomm.h protos.h scc.h -iwm.o: iwm.c defc.h defcomm.h iwm.h protos.h iwm_35_525.h -imagewriter.o: imagewriter.cpp -joystick_driver.o: joystick_driver.c defc.h defcomm.h iwm.h protos.h -moremem.o: moremem.c defc.h defcomm.h iwm.h protos.h -paddles.o: paddles.c defc.h defcomm.h iwm.h protos.h -parallel.o: parallel.c defc.h -printer.o: printer.cpp -sim65816.o: sim65816.c defc.h defcomm.h iwm.h protos.h -smartport.o: smartport.c defc.h defcomm.h iwm.h protos.h -sound.o: sound.c defc.h defcomm.h iwm.h protos.h sound.h -sound_driver.o: sound_driver.c defc.h defcomm.h iwm.h protos.h sound.h -video.o: video.c defc.h defcomm.h iwm.h protos.h superhires.h gsportfont.h -tfe.o: tfe/tfe.c tfe/tfe.h tfe/tfe_protos.h -tfearch.o: tfe/tfearch.c tfe/tfearch.h tfe/tfe_protos.h -tfesupp.o: tfe/tfesupp.c tfe/tfesupp.h tfe/tfe_protos.h -macdriver.o: macdriver.c defc.h defcomm.h iwm.h protos.h protos_macdriver.h -macdriver_console.o: macdriver_console.c defc.h defcomm.h iwm.h protos.h protos_macdriver.h -macdriver_generic.o: macdriver_generic.c defc.h defcomm.h iwm.h protos.h protos_macdriver.h -macsnd_driver.o: macsnd_driver.c defc.h defcomm.h iwm.h protos.h sound.h -windriver.o: windriver.c defc.h defcomm.h iwm.h protos.h protos_windriver.h winresource.h gsplus32.o -win_console.o: win_console.c defc.h defcomm.h iwm.h protos.h protos_windriver.h winresource.h -win_generic.o: win_generic.c defc.h defcomm.h iwm.h protos.h protos_windriver.h winresource.h -win32snd_driver.o: win32snd_driver.c defc.h defcomm.h iwm.h protos.h sound.h diff --git a/src/arch/win32/bittypes.h b/src/arch/win32/bittypes.h deleted file mode 100644 index 654f37b..0000000 --- a/src/arch/win32/bittypes.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#ifndef _BITTYPES_H -#define _BITTYPES_H - -#ifndef HAVE_U_INT8_T - -#if SIZEOF_CHAR == 1 -typedef unsigned char u_int8_t; -typedef signed char int8_t; -#elif SIZEOF_INT == 1 -typedef unsigned int u_int8_t; -typedef signed int int8_t; -#else /* XXX */ -#error "there's no appropriate type for u_int8_t" -#endif -#define HAVE_U_INT8_T 1 -#define HAVE_INT8_T 1 - -#endif /* HAVE_U_INT8_T */ - -#ifndef HAVE_U_INT16_T - -#if SIZEOF_SHORT == 2 -typedef unsigned short u_int16_t; -typedef signed short int16_t; -#elif SIZEOF_INT == 2 -typedef unsigned int u_int16_t; -typedef signed int int16_t; -#elif SIZEOF_CHAR == 2 -typedef unsigned char u_int16_t; -typedef signed char int16_t; -#else /* XXX */ -#error "there's no appropriate type for u_int16_t" -#endif -#define HAVE_U_INT16_T 1 -#define HAVE_INT16_T 1 - -#endif /* HAVE_U_INT16_T */ - -#ifndef HAVE_U_INT32_T - -#if SIZEOF_INT == 4 -typedef unsigned int u_int32_t; -typedef signed int int32_t; -#elif SIZEOF_LONG == 4 -typedef unsigned long u_int32_t; -typedef signed long int32_t; -#elif SIZEOF_SHORT == 4 -typedef unsigned short u_int32_t; -typedef signed short int32_t; -#else /* XXX */ -#error "there's no appropriate type for u_int32_t" -#endif -#define HAVE_U_INT32_T 1 -#define HAVE_INT32_T 1 - -#endif /* HAVE_U_INT32_T */ - -#endif /* _BITTYPES_H */ diff --git a/src/arch/win32/bpf.h b/src/arch/win32/bpf.h deleted file mode 100644 index 51f9ecb..0000000 --- a/src/arch/win32/bpf.h +++ /dev/null @@ -1,523 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)bpf.h 7.1 (Berkeley) 5/7/91 - * - * @(#) $Header$ (LBL) - */ - -#ifndef BPF_MAJOR_VERSION - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _MSC_VER -#include -typedef unsigned int u_int; -typedef unsigned char u_char; -typedef unsigned short u_short; -#endif - -/* BSD style release date */ -#define BPF_RELEASE 199606 - -typedef int bpf_int32; -typedef u_int bpf_u_int32; - -/* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. - */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) - -#define BPF_MAXINSNS 512 -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 - -/* - * Structure for BIOCSETF. - */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - -/* - * Struct returned by BIOCGSTATS. - */ -struct bpf_stat { - u_int bs_recv; /* number of packets received */ - u_int bs_drop; /* number of packets dropped */ -}; - -/* - * Struct return by BIOCVERSION. This represents the version number of - * the filter language described by the instruction encodings below. - * bpf understands a program iff kernel_major == filter_major && - * kernel_minor >= filter_minor, that is, if the value returned by the - * running kernel has the same major number and a minor number equal - * equal to or less than the filter being downloaded. Otherwise, the - * results are undefined, meaning an error may be returned or packets - * may be accepted haphazardly. - * It has nothing to do with the source code version. - */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; -/* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 - -/* - * BPF ioctls - * - * The first set is for compatibility with Sun's pcc style - * header files. If your using gcc, we assume that you - * have run fixincludes so the latter set should work. - */ -#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__) -#define BIOCGBLEN _IOR(B,102, u_int) -#define BIOCSBLEN _IOWR(B,102, u_int) -#define BIOCSETF _IOW(B,103, struct bpf_program) -#define BIOCFLUSH _IO(B,104) -#define BIOCPROMISC _IO(B,105) -#define BIOCGDLT _IOR(B,106, u_int) -#define BIOCGETIF _IOR(B,107, struct ifreq) -#define BIOCSETIF _IOW(B,108, struct ifreq) -#define BIOCSRTIMEOUT _IOW(B,109, struct timeval) -#define BIOCGRTIMEOUT _IOR(B,110, struct timeval) -#define BIOCGSTATS _IOR(B,111, struct bpf_stat) -#define BIOCIMMEDIATE _IOW(B,112, u_int) -#define BIOCVERSION _IOR(B,113, struct bpf_version) -#define BIOCSTCPF _IOW(B,114, struct bpf_program) -#define BIOCSUDPF _IOW(B,115, struct bpf_program) -#else -#define BIOCGBLEN _IOR('B',102, u_int) -#define BIOCSBLEN _IOWR('B',102, u_int) -#define BIOCSETF _IOW('B',103, struct bpf_program) -#define BIOCFLUSH _IO('B',104) -#define BIOCPROMISC _IO('B',105) -#define BIOCGDLT _IOR('B',106, u_int) -#define BIOCGETIF _IOR('B',107, struct ifreq) -#define BIOCSETIF _IOW('B',108, struct ifreq) -#define BIOCSRTIMEOUT _IOW('B',109, struct timeval) -#define BIOCGRTIMEOUT _IOR('B',110, struct timeval) -#define BIOCGSTATS _IOR('B',111, struct bpf_stat) -#define BIOCIMMEDIATE _IOW('B',112, u_int) -#define BIOCVERSION _IOR('B',113, struct bpf_version) -#define BIOCSTCPF _IOW('B',114, struct bpf_program) -#define BIOCSUDPF _IOW('B',115, struct bpf_program) -#endif - -/* - * Structure prepended to each packet. - */ -struct bpf_hdr { - struct timeval bh_tstamp; /* time stamp */ - bpf_u_int32 bh_caplen; /* length of captured portion */ - bpf_u_int32 bh_datalen; /* original length of packet */ - u_short bh_hdrlen; /* length of bpf header (this struct - plus alignment padding) */ -}; -/* - * Because the structure above is not a multiple of 4 bytes, some compilers - * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work. - * Only the kernel needs to know about it; applications use bh_hdrlen. - */ -#if defined(KERNEL) || defined(_KERNEL) -#define SIZEOF_BPF_HDR 18 -#endif - -/* - * Data-link level type codes. - */ - -/* - * These are the types that are the same on all platforms; on other - * platforms, a should be supplied that defines the additional - * DLT_* codes appropriately for that platform (the BSDs, for example, - * should not just pick up this version of "bpf.h"; they should also define - * the additional DLT_* codes used by their kernels, as well as the values - * defined here - and, if the values they use for particular DLT_ types - * differ from those here, they should use their values, not the ones - * here). - */ -#define DLT_NULL 0 /* no link-layer encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* IEEE 802 Networks */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ - -/* - * These are values from the traditional libpcap "bpf.h". - * Ports of this to particular platforms should replace these definitions - * with the ones appropriate to that platform, if the values are - * different on that platform. - */ -#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ -#define DLT_RAW 12 /* raw IP */ - -/* - * These are values from BSD/OS's "bpf.h". - * These are not the same as the values from the traditional libpcap - * "bpf.h"; however, these values shouldn't be generated by any - * OS other than BSD/OS, so the correct values to use here are the - * BSD/OS values. - * - * Platforms that have already assigned these values to other - * DLT_ codes, however, should give these codes the values - * from that platform, so that programs that use these codes will - * continue to compile - even though they won't correctly read - * files of these types. - */ -#ifdef __NetBSD__ -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif - -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ - -/* - * These values are defined by NetBSD; other platforms should refrain from - * using them for other purposes, so that NetBSD savefiles with link - * types of 50 or 51 can be read as this type on all platforms. - */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ - -/* - * Values between 100 and 103 are used in capture file headers as - * link-layer types corresponding to DLT_ types that differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * This value was defined by libpcap 0.5; platforms that have defined - * it with a different value should define it here with that value - - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, - * whatever value that happens to be, so programs will correctly - * handle files with that link type regardless of the value of - * DLT_C_HDLC. - * - * The name DLT_C_HDLC was used by BSD/OS; we use that name for source - * compatibility with programs written for BSD/OS. - * - * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, - * for source compatibility with programs written for libpcap 0.5. - */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC - -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - -/* - * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, - * except when it isn't. (I.e., sometimes it's just raw IP, and - * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, - * so that we don't have to worry about the link-layer header.) - */ - -/* - * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides - * with other values. - * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header - * (DLCI, etc.). - */ -#define DLT_FRELAY 107 - -/* - * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except - * that the AF_ type in the link-layer header is in network byte order. - * - * OpenBSD defines it as 12, but that collides with DLT_RAW, so we - * define it as 108 here. If OpenBSD picks up this file, it should - * define DLT_LOOP as 12 in its version, as per the comment above - - * and should not use 108 as a DLT_ value. - */ -#define DLT_LOOP 108 - -/* - * Values between 109 and 112 are used in capture file headers as - * link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ types - * other than the corresponding DLT_ types. - */ - -/* - * This is for Linux cooked sockets. - */ -#define DLT_LINUX_SLL 113 - -/* - * Apple LocalTalk hardware. - */ -#define DLT_LTALK 114 - -/* - * Acorn Econet. - */ -#define DLT_ECONET 115 - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define DLT_IPFILTER 116 - -/* - * Reserved for use in capture-file headers as a link-layer type - * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, - * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it - * in capture-file headers. - */ -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * Reserved for 802.11 cards using the Prism II chips, with a link-layer - * header including Prism monitor mode information plus an 802.11 - * header. - */ -#define DLT_PRISM_HEADER 119 - -/* - * Reserved for Aironet 802.11 cards, with an Aironet link-layer header - * (see Doug Ambrisko's FreeBSD patches). - */ -#define DLT_AIRONET_HEADER 120 - -/* - * Reserved for Siemens HiPath HDLC. - */ -#define DLT_HHDLC 121 - -/* - * This is for RFC 2625 IP-over-Fibre Channel. - * - * This is not for use with raw Fibre Channel, where the link-layer - * header starts with a Fibre Channel frame header; it's for IP-over-FC, - * where the link-layer header starts with an RFC 2625 Network_Header - * field. - */ -#define DLT_IP_OVER_FC 122 - -/* - * This is for Full Frontal ATM on Solaris with SunATM, with a - * pseudo-header followed by an AALn PDU. - * - * There may be other forms of Full Frontal ATM on other OSes, - * with different pseudo-headers. - * - * If ATM software returns a pseudo-header with VPI/VCI information - * (and, ideally, packet type information, e.g. signalling, ILMI, - * LANE, LLC-multiplexed traffic, etc.), it should not use - * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump - * and the like don't have to infer the presence or absence of a - * pseudo-header and the form of the pseudo-header. - */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ - -/* - * Reserved as per request from Kent Dahlgren - * for private use. - */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but could and arguably should also be used by non-AVS Linux - * 802.11 drivers and BSD drivers; that may happen in the future. - */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */ - -/* - * Reserved for the TZSP encapsulation, as per request from - * Chris Waters - * TZSP is a generic encapsulation for any other link type, - * which includes a means to include meta-information - * with the packet, e.g. signal strength and channel - * for 802.11 packets. - */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ - -/* - * BSD's ARCNET headers have the source host, destination host, - * and type at the beginning of the packet; that's what's handed - * up to userland via BPF. - * - * Linux's ARCNET headers, however, have a 2-byte offset field - * between the host IDs and the type; that's what's handed up - * to userland via PF_PACKET sockets. - * - * We therefore have to have separate DLT_ values for them. - */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ - -/* - * The instruction encodings. - */ -/* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 - -/* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 - -/* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 - -/* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 - -/* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 - -/* - * The instruction data structure. - */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_int32 k; -}; - -/* - * Macros for insn array initializers. - */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } - -#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL)) -/* - * Systems based on non-BSD kernels don't have ifnet's (or they don't mean - * anything if it is in ) and won't work like this. - */ -# if __STDC__ -extern void bpf_tap(struct ifnet *, u_char *, u_int); -extern void bpf_mtap(struct ifnet *, struct mbuf *); -extern void bpfattach(struct ifnet *, u_int, u_int); -extern void bpfilterattach(int); -# else -extern void bpf_tap(); -extern void bpf_mtap(); -extern void bpfattach(); -extern void bpfilterattach(); -# endif /* __STDC__ */ -#endif /* BSD && (_KERNEL || KERNEL) */ -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(struct bpf_insn *, int); -extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif - -/* - * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). - */ -#define BPF_MEMWORDS 16 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/arch/win32/ip6_misc.h b/src/arch/win32/ip6_misc.h deleted file mode 100644 index 6714f0e..0000000 --- a/src/arch/win32/ip6_misc.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header$ (LBL) - */ - -/* - * This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows - */ - -#include - -#ifndef __MINGW32__ -#include -#endif /* __MINGW32__ */ - -#define IN_MULTICAST(a) IN_CLASSD(a) - -#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xe0000000) == 0xe0000000) - -#define IN_LOOPBACKNET 127 - -#ifdef __MINGW32__ -/* IPv6 address */ -struct in6_addr - { - union - { - u_int8_t u6_addr8[16]; - u_int16_t u6_addr16[8]; - u_int32_t u6_addr32[4]; - } in6_u; -#define s6_addr in6_u.u6_addr8 -#define s6_addr16 in6_u.u6_addr16 -#define s6_addr32 in6_u.u6_addr32 -#define s6_addr64 in6_u.u6_addr64 - }; - -#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } -#endif /* __MINGW32__ */ - - -#ifdef __MINGW32__ -typedef unsigned short sa_family_t; - -#define __SOCKADDR_COMMON(sa_prefix) \ - sa_family_t sa_prefix##family - -/* Ditto, for IPv6. */ -struct sockaddr_in6 - { - __SOCKADDR_COMMON (sin6_); - u_int16_t sin6_port; /* Transport layer port # */ - u_int32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ - }; - -#define IN6_IS_ADDR_V4MAPPED(a) \ - ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ - (((u_int32_t *) (a))[2] == htonl (0xffff))) - -#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff) - -#define IN6_IS_ADDR_LINKLOCAL(a) \ - ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000)) - -#define IN6_IS_ADDR_LOOPBACK(a) \ - (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ - ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) -#endif /* __MINGW32__ */ - -#define ip6_vfc ip6_ctlun.ip6_un2_vfc -#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow -#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen -#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt -#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim -#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim - -#define nd_rd_type nd_rd_hdr.icmp6_type -#define nd_rd_code nd_rd_hdr.icmp6_code -#define nd_rd_cksum nd_rd_hdr.icmp6_cksum -#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] - -/* - * IPV6 extension headers - */ -#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ -#define IPPROTO_IPV6 41 /* IPv6 header. */ -#define IPPROTO_ROUTING 43 /* IPv6 routing header */ -#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ -#define IPPROTO_ESP 50 /* encapsulating security payload */ -#define IPPROTO_AH 51 /* authentication header */ -#define IPPROTO_ICMPV6 58 /* ICMPv6 */ -#define IPPROTO_NONE 59 /* IPv6 no next header */ -#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ -#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ - -#define IPV6_RTHDR_TYPE_0 0 - -/* Option types and related macros */ -#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ -#define IP6OPT_PADN 0x01 /* 00 0 00001 */ -#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ -#define IP6OPT_JUMBO_LEN 6 -#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ - -#define IP6OPT_RTALERT_LEN 4 -#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ -#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ -#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ -#define IP6OPT_MINLEN 2 - -#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ -#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ -#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ -#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ -#define IP6OPT_EID 0x8a /* 10 0 01010 */ - -#define IP6OPT_TYPE(o) ((o) & 0xC0) -#define IP6OPT_TYPE_SKIP 0x00 -#define IP6OPT_TYPE_DISCARD 0x40 -#define IP6OPT_TYPE_FORCEICMP 0x80 -#define IP6OPT_TYPE_ICMP 0xC0 - -#define IP6OPT_MUTABLE 0x20 - - -#ifdef __MINGW32__ -#ifndef EAI_ADDRFAMILY -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif -#endif /* __MINGW32__ */ diff --git a/src/arch/win32/pcap-stdinc.h b/src/arch/win32/pcap-stdinc.h deleted file mode 100644 index 221003d..0000000 --- a/src/arch/win32/pcap-stdinc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2002 - * Politecnico di Torino. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the Politecnico - * di Torino, and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header$ (LBL) - */ - -#define SIZEOF_CHAR 1 -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 - -#define _WINSOCKAPI_ -#include - -#include -#include "bittypes.h" -#include -#include - -#ifndef __MINGW32__ -#include "IP6_misc.h" -#endif - -#define caddr_t char* - -#define snprintf _snprintf -//#define vsnprintf _vsnprintf - diff --git a/src/arch/win32/pcap.h b/src/arch/win32/pcap.h deleted file mode 100644 index 3b8dcda..0000000 --- a/src/arch/win32/pcap.h +++ /dev/null @@ -1,273 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#) $Header$ (LBL) - */ - -#ifndef lib_pcap_h -#define lib_pcap_h - -#include - -#if defined _MSC_VER -# include -#else -#include -#endif - -/* RGJ Changed it to "bpf.h" for AppleWin */ -#include "bpf.h" - -#include - -#ifdef REMOTE - // We have to define the SOCKET here, although it has been defined in sockutils.h - // This is to avoid the distribution of the 'sockutils.h' file around - // (for example in the WinPcap developer's pack) - #ifndef SOCKET - #ifdef WIN32 - #define SOCKET unsigned int - #else - #define SOCKET int - #endif - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 - -#define PCAP_ERRBUF_SIZE 256 - -/* - * Compatibility for systems that have a bpf.h that - * predates the bpf typedefs for 64-bit support. - */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; - -/* - * The first record in the file contains saved values for some - * of the flags used in the printout phases of tcpdump. - * Many fields here are 32 bit ints so compilers won't insert unwanted - * padding; these files need to be interchangeable across architectures. - * - * Do not change the layout of this structure, in any way (this includes - * changes that only affect the length of fields in this structure). - * - * Also, do not change the interpretation of any of the members of this - * structure, in any way (this includes using values other than - * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" - * field). - * - * Instead: - * - * introduce a new structure for the new format, if the layout - * of the structure changed; - * - * send mail to "tcpdump-workers@tcpdump.org", requesting a new - * magic number for your new capture file format, and, when - * you get the new magic number, put it in "savefile.c"; - * - * use that magic number for save files with the changed file - * header; - * - * make the code in "savefile.c" capable of reading files with - * the old file header as well as files with the new file header - * (using the magic number to determine the header format). - * - * Then supply the changes to "patches@tcpdump.org", so that future - * versions of libpcap and programs that use it (such as tcpdump) will - * be able to read your new capture file format. - */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; - -/* - * Each packet in the dump file is prepended with this generic header. - * This gets around the problem of different headers for different - * packet interfaces. - */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; - -/* - * As returned by the pcap_stats() - */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef REMOTE -#ifdef WIN32 -// u_int bs_capt; /* number of packets that reach the application */ -#endif /* WIN32 */ - u_int ps_capt; /* number of packets that reach the application; please get rid off the Win32 ifdef */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif -}; - -/* - * Item in a list of interfaces. - */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; - -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ - -/* - * Representation of an interface address. - */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; - -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); - -char *pcap_lookupdev(char *); -int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); -pcap_t *pcap_open_live(const char *, int, int, int, char *); -pcap_t *pcap_open_dead(int, int); -pcap_t *pcap_open_offline(const char *, char *); -void pcap_close(pcap_t *); -int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -const u_char* - pcap_next(pcap_t *, struct pcap_pkthdr *); -int pcap_stats(pcap_t *, struct pcap_stat *); -int pcap_setfilter(pcap_t *, struct bpf_program *); -int pcap_getnonblock(pcap_t *, char *); -int pcap_setnonblock(pcap_t *, int, char *); -void pcap_perror(pcap_t *, char *); -char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -int pcap_compile(pcap_t *, struct bpf_program *, char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - char *, int, bpf_u_int32); -void pcap_freecode(struct bpf_program *); -int pcap_datalink(pcap_t *); -int pcap_list_datalinks(pcap_t *, int **); -int pcap_set_datalink(pcap_t *, int); -int pcap_datalink_name_to_val(const char *); -const char *pcap_datalink_val_to_name(int); -int pcap_snapshot(pcap_t *); -int pcap_is_swapped(pcap_t *); -int pcap_major_version(pcap_t *); -int pcap_minor_version(pcap_t *); - -/* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); - -pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -int pcap_dump_flush(pcap_dumper_t *); -void pcap_dump_close(pcap_dumper_t *); -void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); - -int pcap_findalldevs(pcap_if_t **, char *); -void pcap_freealldevs(pcap_if_t *); - -/* To avoid callback, this returns one packet at a time */ -int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data); - -/* XXX this guy lives in the bpf tree */ -u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); -int bpf_validate(struct bpf_insn *f, int len); -char *bpf_image(struct bpf_insn *, int); -void bpf_dump(struct bpf_program *, int); - -#ifdef WIN32 -/* - * Win32 definitions - */ - -int pcap_setbuff(pcap_t *p, int dim); -int pcap_setmode(pcap_t *p, int mode); -int pcap_sendpacket(pcap_t *p, u_char *buf, int size); -int pcap_setmintocopy(pcap_t *p, int size); - -#ifdef WPCAP -/* Include file with the wpcap-specific extensions */ -#include -#endif - -#define MODE_CAPT 0 -#define MODE_STAT 1 -#define MODE_MON 2 - -#endif /* WIN32 */ - -#ifdef REMOTE -/* Includes most of the public stuff that is needed for the remote capture */ -#include "remote-ext.h" -#endif - - - -#ifdef __cplusplus -} -#endif - -#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/GSOS.text b/src/assets/GSOS.text new file mode 100644 index 0000000..894d3d6 --- /dev/null +++ b/src/assets/GSOS.text @@ -0,0 +1,120 @@ +; ProDOS 16 Calls. +0001 CREATE +0002 DESTROY +0004 CHANGE_PATH +0005 SET_FILE_INFO +0006 GET_FILE_INFO +0008 VOLUME +0009 SET_PREFIX +000A GET_PREFIX +000B CLEAR_BACKUP_BIT +0010 OPEN +0011 NEWLINE +0012 READ +0013 WRITE +0014 CLOSE +0015 FLUSH +0016 SET_MARK +0017 GET_MARK +0018 SET_EOF +0019 GET_EOF +001A SET_LEVEL +001B GET_LEVEL +001C GET_DIR_ENTRY +0020 GET_DEV_NUM +0021 GET_LAST_DEV +0022 READ_BLOCK +0023 WRITE_BLOCK +0024 FORMAT +0025 ERASE_DISK +0027 GET_NAME +0028 GET_BOOT_VOL +0029 QUIT +002A GET_VERSION +002C D_INFO +0031 ALLOC_INTERRUPT +0032 DEALLOCATE_INTERRUPT +; ORCA/Shell calls. +0101 Get_LInfo +0102 Set_LInfo +0103 Get_Lang +0104 Set_Lang +0105 Error +0106 Set_Variable +0107 Version +0108 Read_Indexed +0109 Init_Wildcard +010A Next_Wildcard +010B Read_Variable +010C ChangeVector +010D Execute +010E FastFile +010F Direction +0110 Redirect +0113 Stop +0114 ExpandDevices +0115 UnsetVariable +0116 Export +0117 PopVariables +0118 PushVariables +0119 SetStopFlag +011A ConsoleOut +011B SetIODevices +011C GetIODevices +011D GetCommand +; GS/OS Calls. +2001 Create +2002 Destroy +2003 OSShutdown +2004 ChangePath +2005 SetFileInfo +2006 GetFileInfo +2007 JudgeName +2008 Volume +2009 SetPrefix +200A GetPrefix +200B ClearBackup +200C SetSysPrefs +200D Null +200E ExpandPath +200F GetSysPrefs +2010 Open +2011 NewLine +2012 Read +2013 Write +2014 Close +2015 Flush +2016 SetMark +2017 GetMark +2018 SetEOF +2019 GetEOF +201A SetLevel +201B GetLevel +201C GetDirEntry +201D BeginSession +201E EndSession +201F SessionStatus +2020 GetDevNumber +2024 Format +2025 EraseDisk +2026 ResetCache +2027 GetName +2028 GetBootvol +2029 Quit +202A GetVersion +202B GetFSTInfo +202C DInfo +202D DStatus +202E DControl +202F DRead +2030 DWrite +2031 BindInt +2032 UnbindInt +2033 FSTSpecific +2034 AddNotifyProc +2035 DelNotifyProc +2036 DRename +2037 GetStdRefNum +2038 GetRefNum +2039 GetRefInfo +203A SetStdRefNum 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/Tools.text b/src/assets/Tools.text new file mode 100644 index 0000000..892bed2 --- /dev/null +++ b/src/assets/Tools.text @@ -0,0 +1,1460 @@ +; === System Tools === +; === tool locator === +0101 TLBootInit +0201 TLStartUp +0301 TLShutDown +0401 TLVersion +0501 TLReset +0601 TLStatus +0901 GetTSPtr +0A01 SetTSPtr +0B01 GetFuncPtr +0C01 GetWAP +0D01 SetWAP +0E01 LoadTools +0F01 LoadOneTool +1001 UnloadOneTool +1101 TLMountVolume +1201 TLTextMountVolume +1301 SaveTextState +1401 RestoreTextState +1501 MessageCenter +1601 SetDefaultTPT +1701 MessageByName +1801 StartUpTools +1901 ShutDownTools +1A01 GetMsgHandle +1B01 AcceptRequests +1C01 SendRequest +; === memory manager === +0102 MMBootInit +0202 MMStartUp +0302 MMShutDown +0402 MMVersion +0502 MMReset +0602 MMStatus +0902 NewHandle +0A02 ReAllocHandle +0B02 RestoreHandle +0C02 AddToOOMQueue +0D02 RemoveFromOOMQueue +1002 DisposeHandle +1102 DisposeAll +1202 PurgeHandle +1302 PurgeAll +1802 GetHandleSize +1902 SetHandleSize +1A02 FindHandle +1B02 FreeMem +1C02 MaxBlock +1D02 TotalMem +1E02 CheckHandle +1F02 CompactMem +2002 HLock +2102 HLockAll +2202 HUnlock +2302 HUnlockAll +2402 SetPurge +2502 SetPurgeAll +2802 PtrToHand +2902 HandToPtr +2A02 HandToHand +2B02 BlockMove +2F02 RealFreeMem +3002 SetHandleID +; === misc tools === +0103 MTBootInit +0203 MTStartUp +0303 MTShutDown +0403 MTVersion +0503 MTReset +0603 MTStatus +0903 WriteBRam +0A03 ReadBRam +0B03 WriteBParam +0C03 ReadBParam +0D03 ReadTimeHex +0E03 WriteTimeHex +0F03 ReadAsciiTime +1003 SetVector +1103 GetVector +1203 SetHeartBeat +1303 DelHeartBeat +1403 ClrHeartBeat +1503 SysFailMgr +1603 GetAddr +1703 ReadMouse +1803 InitMouse +1903 SetMouse +1A03 HomeMouse +1B03 ClearMouse +1C03 ClampMouse +1D03 GetMouseClamp +1E03 PosMouse +1F03 ServeMouse +2003 GetNewID +2103 DeleteID +2203 StatusID +2303 IntSource +2403 FWEntry +2503 GetTick +2603 PackBytes +2703 UnPackBytes +2803 Munger +2903 GetIRQEnable +2A03 SetAbsClamp +2B03 GetAbsClamp +2C03 SysBeep +2E03 AddToQueue +2F03 DeleteFromQueue +3003 SetInterruptState +3103 GetInterruptState +3203 GetIntStateRecSize +3303 ReadMouse2 +3403 GetCodeResConverter +3503 GetROMResource +3603 ReleaseROMResource +3703 ConvSeconds +3803 SysBeep2 +3903 VersionString +3A03 WaitUntil +3B03 StringToText +3C03 ShowBootInfo +3D03 ScanDevices +3E03 AlertMessage +3F03 DoSysPrefs +; === QuickDraw II === +0104 QDBootInit +0204 QDStartUp +0304 QDShutDown +0404 QDVersion +0504 QDReset +0604 QDStatus +0904 GetAddress +0A04 GrafOn +0B04 GrafOff +0C04 GetStandardSCB +0D04 InitColorTable +0E04 SetColorTable +0F04 GetColorTable +1004 SetColorEntry +1104 GetColorEntry +1204 SetSCB +1304 GetSCB +1404 SetAllSCBs +1504 ClearScreen +1604 SetMasterSCB +1704 GetMasterSCB +1804 OpenPort +1904 InitPort +1A04 ClosePort +1B04 SetPort +1C04 GetPort +1D04 SetPortLoc +1E04 GetPortLoc +1F04 SetPortRect +2004 GetPortRect +2104 SetPortSize +2204 MovePortTo +2304 SetOrigin +2404 SetClip +2504 GetClip +2604 ClipRect +2704 HidePen +2804 ShowPen +2904 GetPen +2A04 SetPenState +2B04 GetPenState +2C04 SetPenSize +2D04 GetPenSize +2E04 SetPenMode +2F04 GetPenMode +3004 SetPenPat +3104 GetPenPat +3204 SetPenMask +3304 GetPenMask +3404 SetBackPat +3504 GetBackPat +3604 PenNormal +3704 SetSolidPenPat +3804 SetSolidBackPat +3904 SolidPattern +3A04 MoveTo +3B04 Move +3C04 LineTo +3D04 Line +3E04 SetPicSave +3F04 GetPicSave +4004 SetRgnSave +4104 GetRgnSave +4204 SetPolySave +4304 GetPolySave +4404 SetGrafProcs +4504 GetGrafProcs +4604 SetUserField +4704 GetUserField +4804 SetSysField +4904 GetSysField +4A04 SetRect +4B04 OffsetRect +4C04 InsetRect +4D04 SectRect +4E04 UnionRect +4F04 PtInRect +5004 Pt2Rect +5104 EqualRect +5204 NotEmptyRect +5304 FrameRect +5404 PaintRect +5504 EraseRect +5604 InvertRect +5704 FillRect +5804 FrameOval +5904 PaintOval +5A04 EraseOval +5B04 InvertOval +5C04 FillOval +5D04 FrameRRect +5E04 PaintRRect +5F04 EraseRRect +6004 InvertRRect +6104 FillRRect +6204 FrameArc +6304 PaintArc +6404 EraseArc +6504 InvertArc +6604 FillArc +6704 NewRgn +6804 DisposeRgn +6904 CopyRgn +6A04 SetEmptyRgn +6B04 SetRectRgn +6C04 RectRgn +6D04 OpenRgn +6E04 CloseRgn +6F04 OffsetRgn +7004 InsetRgn +7104 SectRgn +7204 UnionRgn +7304 DiffRgn +7404 XorRgn +7504 PtInRgn +7604 RectInRgn +7704 EqualRgn +7804 EmptyRgn +7904 FrameRgn +7A04 PaintRgn +7B04 EraseRgn +7C04 InvertRgn +7D04 FillRgn +7E04 ScrollRect +7F04 PaintPixels +8004 AddPt +8104 SubPt +8204 SetPt +8304 EqualPt +8404 LocalToGlobal +8504 GlobalToLocal +8604 Random +8704 SetRandSeed +8804 GetPixel +8904 ScalePt +8A04 MapPt +8B04 MapRect +8C04 MapRgn +8D04 SetStdProcs +8E04 SetCursor +8F04 GetCursorAdr +9004 HideCursor +9104 ShowCursor +9204 ObscureCursor +9304 SetMouseLoc ??? +9404 SetFont +9504 GetFont +9604 GetFontInfo +9704 GetFontGlobals +9804 SetFontFlags +9904 GetFontFlags +9A04 SetTextFace +9B04 GetTextFace +9C04 SetTextMode +9D04 GetTextMode +9E04 SetSpaceExtra +9F04 GetSpaceExtra +A004 SetForeColor +A104 GetForeColor +A204 SetBackColor +A304 GetBackColor +A404 DrawChar +A504 DrawString +A604 DrawCString +A704 DrawText +A804 CharWidth +A904 StringWidth +AA04 CStringWidth +AB04 TextWidth +AC04 CharBounds +AD04 StringBounds +AE04 CStringBounds +AF04 TextBounds +B004 SetArcRot +B104 GetArcRot +B204 SetSysFont +B304 GetSysFont +B404 SetVisRgn +B504 GetVisRgn +B604 SetIntUse +B704 OpenPicture +B804 PicComment +B904 ClosePicture +BA04 DrawPicture +BB04 KillPicture +BC04 FramePoly +BD04 PaintPoly +BE04 ErasePoly +BF04 InvertPoly +C004 FillPoly +C104 OpenPoly +C204 ClosePoly +C304 KillPoly +C404 OffsetPoly +C504 MapPoly +C604 SetClipHandle +C704 GetClipHandle +C804 SetVisHandle +C904 GetVisHandle +CA04 InitCursor +CB04 SetBufDims +CC04 ForceBufDims +CD04 SaveBufDims +CE04 RestoreBufDims +CF04 GetFGSize +D004 SetFontID +D104 GetFontID +D204 SetTextSize +D304 GetTextSize +D404 SetCharExtra +D504 GetCharExtra +D604 PPToPort +D704 InflateTextBuffer +D804 GetRomFont +D904 GetFontLore +DA04 Get640Colors +DB04 Set640Color +; === desk manager === +0105 DeskBootInit +0205 DeskStartUp +0305 DeskShutDown +0405 DeskVersion +0505 DeskReset +0605 DeskStatus +0905 SaveScrn +0A05 RestScrn +0B05 SaveAll +0C05 RestAll +0E05 InstallNDA +0F05 InstallCDA +1105 ChooseCDA +1305 SetDAStrPtr +1405 GetDAStrPtr +1505 OpenNDA +1605 CloseNDA +1705 SystemClick +1805 SystemEdit +1905 SystemTask +1A05 SystemEvent +1B05 GetNumNDAs +1C05 CloseNDAbyWinPtr +1D05 CloseAllNDAs +1E05 FixAppleMenu +1F05 AddToRunQ +2005 RemoveFromRunQ +2105 RemoveCDA +2205 RemoveNDA +2305 GetDeskAccInfo +2405 CallDeskAcc +2505 GetDeskGlobal +; === event manager === +0106 EMBootInit +0206 EMStartUp +0306 EMShutDown +0406 EMVersion +0506 EMReset +0606 EMStatus +0906 DoWindows +0A06 GetNextEvent +0B06 EventAvail +0C06 GetMouse +0D06 Button +0E06 StillDown +0F06 WaitMouseUp +1006 TickCount +1106 GetDblTime +1206 GetCaretTime +1306 SetSwitch +1406 PostEvent +1506 FlushEvents +1606 GetOSEvent +1706 OSEventAvail +1806 SetEventMask +1906 FakeMouse +1A06 SetAutoKeyLimit +1B06 GetKeyTranslation +1C06 SetKeyTranslation +; === scheduler === +0107 SchBootInit +0207 SchStartUp +0307 SchShutDown +0407 SchVersion +0507 SchReset +0607 SchStatus +0907 SchAddTask +0A07 SchFlush +; === sound manager === +0108 SoundBootInit +0208 SoundStartUp +0308 SoundShutDown +0408 SoundVersion +0508 SoundReset +0608 SoundToolStatus +0908 WriteRamBlock +0A08 ReadRamBlock +0B08 GetTableAddress +0C08 GetSoundVolume +0D08 SetSoundVolume +0E08 FFStartSound +0F08 FFStopSound +1008 FFSoundStatus +1108 FFGeneratorStatus +1208 SetSoundMIRQV +1308 SetUserSoundIRQV +1408 FFSoundDoneStatus +1508 FFSetUpSound +1608 FFStartPlaying +1708 SetDocReg +1808 ReadDocReg +; === desktop bus === +0109 ADBBootInit +0209 ADBStartUp +0309 ADBShutDown +0409 ADBVersion +0509 ADBReset +0609 ADBStatus +0909 SendInfo +0A09 ReadKeyMicroData +0B09 ReadKeyMicroMemory +;0C09 [resynch--don't call] +0D09 AsyncADBReceive +0E09 SyncADBReceive +0F09 AbsOn +1009 AbsOff +1109 RdAbs +1209 SetAbsScale +1309 GetAbsScale +1409 SRQPoll +1509 SRQRemove +1609 ClearSRQTable +;FF09 [OBSOLETE: Use 09FF] +; === SANE === +010A SANEBootInit +020A SANEStartUp +030A SANEShutDown +040A SANEVersion +050A SANEReset +060A SANEStatus +090A FPNum +0A0A DecStrNum +0B0A ElemNum +;FF0A [OBSOLETE: USE $0AFF] +; === integer math === +010B IMBootInit +020B IMStartUp +030B IMShutDown +040B IMVersion +050B IMReset +060B IMStatus +090B Multiply +0A0B SDivide +0B0B UDivide +0C0B LongMul +0D0B LongDivide +0E0B FixRatio +0F0B FixMul +100B FracMul +110B FixDiv +120B FracDiv +130B FixRound +140B FracSqrt +150B FracCos +160B FracSin +170B FixATan2 +180B HiWord +190B LoWord +1A0B Long2Fix +1B0B Fix2Long +1C0B Fix2Frac +1D0B Frac2Fix +1E0B Fix2X +1F0B Frac2X +200B X2Fix +210B X2Frac +220B Int2Hex +230B Long2Hex +240B Hex2Int +250B Hex2Long +260B Int2Dec +270B Long2Dec +280B Dec2Int +290B Dec2Long +2A0B HexIt +; === text tools === +010C TextBootInit +020C TextStartUp +030C TextShutDown +040C TextVersion +050C TextReset +060C TextStatus +090C SetInGlobals +0A0C SetOutGlobals +0B0C SetErrGlobals +0C0C GetInGlobals +0D0C GetOutGlobals +0E0C GetErrGlobals +0F0C SetInputDevice +100C SetOutputDevice +110C SetErrorDevice +120C GetInputDevice +130C GetOutputDevice +140C GetErrorDevice +150C InitTextDev +160C CtlTextDev +170C StatusTextDev +180C WriteChar +190C ErrWriteChar +1A0C WriteLine +1B0C ErrWriteLine +1C0C WriteString +1D0C ErrWriteString +1E0C TextWriteBlock +1F0C ErrWriteBlock +200C WriteCString +210C ErrWriteCString +220C ReadChar +230C TextReadBlock +240C ReadLine +; === window manager === +010E WindBootInit +020E WindStartUp +030E WindShutDown +040E WindVersion +050E WindReset +060E WindStatus +090E NewWindow +0A0E CheckUpdate +0B0E CloseWindow +0C0E Desktop +0D0E SetWTitle +0E0E GetWTitle +0F0E SetFrameColor +100E GetFrameColor +110E SelectWindow +120E HideWindow +130E ShowWindow +140E SendBehind +150E FrontWindow +160E SetInfoDraw +170E FindWindow +180E TrackGoAway +190E MoveWindow +1A0E DragWindow +1B0E GrowWindow +1C0E SizeWindow +1D0E TaskMaster +1E0E BeginUpdate +1F0E EndUpdate +200E GetWMgrPort +210E PinRect +220E HiliteWindow +230E ShowHide +240E BringToFront +250E WindNewRes +260E TrackZoom +270E ZoomWindow +280E SetWRefCon +290E GetWRefCon +2A0E GetNextWindow +2B0E GetWKind +2C0E GetWFrame +2D0E SetWFrame +2E0E GetStructRgn +2F0E GetContentRgn +300E GetUpdateRgn +310E GetDefProc +320E SetDefProc +330E GetWControls +340E SetOriginMask +350E GetInfoRefCon +360E SetInfoRefCon +370E GetZoomRect +380E SetZoomRect +390E RefreshDesktop +3A0E InvalRect +3B0E InvalRgn +3C0E ValidRect +3D0E ValidRgn +3E0E GetContentOrigin +3F0E SetContentOrigin +400E GetDataSize +410E SetDataSize +420E GetMaxGrow +430E SetMaxGrow +440E GetScroll +450E SetScroll +460E GetPage +470E SetPage +480E GetContentDraw +490E SetContentDraw +4A0E GetInfoDraw +4B0E SetSysWindow +4C0E GetSysWFlag +4D0E StartDrawing +4E0E SetWindowIcons +4F0E GetRectInfo +500E StartInfoDrawing +510E EndInfoDrawing +520E GetFirstWindow +530E WindDragRect +540E GetDragRectPtr +550E DrawInfoBar +560E WindowGlobal +570E SetContentOrigin2 +580E GetWindowMgrGlobals +590E AlertWindow +5A0E StartFrameDrawing +5B0E EndFrameDrawing +5C0E ResizeWindow +5D0E TaskMasterContent +5E0E TaskMasterKey +5F0E TaskMasterDA +600E CompileText +610E NewWindow2 +620E ErrorWindow +630E GetAuxWindInfo +640E DoModalWindow +650E MWGetCtlPart +660E MWSetMenuProc +670E MWStdDrawProc +680E MWSetUpEditMenu +690E FindCursorCtl +6A0E ResizeInfoBar +6B0E HandleDiskInsert +6C0E UpdateWindow +; === menu manager === +010F MenuBootInit +020F MenuStartUp +030F MenuShutDown +040F MenuVersion +050F MenuReset +060F MenuStatus +090F MenuKey +0A0F GetMenuBar +0B0F MenuRefresh +0C0F FlashMenuBar +0D0F InsertMenu +0E0F DeleteMenu +0F0F InsertMItem +100F DeleteMItem +110F GetSysBar +120F SetSysBar +130F FixMenuBar +140F CountMItems +150F NewMenuBar +160F GetMHandle +170F SetBarColors +180F GetBarColors +190F SetMTitleStart +1A0F GetMTitleStart +1B0F GetMenuMgrPort +1C0F CalcMenuSize +1D0F SetMTitleWidth +1E0F GetMTitleWidth +1F0F SetMenuFlag +200F GetMenuFlag +210F SetMenuTitle +220F GetMenuTitle +230F MenuGlobal +240F SetMItem +250F GetMItem +260F SetMItemFlag +270F GetMItemFlag +280F SetMItemBlink +290F MenuNewRes +2A0F DrawMenuBar +2B0F MenuSelect +2C0F HiliteMenu +2D0F NewMenu +2E0F DisposeMenu +2F0F InitPalette +300F EnableMItem +310F DisableMItem +320F CheckMItem +330F SetMItemMark +340F GetMItemMark +350F SetMItemStyle +360F GetMItemStyle +370F SetMenuID +380F SetMItemID +390F SetMenuBar +3A0F SetMItemName +3B0F GetPopUpDefProc +3C0F PopUpMenuSelect +3D0F DrawPopUp +3E0F NewMenu2 +3F0F InsertMItem2 +400F SetMenuTitle2 +410F SetMItem2 +420F SetMItemName2 +430F NewMenuBar2 +450F HideMenuBar +460F ShowMenuBar +470F SetMItemIcon +480F GetMItemIcon +490F SetMItemStruct +4A0F GetMItemStruct +4B0F RemoveMItemStruct +4C0F GetMItemFlag2 +4D0F SetMItemFlag2 +4F0F GetMItemBlink +500F InsertPathMItems +; === control manager === +0110 CtlBootInit +0210 CtlStartUp +0310 CtlShutDown +0410 CtlVersion +0510 CtlReset +0610 CtlStatus +0910 NewControl +0A10 DisposeControl +0B10 KillControls +0C10 SetCtlTitle +0D10 GetCtlTitle +0E10 HideControl +0F10 ShowControl +1010 DrawControls +1110 HiliteControl +1210 CtlNewRes +1310 FindControl +1410 TestControl +1510 TrackControl +1610 MoveControl +1710 DragControl +1810 SetCtlIcons +1910 SetCtlValue +1A10 GetCtlValue +1B10 SetCtlParams +1C10 GetCtlParams +1D10 DragRect +1E10 GrowSize +1F10 GetCtlDpage +2010 SetCtlAction +2110 GetCtlAction +2210 SetCtlRefCon +2310 GetCtlRefCon +2410 EraseControl +2510 DrawOneCtl +2610 FindTargetCtl +2710 MakeNextCtlTarget +2810 MakeThisCtlTarget +2910 SendEventToCtl +2A10 GetCtlID +2B10 SetCtlID +2C10 CallCtlDefProc +2D10 NotifyCtls +2E10 GetCtlMoreFlags +2F10 SetCtlMoreFlags +3010 GetCtlHandleFromID +3110 NewControl2 +3210 CMLoadResource +3310 CMReleaseResource +3410 SetCtlParamPtr +3510 GetCtlParamPtr +3710 InvalCtls +;3810 [reserved] +3910 FindRadioButton +3A10 SetLETextByID +3B10 GetLETextByID +3C10 SetCtlValueByID +3D10 GetCtlValueByID +3E10 InvalOneCtlByID +3F10 HiliteCtlByID +; === loader === +0111 LoaderBootInit +0211 LoaderStartUp +0311 LoaderShutDown +0411 LoaderVersion +0511 LoaderReset +0611 LoaderStatus +0911 InitialLoad +0A11 Restart +0B11 LoadSegNum +0C11 UnloadSegNum +0D11 LoadSegName +0E11 UnloadSeg +0F11 GetLoadSegInfo +1011 GetUserID +1111 LGetPathname +1211 UserShutDown +1311 RenamePathname +2011 InitialLoad2 +2111 GetUserID2 +2211 LGetPathname2 +; === QuickDraw Aux === +0112 QDAuxBootInit +0212 QDAuxStartUp +0312 QDAuxShutDown +0412 QDAuxVersion +0512 QDAuxReset +0612 QDAuxStatus +0912 CopyPixels +0A12 WaitCursor +0B12 DrawIcon +0C12 SpecialRect +0D12 SeedFill +0E12 CalcMask +0F12 GetSysIcon +1012 PixelMap2Rgn +1312 IBeamCursor +1412 WhooshRect +1512 DrawStringWidth +1612 UseColorTable +1712 RestoreColorTable +; === print manager === +0113 PMBootInit +0213 PMStartUp +0313 PMShutDown +0413 PMVersion +0513 PMReset +0613 PMStatus +0913 PrDefault +0A13 PrValidate +0B13 PrStlDialog +0C13 PrJobDialog +0D13 PrPixelMap +0E13 PrOpenDoc +0F13 PrCloseDoc +1013 PrOpenPage +1113 PrClosePage +1213 PrPicFile +1313 PrControl +1413 PrError +1513 PrSetError +1613 PrChoosePrinter +1813 PrGetPrinterSpecs +1913 PrDevPrChanged +1A13 PrDevStartup +1B13 PrDevShutDown +1C13 PrDevOpen +1D13 PrDevRead +1E13 PrDevWrite +1F13 PrDevClose +2013 PrDevStatus +2113 PrDevAsyncRead +2213 PrDevWriteBackground +2313 PrDriverVer +2413 PrPortVer +2513 PrGetZoneName +2813 PrGetPrinterDvrName +2913 PrGetPortDvrName +2A13 PrGetUserName +2B13 PrGetNetworkName +3013 PrDevIsItSafe +3113 GetZoneList +3213 GetMyZone +3313 GetPrinterList +3413 PMUnloadDriver +3513 PMLoadDriver +3613 PrGetDocName +3713 PrSetDocName +3813 PrGetPgOrientation +; === line edit === +0114 LEBootInit +0214 LEStartUp +0314 LEShutDown +0414 LEVersion +0514 LEReset +0614 LEStatus +0914 LENew +0A14 LEDispose +0B14 LESetText +0C14 LEIdle +0D14 LEClick +0E14 LESetSelect +0F14 LEActivate +1014 LEDeactivate +1114 LEKey +1214 LECut +1314 LECopy +1414 LEPaste +1514 LEDelete +1614 LEInsert +1714 LEUpdate +1814 LETextBox +1914 LEFromScrap +1A14 LEToScrap +1B14 LEScrapHandle +1C14 LEGetScrapLen +1D14 LESetScrapLen +1E14 LESetHilite +1F14 LESetCaret +2014 LETextBox2 +2114 LESetJust +2214 LEGetTextHand +2314 LEGetTextLen +2414 GetLEDefProc +2514 LEClassifyKey +; === dialog manager === +0115 DialogBootInit +0215 DialogStartUp +0315 DialogShutDown +0415 DialogVersion +0515 DialogReset +0615 DialogStatus +0915 ErrorSound +0A15 NewModalDialog +0B15 NewModelessDialog +0C15 CloseDialog +0D15 NewDItem +0E15 RemoveDItem +0F15 ModalDialog +1015 IsDialogEvent +1115 DialogSelect +1215 DlgCut +1315 DlgCopy +1415 DlgPaste +1515 DlgDelete +1615 DrawDialog +1715 Alert +1815 StopAlert +1915 NoteAlert +1A15 CautionAlert +1B15 ParamText +1C15 SetDAFont +1E15 GetControlDItem +1F15 GetIText +2015 SetIText +2115 SelectIText +2215 HideDItem +2315 ShowDItem +2415 FindDItem +2515 UpdateDialog +2615 GetDItemType +2715 SetDItemType +2815 GetDItemBox +2915 SetDItemBox +2A15 GetFirstDItem +2B15 GetNextDItem +2C15 ModalDialog2 +2E15 GetDItemValue +2F15 SetDItemValue +3215 GetNewModalDialog +3315 GetNewDItem +3415 GetAlertStage +3515 ResetAlertStage +3615 DefaultFilter +3715 GetDefButton +3815 SetDefButton +3915 DisableDItem +3A15 EnableDItem +; === scrap manager === +0116 ScrapBootInit +0216 ScrapStartUp +0316 ScrapShutDown +0416 ScrapVersion +0516 ScrapReset +0616 ScrapStatus +0916 UnloadScrap +0A16 LoadScrap +0B16 ZeroScrap +0C16 PutScrap +0D16 GetScrap +0E16 GetScrapHandle +0F16 GetScrapSize +1016 GetScrapPath +1116 SetScrapPath +1216 GetScrapCount +1316 GetScrapState +1416 GetIndScrap +1516 ShowClipboard +; === standard file === +0117 SFBootInit +0217 SFStartUp +0317 SFShutDown +0417 SFVersion +0517 SFReset +0617 SFStatus +0917 SFGetFile +0A17 SFPutFile +0B17 SFPGetFile +0C17 SFPPutFile +0D17 SFAllCaps +0E17 SFGetFile2 +0F17 SFPutFile2 +1017 SFPGetFile2 +1117 SFPPutFile2 +1217 SFShowInvisible +1317 SFReScan +1417 SFMultiGet2 +1517 SFPMultiGet2 +; === note synthesizer === +0119 NSBootInit +0219 NSStartUp +0319 NSShutDown +0419 NSVersion +0519 NSReset +0619 NSStatus +0919 AllocGen +0A19 DeallocGen +0B19 NoteOn +0C19 NoteOff +0D19 AllNotesOff +0E19 NSSetUpdateRate +0F19 NSSetUserUpdateRtn +; === note sequencer === +011A SeqBootInit +021A SeqStartUp +031A SeqShutDown +041A SeqVersion +051A SeqReset +061A SeqStatus +091A SetIncr +0A1A ClearIncr +0B1A GetTimer +0C1A GetLoc +0D1A SeqAllNotesOff +0E1A SetTrkInfo +0F1A StartSeq +101A StepSeq +111A StopSeq +121A SetInstTable +131A StartInts +141A StopInts +151A StartSeqRel +; === font manager === +011B FMBootInit +021B FMStartUp +031B FMShutDown +041B FMVersion +051B FMReset +061B FMStatus +091B CountFamilies +0A1B FindFamily +0B1B GetFamInfo +0C1B GetFamNum +0D1B AddFamily +0E1B InstallFont +0F1B SetPurgeStat +101B CountFonts +111B FindFontStats +121B LoadFont +131B LoadSysFont +141B AddFontVar +151B FixFontMenu +161B ChooseFont +171B ItemID2FamNum +181B FMSetSysFont +191B FMGetSysFID +1A1B FMGetCurFID +1B1B FamNum2ItemID +1C1B InstallWithStats +; === List Manager === +011C ListBootInit +021C ListStartUp +031C ListShutDown +041C ListVersion +051C ListReset +061C ListStatus +091C CreateList +0A1C SortList +0B1C NextMember +0C1C DrawMember +0D1C SelectMember +0E1C GetListDefProc +0F1C ResetMember +101C NewList +111C DrawMember2 +121C NextMember2 +131C ResetMember2 +141C SelectMember2 +151C SortList2 +161C NewList2 +171C ListKey +181C CompareStrings +; === Audio Compression/Expansion === +011D ACEBootInit +021D ACEStartUp +031D ACEShutDown +041D ACEVersion +051D ACEReset +061D ACEStatus +071D ACEInfo +091D ACECompress +0A1D ACEExpand +0B1D ACECompBegin +0C1D ACEExpBegin +0D1D GetACEExpState +0E1D SetACEExpState +; === Resource Manager === +011E ResourceBootInit +021E ResourceStartUp +031E ResourceShutDown +041E ResourceVersion +051E ResourceReset +061E ResourceStatus +091E CreateResourceFile +0A1E OpenResourceFile +0B1E CloseResourceFile +0C1E AddResource +0D1E UpdateResourcefile +0E1E LoadResource +0F1E RemoveResource +101E MarkResourceChange +111E SetCurResourceFile +121E GetCurResourceFile +131E SetCurResourceApp +141E GetCurResourceApp +151E HomeResourceFile +161E WriteResource +171E ReleaseResource +181E DetachResource +191E UniqueResourceID +1A1E SetResourceID +1B1E GetResourceAttr +1C1E SetResourceAttr +1D1E GetResourceSize +1E1E MatchResourceHandle +1F1E GetOpenFileRefNum +201E CountTypes +211E GetIndType +221E CountResources +231E GetIndResource +241E SetResourceLoad +251E SetResourceFileDepth +261E GetMapHandle +271E LoadAbsResource +281E ResourceConverter +291E LoadResource2 +2A1E RMFindNamedResource +2B1E RMGetResourceName +2C1E RMLoadNamedResource +2D1E RMSetResourceName +2E1E OpenResourceFileByID +2F1E CompactResourceFile +; === MIDI === +0120 MidiBootInit +0220 MidiStartUp +0320 MidiShutDown +0420 MidiVersion +0520 MidiReset +0620 MidiStatus +0920 MidiControl +0A20 MidiDevice +0B20 MidiClock +0C20 MidiInfo +0D20 MidiReadPacket +0E20 MidiWritePacket +; === Video Overlay === +0121 VDBootInit +0221 VDStartUp +0321 VDShutDown +0421 VDVersion +0521 VDReset +0621 VDStatus +0921 VDInStatus +0A21 VDInSetStd +0B21 VDInGetStd +0C21 VDInConvAdj +0D21 VDKeyControl +0E21 VDKeyStatus +0F21 VDKeySetKCol +1021 VDKeyGetKRCol +1121 VDKeyGetKGCol +1221 VDKeyGetKBCol +1321 VDKeySetKDiss +1421 VDKeyGetKDiss +1521 VDKeySetNKDiss +1621 VDKeyGetNKDiss +1721 VDOutSetStd +1821 VDOutGetStd +1921 VDOutControl +1A21 VDOutStatus +1B21 VDGetFeatures +1C21 VDInControl +1D21 VDGGControl +1E21 VDGGStatus +; === Text Edit === +0122 TEBootInit +0222 TEStartUp +0322 TEShutDown +0422 TEVersion +0522 TEReset +0622 TEStatus +0922 TENew +0A22 TEKill +0B22 TESetText +0C22 TEGetText +0D22 TEGetTextInfo +0E22 TEIdle +0F22 TEActivate +1022 TEDeactivate +1122 TEClick +1222 TEUpdate +1322 TEPaintText +1422 TEKey +;1522 [not supported] +1622 TECut +1722 TECopy +1822 TEPaste +1922 TEClear +1A22 TEInsert +1B22 TEReplace +1C22 TEGetSelection +1D22 TESetSelection +1E22 TEGetSelectionStyle +1F22 TEStyleChange +2022 TEOffsetToPoint +2122 TEPointToOffset +2222 TEGetDefProc +2322 TEGetRuler +2422 TESetRuler +2522 TEScroll +2622 TEGetInternalProc +2722 TEGetLastError +2822 TECompactRecord +; === MIDI Synth === +0123 MSBootInit +0223 MSStartUp +0323 MSShutDown +0423 MSVersion +0523 MSReset +0623 MSStatus +0923 SetBasicChannel +0A23 SetMIDIMode +0B23 PlayNote +0C23 StopNote +0D23 KillAllNotes +0E23 SetRecTrack +0F23 SetPlayTrack +1023 TrackToChannel +1123 Locate +1223 SetVelComp +1323 SetMIDIPort +1423 SetInstrument +1523 SeqPlayer +1623 SetTempo +1723 SetCallBack +1823 SysExOut +1923 SetBeat +1A23 MIDIMessage +1B23 LocateEnd +1C23 Merge +1D23 DeleteTrack +1E23 SetMetro +1F23 GetMSData +2023 ConvertToTime +2123 ConvertToMeasure +2223 MSSuspend +2323 MSResume +2423 SetTuningTable +2523 GetTuningTable +2623 SetTrackOut +2723 InitMIDIDriver +2823 RemoveMIDIDriver +; === Media Controller === +0126 MCBootInit +0226 MCStartUp +0326 MCShutDown +0426 MCVersion +0526 MCReset +0626 MCStatus +0926 MCGetErrorMsg +0A26 MCLoadDriver +0B26 MCUnLoadDriver +0C26 MCTimeToBin +0D26 MCBinToTime +0E26 MCGetTrackTitle +0F26 MCSetTrackTitle +1026 MCGetProgram +1126 MCSetProgram +1226 MCGetDiscTitle +1326 MCSetDiscTitle +1426 MCDStartUp +1526 MCDShutDown +1626 MCGetFeatures +1726 MCPlay +1826 MCPause +1926 MCSendRawData +1A26 MCGetStatus +1B26 MCControl +1C26 MCScan +1D26 MCGetSpeeds +1E26 MCSpeed +1F26 MCStopAt +2026 MCJog +2126 MCSearchTo +2226 MCSearchDone +2326 MCSearchWait +2426 MCGetPosition +2526 MCSetAudio +2626 MCGetTimes +2726 MCGetDiscTOC +2826 MCGetDiscID +2926 MCGetNoTracks +2A26 MCRecord +2B26 MCStop +2C26 MCWaitRawData +2D26 MCGetName +2E26 MCSetVolume +; === Marinetti === +0136 TCPIPBootInit +0236 TCPIPStartUp +0336 TCPIPShutDown +0436 TCPIPVersion +0536 TCPIPReset +0636 TCPIPStatus +0836 TCPIPLongVersion +0936 TCPIPGetConnectStatus +0A36 TCPIPGetErrorTable +0B36 TCPIPGetReconnectStatus +0C36 TCPIPReconnect +0D36 TCPIPConvertIPToHex +0E36 TCPIPConvertIPToASCII +0F36 TCPIPGetMyIPAddress +1036 TCPIPGetConnectMethod +1136 TCPIPSetConnectMethod +1236 TCPIPConnect +1336 TCPIPDisconnect +1436 TCPIPGetMTU +1536 TCPIPValidateIPCString +1636 TCPIPGetConnectData +1736 TCPIPSetConnectData +1836 TCPIPGetDisconnectData +1936 TCPIPSetDisconnectData +1A36 TCPIPLoadPreferences +1B36 TCPIPSavePreferences +1C36 TCPIPGetDNS +1D36 TCPIPSetDNS +1E36 TCPIPGetTuningTable +1F36 TCPIPSetTuningTable +2036 TCPIPCancelDNR +2136 TCPIPDNRNameToIP +2236 TCPIPPoll +2336 TCPIPLogin +2436 TCPIPLogout +2536 TCPIPSendICMP +2636 TCPIPSendUDP +2736 TCPIPGetDatagramCount +2836 TCPIPGetNextDatagram +2936 TCPIPGetLoginCount +2A36 TCPIPSendICMPEcho +2B36 TCPIPReceiveICMPEcho +2C36 TCPIPOpenTCP +2D36 TCPIPWriteTCP +2E36 TCPIPReadTCP +2F36 TCPIPCloseTCP +3036 TCPIPAbortTCP +3136 TCPIPStatusTCP +3236 TCPIPGetSourcePort +3336 TCPIPGetTOS +3436 TCPIPSetTOS +3536 TCPIPGetTTL +3636 TCPIPSetTTL +3736 TCPIPSetSourcePort +3836 TCPIPSetMyIPAddress +3936 TCPIPGetDP +3A36 TCPIPGetDebugHex +3B36 TCPIPDebugHex +3C36 TCPIPGetDebugTCP +3D36 TCPIPDebugTCP +3E36 TCPIPGetUserRecord +3F36 TCPIPConvertIPCToHex +4036 TCPIPSendIPDatagram +4136 TCPIPConvertIPToClass +4236 TCPIPGetConnectMsgFlag +4336 TCPIPSetConnectMsgFlag +4436 TCPIPGetUsername +4536 TCPIPSetUsername +4636 TCPIPGetPassword +4736 TCPIPSetPassword +4836 TCPIPValidateIPString +4936 TCPIPGetUserStatistic +4A36 TCPIPGetLinkVariables +4B36 TCPIPEditLinkConfig +4C36 TCPIPGetModuleNames +4D36 TCPIPRebuildModuleList +4E36 TCPIPListenTCP +4F36 TCPIPAcceptTCP +5036 TCPIPSetNewDestination +5136 TCPIPGetHostName +5236 TCPIPSetHostName +5336 TCPIPStatusUDP +5436 TCPIPGetLinkLayer +5536 TCPIPPtrToPtr +5636 TCPIPPtrToPtrNeg +5736 TCPIPGetAuthMessage +5836 TCPIPConvertIPToCASCII +5936 TCPIPMangleDomainName +5A36 TCPIPGetAliveFlag +5B36 TCPIPSetAliveFlag +5C36 TCPIPGetAliveMinutes +5D36 TCPIPSetAliveMinutes +5E36 TCPIPReadLineTCP +5F36 TCPIPGetBootConnectFlag +6036 TCPIPSetBootConnectFlag +6136 TCPIPSetUDPDispatch +6236 TCPIPGetDestination +6336 TCPIPGetUserEventTrigger +6436 TCPIPSetUserEventTrigger +6536 TCPIPGetSysEventTrigger +6636 TCPIPSetSysEventTrigger +6736 TCPIPGetDNRTimeouts +6836 TCPIPSetDNRTimeouts +; === Male Voice === +0132 MaleBootInit +0232 MaleStartUp +0332 MaleShutDown +0432 MaleVersion +0532 MaleReset +0632 MaleStatus +0932 MaleSpeak +; === Female Voice === +0133 FemaleBootInit +0233 FemaleStartUp +0333 FemaleShutDown +0433 FemaleVersion +0533 FemaleReset +0633 FemaleStatus +0933 FemaleSpeak +; === TML Speech Toolkit parser === +0134 SpeechBootInit +0234 SpeechStartUp +0334 SpeechShutDown +0434 SpeechVersion +0534 SpeechReset +0634 SpeechStatus +0934 Parse +0A34 DictInsert +0B34 DictDelete +0C34 DictDump +0D34 SetSayGlobals +0E34 DictInit +0F34 Say +1034 Activate... +; === GSBug === +04FF DebugVersion +06FF DebugStatus +09FF DebugStr +0AFF SetMileStone +0BFF DebugSetHook +0CFF DebugGetInfo +0DFF DebugControl +0EFF DebugQuery \ No newline at end of file diff --git a/src/assets/gsp_icon.icns b/src/assets/gsp_icon.icns new file mode 100644 index 0000000..c191909 Binary files /dev/null and b/src/assets/gsp_icon.icns differ diff --git a/src/gsp_icon.ico b/src/assets/gsp_icon.ico similarity index 100% rename from src/gsp_icon.ico rename to src/assets/gsp_icon.ico diff --git a/src/gsport32.ico b/src/assets/gsport32.ico similarity index 100% rename from src/gsport32.ico rename to src/assets/gsport32.ico diff --git a/src/win32.ico b/src/assets/win32.ico similarity index 100% rename from src/win32.ico rename to src/assets/win32.ico diff --git a/src/atbridge/CMakeLists.txt b/src/atbridge/CMakeLists.txt index 050752a..7bdcac3 100644 --- a/src/atbridge/CMakeLists.txt +++ b/src/atbridge/CMakeLists.txt @@ -3,3 +3,7 @@ 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/atbridge.vcxproj b/src/atbridge/atbridge.vcxproj deleted file mode 100644 index 8654124..0000000 --- a/src/atbridge/atbridge.vcxproj +++ /dev/null @@ -1,108 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - - - {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B} - Win32Proj - atbridge - - - - StaticLibrary - true - v120 - MultiByte - - - StaticLibrary - false - v120 - true - MultiByte - - - - - - - - - - - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - Default - false - - - Windows - true - - - %(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - Speed - StreamingSIMDExtensions2 - Default - - - Windows - true - true - true - - - %(AdditionalDependencies) - - - - - - diff --git a/src/atbridge/atbridge.vcxproj.filters b/src/atbridge/atbridge.vcxproj.filters deleted file mode 100644 index 3cbdd44..0000000 --- a/src/atbridge/atbridge.vcxproj.filters +++ /dev/null @@ -1,66 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - 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.c b/src/config.c index fd0f9e5..177e52f 100644 --- a/src/config.c +++ b/src/config.c @@ -7,26 +7,40 @@ #include "defc.h" #include +#include #include "config.h" #include "glog.h" #include "imagewriter.h" -#if defined(_MSC_VER) -#include "arch\win32\dirent-win32.h" -#else -#include -#endif -#ifdef HAVE_TFE -#include "tfe/tfesupp.h" -#include "tfe/protos_tfe.h" +#include + +#ifdef HAVE_RAWNET +#include "rawnet/rawnet.h" #endif #if defined _MSC_VER -#include -#define snprintf _snprintf + typedef unsigned int mode_t; + +#define strcasecmp stricmp +#define strncasecmp strnicmp + #endif + +#define KEY_DOWN_ARROW 0x0a +#define KEY_UP_ARROW 0x0b +#define KEY_RIGHT_ARROW 0x15 +#define KEY_LEFT_ARROW 0x08 +#define KEY_TAB 0x09 +#define KEY_RETURN 0x0d +#define KEY_PAGE_DOWN 0x1079 +#define KEY_PAGE_UP 0x1074 +#define KEY_ESC 0x1b +#define KEY_DELETE 0x7f + + + static const char parse_log_prefix_file[] = "Option set [file]:"; @@ -75,7 +89,8 @@ extern int g_joystick_button_0; extern int g_joystick_button_1; extern int g_joystick_button_2; extern int g_joystick_button_3; -extern int g_ethernet; + + extern int g_halt_on_bad_read; extern int g_ignore_bad_acc; extern int g_ignore_halts; @@ -100,7 +115,8 @@ extern int g_joystick_trim_amount_y; extern int g_swap_paddles; extern int g_invert_paddles; extern int g_ethernet; -extern int g_ethernet_interface; +extern int g_ethernet_enabled; +extern char * g_ethernet_interface; extern int g_appletalk_bridging; extern int g_appletalk_turbo; extern int g_appletalk_diagnostics; @@ -129,7 +145,7 @@ extern char* g_imagewriter_prop_font; extern int g_imagewriter_paper; extern int g_imagewriter_banner; -#if defined(_WIN32) && !defined(WIN_SDL) || defined(__CYGWIN__) && !defined(WIN_SDL) +#if defined(_WIN32) && !defined(HAVE_SDL) extern int g_win_show_console_request; extern int g_win_status_debug_request; #endif @@ -199,6 +215,8 @@ int g_cfg_file_dir_only = 0; #define MAX_PARTITION_BLK_SIZE 65536 +void display_rawnet_menu(const char *name, const char **value); + extern Cfg_menu g_cfg_main_menu[]; #define KNMP(a) &a, #a, 0 @@ -233,7 +251,6 @@ Cfg_menu g_cfg_uiless_menu[] = { { "", KNMP(g_joystick_button_1), CFGTYPE_INT }, { "", KNMP(g_joystick_button_2), CFGTYPE_INT }, { "", KNMP(g_joystick_button_3), CFGTYPE_INT }, - { "", KNMP(g_ethernet), CFGTYPE_INT }, { "", KNMP(g_halt_on_bad_read), CFGTYPE_INT }, { "", KNMP(g_ignore_bad_acc), CFGTYPE_INT }, { "", KNMP(g_ignore_halts), CFGTYPE_INT }, @@ -350,10 +367,11 @@ Cfg_menu g_cfg_parallel_menu[] = { { 0, 0, 0, 0, 0 }, }; +#ifdef HAVE_RAWNET Cfg_menu g_cfg_ethernet_menu[] = { { "Ethernet Card Configuration", g_cfg_ethernet_menu, 0, 0, CFGTYPE_MENU }, - { "Use Interface Number,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10", - KNMP(g_ethernet_interface), CFGTYPE_INT }, + { "Interface", + KNMP(g_ethernet_interface), CFGTYPE_STR_FUNC, display_rawnet_menu }, { "", 0, 0, 0, 0 }, { "Uthernet Card in Slot 3,0,Off,1,On", KNMP(g_ethernet), CFGTYPE_INT }, @@ -368,6 +386,8 @@ Cfg_menu g_cfg_ethernet_menu[] = { { "Back to Main Config", g_cfg_main_menu, 0, 0, CFGTYPE_MENU }, { 0, 0, 0, 0, 0 }, }; +#endif + #ifdef HAVE_SDL Cfg_menu g_cfg_printer_menu[] = { { "Virtual Epson Configuration", g_cfg_printer_menu, 0, 0, CFGTYPE_MENU }, @@ -428,7 +448,7 @@ Cfg_menu g_cfg_imagewriter_menu[] = { Cfg_menu g_cfg_devel_menu[] = { { "Developer Options", g_cfg_devel_menu, 0, 0, CFGTYPE_MENU }, -#if defined(_WIN32) && !defined(WIN_SDL) || defined(__CYGWIN__) && !defined(WIN_SDL) +#if defined(_WIN32) && !defined(HAVE_SDL) { "Status lines,0,Hide,1,Show", KNMP(g_win_status_debug_request), CFGTYPE_INT }, { "Console,0,Hide,1,Show", KNMP(g_win_show_console_request), CFGTYPE_INT }, #endif @@ -457,7 +477,9 @@ Cfg_menu g_cfg_main_menu[] = { { "ROM File Selection", g_cfg_rom_menu, 0, 0, CFGTYPE_MENU }, { "HOST FST Configuration", g_cfg_host_menu, 0, 0, CFGTYPE_MENU }, { "Serial Port Configuration", g_cfg_serial_menu, 0, 0, CFGTYPE_MENU }, +#ifdef HAVE_RAWNET { "Ethernet Card Configuration", g_cfg_ethernet_menu, 0, 0, CFGTYPE_MENU }, +#endif { "Parallel Card Configuration", g_cfg_parallel_menu, 0, 0, CFGTYPE_MENU }, #ifdef HAVE_SDL { "Virtual Epson Configuration", g_cfg_printer_menu, 0, 0, CFGTYPE_MENU }, @@ -469,15 +491,14 @@ Cfg_menu g_cfg_main_menu[] = { { "Expansion Mem Size,0,0MB,0x100000,1MB,0x200000,2MB,0x300000,3MB," "0x400000,4MB,0x600000,6MB,0x800000,8MB,0xa00000,10MB,0xc00000,12MB," "0xe00000,14MB", KNMP(g_mem_size_exp), CFGTYPE_INT }, - { "Dump text screen to file", (void *)cfg_text_screen_dump, 0, 0, CFGTYPE_FUNC}, + { "Dump text screen to file", 0, 0, 0, CFGTYPE_FUNC, cfg_text_screen_dump}, #ifdef HAVE_SDL - { "Reset Virtual ImageWriter", (void *)cfg_iwreset, 0, 0, CFGTYPE_FUNC }, + { "Reset Virtual ImageWriter", 0, 0, 0, CFGTYPE_FUNC, cfg_iwreset }, #endif { "", 0, 0, 0, 0 }, - { "Save changes to configuration file", (void *)config_write_config_gsplus_file, 0, 0, - CFGTYPE_FUNC }, + { "Save changes to configuration file", 0, 0, 0, CFGTYPE_FUNC, config_write_config_gsplus_file }, { "", 0, 0, 0, 0 }, - { "Exit Config (or press F4)", (void *)cfg_exit, 0, 0, CFGTYPE_FUNC }, + { "Exit Config (or press F4)", 0, 0, 0, CFGTYPE_FUNC, cfg_exit }, { 0, 0, 0, 0, 0 }, }; @@ -595,6 +616,7 @@ void config_init_menus(Cfg_menu *menuptr) { case CFGTYPE_STR: case CFGTYPE_FILE: case CFGTYPE_DIR: + case CFGTYPE_STR_FUNC: str_ptr = (char **)menuptr->ptr; str = *str_ptr; // We need to malloc this string since all @@ -695,36 +717,7 @@ void cfg_iwreset() { imagewriter_init(g_imagewriter_dpi,g_imagewriter_paper,g_imagewriter_banner, g_imagewriter_output,g_imagewriter_multipage); return; } -#ifdef HAVE_TFE -void cfg_get_tfe_name() { - int i = 0; - char *ppname = NULL; - char *ppdes = NULL; - cfg_htab_vtab(0,11); - if (tfe_enumadapter_open()) - { - cfg_printf("Interface List:\n---------------"); - while(tfe_enumadapter(&ppname,&ppdes)) - { - cfg_htab_vtab(0, 13+i); - cfg_printf("%2d: %s",i,ppdes); - i++; - lib_free(ppname); - lib_free(ppdes); - } - tfe_enumadapter_close(); - } - else - { - #if defined(_WIN32) || defined(__CYGWIN__) - cfg_printf("ERROR: Install/Enable WinPcap for Ethernet Support!!"); - #else - cfg_printf("ERROR: Install/Enable LibPcap for Ethernet Support!!"); - #endif - } - return; -} -#endif + void config_vbl_update(int doit_3_persec) { if(doit_3_persec) { @@ -810,6 +803,7 @@ void config_parse_option(char *buf, int pos, int len, int line) { case CFGTYPE_STR: case CFGTYPE_FILE: case CFGTYPE_DIR: + case CFGTYPE_STR_FUNC: strptr = (char **)menuptr->ptr; if(strptr && *strptr) { free(*strptr); @@ -1333,6 +1327,7 @@ void config_write_config_gsplus_file() { case CFGTYPE_STR: case CFGTYPE_FILE: case CFGTYPE_DIR: + case CFGTYPE_STR_FUNC: curstr = *((char **)menuptr->ptr); defstr = *((char **)menuptr->defptr); if(strcmp(curstr, defstr) != 0) { @@ -1421,7 +1416,7 @@ void insert_disk(int slot, int drive, const char *name, int ejected, int force_s name_len = strlen(name); name_ptr = (char *)malloc(name_len + 1); -#if defined(_WIN32) || defined(__CYGWIN__) +#if defined(_WIN32) // On Windows, we need to change backslashes to forward slashes. for (i = 0; i < name_len; i++) { if (name[i] == '\\') { @@ -2059,6 +2054,11 @@ void cfg_putchar(int c) { g_cfg_curs_x = x; } +void cfg_puts(const char *str, int nl) { + for(;*str; ++str) cfg_putchar(*str); + if (nl) cfg_putchar('\n'); +} + void cfg_printf(const char *fmt, ...) { va_list ap; int c; @@ -2260,6 +2260,7 @@ void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int chan case CFGTYPE_STR: case CFGTYPE_FILE: case CFGTYPE_DIR: + case CFGTYPE_STR_FUNC: str_ptr = (char **)menuptr->ptr; curstr = *str_ptr; str_ptr = (char **)menuptr->defptr; @@ -2292,6 +2293,7 @@ void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int chan case CFGTYPE_INT: case CFGTYPE_FILE: case CFGTYPE_DIR: + case CFGTYPE_STR_FUNC: g_cfg_opt_buf[bufpos++] = ' '; g_cfg_opt_buf[bufpos++] = '='; g_cfg_opt_buf[bufpos++] = ' '; @@ -2371,6 +2373,7 @@ void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int chan snprintf(str, CFG_OPT_MAXSTR, "%d", curval); break; case CFGTYPE_STR: + case CFGTYPE_STR_FUNC: str = &(g_cfg_opts_strs[0][0]); //printf("curstr is: %s str is: %s\n", curstr,str); snprintf(str, CFG_OPT_MAXSTR, "%s", curstr); @@ -3068,16 +3071,14 @@ void cfg_file_handle_key(int key) { listhdrptr = &g_cfg_partitionlist; } - // can't hotkey numbers because it falsely matches PGUP/PGDN - if( (g_cfg_file_pathfield == 0) && - ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z')) ) { + if( (g_cfg_file_pathfield == 0) && isalnum(key)) { /* jump to file starting with this letter */ g_cfg_file_match[0] = key; g_cfg_file_match[1] = 0; g_cfg_dirlist.invalid = 1; /* re-read directory */ } else { switch(key) { - case 0x1b: + case KEY_ESC: if(g_cfg_slotdrive < 0xfff) { eject_disk_by_num(g_cfg_slotdrive >> 8, g_cfg_slotdrive & 0xff); } @@ -3085,41 +3086,41 @@ void cfg_file_handle_key(int key) { g_cfg_select_partition = -1; g_cfg_dirlist.invalid = 1; break; - case 0x0a: /* down arrow */ + case KEY_DOWN_ARROW: /* down arrow */ if(g_cfg_file_pathfield == 0) { listhdrptr->curent++; cfg_fix_topent(listhdrptr); } break; - case 0x0b: /* up arrow */ + case KEY_UP_ARROW: /* up arrow */ if(g_cfg_file_pathfield == 0) { listhdrptr->curent--; cfg_fix_topent(listhdrptr); } break; - case 0x33: /* pg dn */ + case KEY_PAGE_DOWN: /* pg dn */ if(g_cfg_file_pathfield == 0) { listhdrptr->curent += CFG_PG_SCROLL_AMT; cfg_fix_topent(listhdrptr); } break; - case 0x39: /* pg up */ + case KEY_PAGE_UP: /* pg up */ if(g_cfg_file_pathfield == 0) { listhdrptr->curent -= CFG_PG_SCROLL_AMT; cfg_fix_topent(listhdrptr); } break; - case 0x0d: /* return */ + case KEY_RETURN: /* return */ cfg_file_selected(0); break; - case 0x09: /* tab */ + case KEY_TAB: /* tab */ g_cfg_file_pathfield = !g_cfg_file_pathfield; break; - case 0x15: + case KEY_RIGHT_ARROW: glogf("You can't go right!"); /* eggs - DB */ break; - case 0x08: /* left arrow */ - case 0x7f: /* delete key */ + case KEY_LEFT_ARROW: /* left arrow */ + case KEY_DELETE: /* delete key */ if(g_cfg_file_pathfield) { len = strlen(&g_cfg_file_curpath[0]) - 1; if(len >= 0) { @@ -3127,7 +3128,7 @@ void cfg_file_handle_key(int key) { } } break; - case 0x20: /* space -- selects file/directory */ + case ' ': /* space -- selects file/directory */ cfg_file_selected(g_cfg_file_dir_only); break; default: @@ -3136,18 +3137,57 @@ void cfg_file_handle_key(int key) { } } -void config_control_panel() { - void (*fn_ptr)(); + +static int config_read_key(void) { + int key = -1; + int mods; + while(g_config_control_panel & !(halt_sim&HALT_WANTTOQUIT)) { + video_update(); + key = adb_read_c000(); + if(key & 0x80) { + key = key & 0x7f; + mods = adb_read_c025(); + (void)adb_access_c010(); + //printf("key: %02x modifiers: %02x\n", key, mods); + // Fkeys have the keypad bit set (but so do numbers) */ + if ((mods & 0x10) && key > 0x3f) key |= 0x1000; + return key; + } + micro_sleep(1.0/60.0); + g_cfg_vbl_count++; + } + return -1; +} + +void config_display_file_menu(void) { + + int key; + cfg_file_init(); + while (g_cfg_slotdrive >= 0) { + cfg_file_draw(); + + cfg_htab_vtab(0, 23); + cfg_printf("Move: \tJ\t \tK\t Change: \tH\t \tU\t \tM"); + if (g_cfg_slotdrive < 0xfff) cfg_printf("\t Eject: \bESC\b"); + + key = config_read_key(); + if (key < 0) break; + cfg_file_handle_key(key); + } + +} + +void config_control_panel() { const char *str; Cfg_menu *menuptr; void *ptr; - int print_eject_help; + void *cookie; int line; int type; - int match_found; int menu_line; int menu_inc; int max_line; + int min_line; int key; int i, j; // First, save important text screen state @@ -3188,10 +3228,38 @@ void config_control_panel() { } cfg_home(); line = 1; - max_line = 1; - match_found = 0; - print_eject_help = 0; cfg_printf("%s\n\n", menuptr[0].str); + + /* calc max/min items */ + max_line = 0; + min_line = 0; + for (i = 0;;++i) { + const char *cp = menuptr[i].str; + if (!cp) break; + if (!*cp) continue; /* place holder */ + if (!min_line) min_line = i; + max_line = i; + } + + /* menu advancement */ + if (menu_inc > 0) { + if (menu_line > max_line) menu_line = max_line; + for( ; menu_line < max_line; ++menu_line) { + const char *cp = menuptr[menu_line].str; + if (*cp) break; + } + menu_inc = 0; + } + + if (menu_inc < 0) { + if (menu_line < min_line) menu_line = min_line; + for( ; menu_line > min_line; --menu_line) { + const char *cp = menuptr[menu_line].str; + if (*cp) break; + } + menu_inc = 0; + } + while(line < 24) { str = menuptr[line].str; type = menuptr[line].cfgtype; @@ -3199,44 +3267,22 @@ void config_control_panel() { if(str == 0) { break; } - if((type & 0xf) == CFGTYPE_DISK) { - print_eject_help = 1; - } + cfg_parse_menu(menuptr, line, menu_line, 0); - if(line == menu_line) { - if(type != 0) { - match_found = 1; - } else if(menu_inc) { - menu_line++; - } else { - menu_line--; - } - } - if(line > max_line) { - max_line = line; - } + cfg_printf("%s\n", g_cfg_opt_buf); line++; } - if((menu_line < 1) && !match_found) { - menu_line = 1; - } - if((menu_line >= max_line) && !match_found) { - menu_line = max_line; - } + if(g_rom_version < 0) { cfg_htab_vtab(0, 21); cfg_printf("\bYOU MUST SELECT A VALID ROM FILE\b\n"); } cfg_htab_vtab(0, 23); - cfg_printf("Move: \tJ\t \tK\t Change: \tH\t \tU\t \tM\t"); - if(print_eject_help) { - cfg_printf(" Eject: "); - if(g_cfg_slotdrive >= 0) { - cfg_printf("\bESC\b"); - } else { - cfg_printf("E"); - } + cfg_printf("Move: \tJ\t \tK\t Change: \tH\t \tU\t \tM"); + type = menuptr[menu_line].cfgtype; + if ((type & 0x0f) == CFGTYPE_DISK) { + cfg_printf("\t Eject: E"); } #if 0 cfg_htab_vtab(0, 22); @@ -3244,126 +3290,111 @@ void config_control_panel() { menu_line, line, g_cfg_vbl_count, g_adb_repeat_vbl, g_key_down); #endif - if(g_cfg_slotdrive >= 0) { - cfg_file_draw(); - } -#ifdef HAVE_TFE - /*HACK eh, at least I think it is. Display the available ethernet interfaces - when in the ethernet control panel. This is the only way one can customize a menu pane. - Kent did it with the directory browser, so why not.*/ - if(menuptr == g_cfg_ethernet_menu) - { - cfg_get_tfe_name(); - } + +#ifdef HAVE_RAWNET + #endif + + + + key = config_read_key(); + if (key < 0) break; + + // Normal menu system + switch(key) { + case KEY_DOWN_ARROW: /* down arrow */ + if (menu_line < max_line) menu_line++; + menu_inc = 1; + break; + case KEY_UP_ARROW: /* up arrow */ + if (menu_line > 1) --menu_line; + menu_inc = -1; + break; + case KEY_PAGE_DOWN: /* pg dn */ + menu_line += CFG_PG_SCROLL_AMT; + menu_inc = 1; + break; + case KEY_PAGE_UP: /* pg up */ + menu_line -= CFG_PG_SCROLL_AMT; + menu_inc = -1; + break; + case KEY_RIGHT_ARROW: /* right arrow */ + cfg_parse_menu(menuptr, menu_line,menu_line,1); + break; + case KEY_LEFT_ARROW: /* left arrow */ + cfg_parse_menu(menuptr,menu_line,menu_line,-1); + break; + case KEY_RETURN: + type = menuptr[menu_line].cfgtype; + ptr = menuptr[menu_line].ptr; + str = menuptr[menu_line].str; + cookie = menuptr[menu_line].cookie; + switch(type & 0xf) { + case CFGTYPE_MENU: + menuptr = (Cfg_menu *)ptr; + menu_line = 1; + #ifdef HAVE_SDL - /*If user enters the Virtual Imagewriter control panel, flag it so we can - automatically apply changes on exit.*/ - if(menuptr == g_cfg_imagewriter_menu) - { - g_cfg_triggeriwreset = 1; - } + /*If user enters the Virtual Imagewriter control panel, flag it so we can + automatically apply changes on exit.*/ + if(menuptr == g_cfg_imagewriter_menu) { + g_cfg_triggeriwreset = 1; + } #endif - key = -1; - while(g_config_control_panel & !(halt_sim&HALT_WANTTOQUIT)) { - video_update(); - key = adb_read_c000(); - if(key & 0x80) { - key = key & 0x7f; - (void)adb_access_c010(); + break; + + case CFGTYPE_FUNC: { + void (*fn)(void); + fn = (void (*)(void))cookie; + if (fn) fn(); + adb_all_keys_up(); //Needed otherwise menu function will continue to repeat until we move selection up or down + break; + } + + case CFGTYPE_DISK: + g_cfg_slotdrive = type >> 4; + g_cfg_file_dir_only = 0; + config_display_file_menu(); + break; + case CFGTYPE_FILE: + g_cfg_slotdrive = 0xfff; + g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr + g_cfg_file_strptr = (char **)ptr; + g_cfg_file_dir_only = 0; + config_display_file_menu(); + break; + case CFGTYPE_DIR: + g_cfg_slotdrive = 0xfff; + g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr + g_cfg_file_strptr = (char **)ptr; + g_cfg_file_dir_only = 1; + config_display_file_menu(); + break; + + case CFGTYPE_STR_FUNC: { + void (*fn)(const char *, char **); + fn = (void (*)(const char *, char **))cookie; + if (fn) fn(str, (char **)ptr); + adb_all_keys_up(); + break; + } + + } break; - } else { - key = -1; - } - micro_sleep(1.0/60.0); - g_cfg_vbl_count++; - if(!match_found) { + case KEY_ESC: + // Jump to last menu entry + menu_line = max_line; break; - } - } - if((key >= 0) && (g_cfg_slotdrive < 0)) { - // Normal menu system - switch(key) { - case 0x0a: /* down arrow */ - menu_line++; - menu_inc = 1; - break; - case 0x0b: /* up arrow */ - menu_line--; - menu_inc = 0; - if(menu_line < 1) { - menu_line = 1; - } - break; - case 0x33: /* pg dn */ - menu_line += CFG_PG_SCROLL_AMT; - menu_inc = 1; - break; - case 0x39: /* pg up */ - menu_line -= CFG_PG_SCROLL_AMT; - menu_inc = 0; - if(menu_line < 1) { - menu_line = 1; - } - break; - case 0x15: /* right arrow */ - cfg_parse_menu(menuptr, menu_line,menu_line,1); - break; - case 0x08: /* left arrow */ - cfg_parse_menu(menuptr,menu_line,menu_line,-1); - break; - case 0x0d: - type = menuptr[menu_line].cfgtype; - ptr = menuptr[menu_line].ptr; - str = menuptr[menu_line].str; - switch(type & 0xf) { - case CFGTYPE_MENU: - menuptr = (Cfg_menu *)ptr; - menu_line = 1; - break; - case CFGTYPE_DISK: - g_cfg_slotdrive = type >> 4; - g_cfg_file_dir_only = 0; - cfg_file_init(); - break; - case CFGTYPE_FUNC: - fn_ptr = (void (*)())ptr; - (*fn_ptr)(); - adb_all_keys_up(); //Needed otherwise menu function will continue to repeat until we move selection up or down - break; - case CFGTYPE_FILE: - g_cfg_slotdrive = 0xfff; - g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr - g_cfg_file_strptr = (char **)ptr; - g_cfg_file_dir_only = 0; - cfg_file_init(); - break; - case CFGTYPE_DIR: - g_cfg_slotdrive = 0xfff; - g_cfg_file_def_name = str /* *((char **)ptr) */; // was ptr - g_cfg_file_strptr = (char **)ptr; - g_cfg_file_dir_only = 1; - cfg_file_init(); - break; - } - break; - case 0x1b: - // Jump to last menu entry - menu_line = max_line; - break; - case 'e': - case 'E': - type = menuptr[menu_line].cfgtype; - if((type & 0xf) == CFGTYPE_DISK) { - eject_disk_by_num(type >> 12, - (type >> 4) & 0xff); - } - break; - default: - glogf("Unhandled config key: 0x%02x", key); - } - } else if(key >= 0) { - cfg_file_handle_key(key); + case 'e': + case 'E': + type = menuptr[menu_line].cfgtype; + if((type & 0xf) == CFGTYPE_DISK) { + eject_disk_by_num(type >> 12, + (type >> 4) & 0xff); + } + break; + default: + glogf("Unhandled config key: 0x%02x", key); } } for(i = 0; i < 0x400; i++) { @@ -3391,3 +3422,113 @@ void x_clk_setup_bram_version() { g_bram_ptr = (&g_bram[1][0]); // ROM 03 } } + + +#ifdef HAVE_RAWNET + +void display_rawnet_menu(const char *name, const char **value) { + + char *entries[20]; + int i; + int index = -1; + int count = 0; + char *ppname = NULL; + char *ppdes = NULL; + + memset(entries, 0, sizeof(entries)); + + if (rawnet_enumadapter_open()) { + count = 0; + while(rawnet_enumadapter(&ppname,&ppdes)) { + entries[count] = ppname; + free(ppdes); + + if (index < 0 && !strcmp(*value, ppname)) index = count; + ++count; + if (count == 20) break; + } + rawnet_enumadapter_close(); + } + + if (index < 0) index = 0; + + for(;;) { + int key; + + cfg_home(); + cfg_puts(name, 1); + for (i = 0; i < 20; ++i) { + char *cp = entries[i]; + if (!cp) break; + + cfg_htab_vtab(4, i + 2); + if (i == index) cfg_putchar('\b'); /* inverse */ + cfg_puts(cp, 1); + if (i == index) cfg_putchar('\b'); + } + + cfg_htab_vtab(0, 23); + cfg_puts("Move: \tJ\t \tK\t Change: \tM",1); + + key = config_read_key(); + switch(key) { + case KEY_UP_ARROW: + if (index) --index; + break; + case KEY_DOWN_ARROW: + if (index < count - 1) ++index; + break; + case KEY_PAGE_UP: + index -= CFG_PG_SCROLL_AMT; + if (index < 0) index = 0; + break; + case KEY_PAGE_DOWN: + index += CFG_PG_SCROLL_AMT; + if (index >= count) index = count - 1; + break; + case KEY_RETURN: + if (index < count) { + *value = strdup(entries[index]); + } + key = -1; + break; + case KEY_ESC: + key = -1; + break; + } + if (key < 0) break; + } + + for (i = 0; i < 20; ++i) free(entries[i]); +} + + +void cfg_get_tfe_name() { + int i = 0; + char *ppname = NULL; + char *ppdes = NULL; + cfg_htab_vtab(0,11); + if (rawnet_enumadapter_open()) + { + cfg_printf("Interface List:\n---------------"); + while(rawnet_enumadapter(&ppname,&ppdes)) + { + cfg_htab_vtab(0, 13+i); + cfg_printf("%2d: %s",i,ppdes); + i++; + free(ppname); + free(ppdes); + } + rawnet_enumadapter_close(); + } + else + { +#if defined(_WIN32) + cfg_printf("ERROR: Install/Enable WinPcap for Ethernet Support!!"); +#else + cfg_printf("ERROR: Install/Enable LibPcap for Ethernet Support!!"); +#endif + } + return; +} +#endif diff --git a/src/config.h b/src/config.h index 779fff7..f03c5ef 100644 --- a/src/config.h +++ b/src/config.h @@ -12,12 +12,13 @@ #define CFG_NUM_SHOWENTS 16 #define CFGTYPE_MENU 1 -#define CFGTYPE_INT 2 +#define CFGTYPE_INT 2 #define CFGTYPE_DISK 3 #define CFGTYPE_FUNC 4 #define CFGTYPE_FILE 5 #define CFGTYPE_STR 6 #define CFGTYPE_DIR 7 +#define CFGTYPE_STR_FUNC 8 /* CFGTYPE limited to just 4 bits: 0-15 */ /* Cfg_menu, Cfg_dirent and Cfg_listhdr are defined in defc.h */ diff --git a/src/debug.c b/src/debug.c index 49c3021..cb59451 100644 --- a/src/debug.c +++ b/src/debug.c @@ -20,24 +20,18 @@ #include "glog.h" // DISASSEMBLER STUFF -enum { - ABS = 1, ABSX, ABSY, ABSLONG, ABSIND, ABSXIND, IMPLY, ACCUM, IMMED, JUST8, - DLOC, DLOCX, DLOCY, LONG, LONGX, DLOCIND, DLOCINDY, DLOCXIND, DLOCBRAK, - DLOCBRAKY, DISP8, DISP8S, DISP8SINDY, DISP16, MVPMVN, REPVAL, SEPVAL -}; -extern const char * const disas_opcodes[256]; -extern const word32 disas_types[256]; +#include "disasm.h" // STEPPING/ENGINE STUFF extern Engine_reg engine; extern int g_config_control_panel; -extern int g_num_breakpoints; -extern word32 g_breakpts[MAX_BREAK_POINTS]; int g_dbg_enable_port = 0; int debug_pause = 0; int g_dbg_step = 0; int step_count = 0; +extern int g_stepping; + // emulator command stuff extern int g_limit_speed; extern int g_screenshot_requested; @@ -223,9 +217,11 @@ void debug_handle_event() { } else { g_dbg_step = -1; // first one just halts } + g_stepping = 1; break; case G_DBG_COMMAND_CONTINUE: //4 g_dbg_step = 0; + g_stepping = 0; step_count = 0; break; case G_DBG_COMMAND_GET_MEM: //6 @@ -238,7 +234,7 @@ void debug_handle_event() { exit(0); // HALT! break; case G_DBG_COMMAND_DEBUGGER: - do_debug_intfc(); + //do_debug_intfc(); break; case G_DBG_COMMAND_SET_CPU: event_set_cpu(&dbg_cmd_queue[0].cdata); @@ -278,7 +274,7 @@ void push_api_msg(int size, char *msg_str) { void api_push_memack() { int size = snprintf(tmp_buffer_4k, sizeof(tmp_buffer_4k),"{\"type\":\"memack\"}"); - char *msg = (char*)malloc(sizeof(char) * size); + char *msg = (char*)malloc(sizeof(char) * size + 1); strcpy(msg,tmp_buffer_4k); push_api_msg(size, msg); } @@ -309,13 +305,16 @@ void api_push_cpu() { void api_push_brk() { int i; + extern int g_num_bp_breakpoints; + extern word32 g_bp_breakpoints[]; + // build our json array of breakpoints tmp_buffer2_4k[0] = '\0'; // start with empty string char *str_ptr = tmp_buffer2_4k; - for(i = 0; i < g_num_breakpoints; i++) { + for(i = 0; i < g_num_bp_breakpoints; i++) { //printf("{\"bp:%02x: %06x\n", i, g_breakpts[i]); - str_ptr += sprintf(str_ptr, "{\"trig\":\"addr\",\"match\":\"%06X\"}", g_breakpts[i]); - if (i < g_num_breakpoints-1) { + str_ptr += sprintf(str_ptr, "{\"trig\":\"addr\",\"match\":\"%06X\"}", g_bp_breakpoints[i]); + if (i < g_num_bp_breakpoints-1) { str_ptr += sprintf(str_ptr, ","); } } @@ -352,7 +351,7 @@ void api_push_stack() { int size = snprintf(tmp_buffer_4k, sizeof(tmp_buffer_4k),"{\"type\":\"stack\",\"data\":{\"loc\":\"%06X\",\"S\":\"%04X\",\"bytes\":[%s]}}", stack_loc,stack,str_ptr); - char *msg = (char*)malloc(sizeof(char) * size); + char *msg = (char*)malloc(sizeof(char) * size + 1); strcpy(msg,tmp_buffer_4k); push_api_msg(size, msg); } @@ -360,7 +359,7 @@ void api_push_stack() { void api_push_disassembly_start() { int size = snprintf(tmp_buffer_4k, sizeof(tmp_buffer_4k),"{\"type\":\"dis0\"}"); - char *msg = (char*)malloc(sizeof(char) * size); + char *msg = (char*)malloc(sizeof(char) * size + 1); strcpy(msg,tmp_buffer_4k); push_api_msg(size, msg); } @@ -609,7 +608,7 @@ void event_add_brk(char *str) { int addr = 0; sscanf(str, "%06X", &addr); addr = addr & 0xFFFFFF; // 24 bit KPC address for 65816 - set_bp(addr); + set_bp('B', addr); api_push_brk(); api_write_socket(); @@ -621,7 +620,7 @@ void event_del_brk(char *str) { int addr = 0; sscanf(str, "%06X", &addr); addr = addr & 0xFFFFFF; // 24 bit KPC address for 65816 - delete_bp(addr); + delete_bp('B', addr); api_push_brk(); api_write_socket(); @@ -1217,8 +1216,8 @@ int do_dis_json(char *buf, word32 kpc, int accsize, int xsize, int op_provided, kpc++; - dtype = disas_types[opcode]; - out = disas_opcodes[opcode]; + dtype = disasm_types[opcode]; + out = disasm_opcodes[opcode]; type = dtype & 0xff; args = dtype >> 8; @@ -1292,6 +1291,12 @@ int do_dis_json(char *buf, word32 kpc, int accsize, int xsize, int op_provided, } sprintf(buf_disasm,"%s $%06x",out,val); break; + case ABSLONGX: + if(args != 3) { + printf("arg # mismatch for opcode %x\n", opcode); + } + sprintf(buf_disasm,"%s $%06x,X",out,val); + break; case ABSIND: if(args != 2) { printf("arg # mismatch for opcode %x\n", opcode); @@ -1349,18 +1354,6 @@ int do_dis_json(char *buf, word32 kpc, int accsize, int xsize, int op_provided, } sprintf(buf_disasm,"%s $%02x,Y",out,val); break; - case LONG: - if(args != 3) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%06x",out,val); - break; - case LONGX: - if(args != 3) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buf_disasm,"%s $%06x,X",out,val); - break; case DLOCIND: if(args != 1) { printf("arg # mismatch for opcode %x\n", opcode); diff --git a/src/debug_shell.re2c b/src/debug_shell.re2c new file mode 100644 index 0000000..ca5e096 --- /dev/null +++ b/src/debug_shell.re2c @@ -0,0 +1,1891 @@ + +/* + * requires re2c (http://re2c.org) + * + */ + +#include +#include +#include +#include + +#include +#include + +#include "defc.h" +#include "disasm.h" + + +extern char *x_readline(const char *prompt); + +extern int g_fullscreen; +extern int g_config_control_panel; +extern Engine_reg engine; +extern int halt_sim; + + +int g_num_mp_breakpoints = 0; +word32 g_mp_breakpoints[MAX_BREAK_POINTS]; + +int g_num_bp_breakpoints = 0; +word32 g_bp_breakpoints[MAX_BREAK_POINTS]; + +int g_num_tp_breakpoints = 0; +word32 g_tp_breakpoints[MAX_BREAK_POINTS]; + +int g_dbg_shell = 0; +int g_stepping = 0; + +word32 g_abort_address = 0; +word32 g_abort_value = 0; +word32 g_abort_bytes = 0; + + +static word32 g_prev_address = 0; +static word32 g_prev_stack_address = 0; +static word32 g_prev_stack_bank = 0; + + +static int g_templates_loaded = 0; +extern void debug_load_templates(const char *path); +extern word32 debug_apply_template(word32 address, const char *name); +extern void debug_load_nifty(const char *path); +extern const char *debug_tool_name(unsigned, unsigned vector); + + + +#if defined(__APPLE__) +#include +static char *get_resource_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 + sizeof("Resources/"); + buffer = malloc(size); + if (!buffer) return NULL; + + /* + * expect .../GSPlus.app/Contents/MacOS/GSPlus + * drop + */ + ok = _NSGetExecutablePath(buffer, &size); + if (ok < 0) { + free(buffer); + return NULL; + } + cp = strrchr(buffer, '/'); + if (!cp) { free(buffer); return NULL; } + *cp = 0; + cp = strrchr(buffer, '/'); + if (!cp) { free(buffer); return NULL; } + + strcpy(cp + 1, "Resources/"); + strcat(cp, leaf); + + return buffer; +} +#elif defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include +/* todo -- something clever like find the home directory */ +static char *get_resource_path(const char *leaf) { + DWORD size; + char *buffer = 0; + char *cp; + int l; + + l = strlen(leaf); + + size = GetModuleFileName(NULL, buffer, 0); + if (size == 0) return strdup(leaf); + + size += l + 2; + buffer = malloc(size); + if (!buffer) return NULL; + + size = GetModuleFileName(NULL, buffer, size); + if (!size) return strdup(leaf); + + cp = strrchr(buffer, '\\'); + strcpy(cp + 1, leaf); + return buffer; +} +#else +static char *get_resource_path(const char *leaf) { + int l; + char *cp; + static char path[] = "/usr/local/share/gsplus/"; + l = strlen(leaf); + cp = malloc(l + sizeof(path) + 1); + if (!cp) return NULL; + strcpy(cp, path); + strcat(cp, leaf); + return cp; +} +#endif + +void clear_line(void) { + /* carriage return, clear_eol */ + /* cr, ce */ + fputs("\r\x1b[K", stdout); +} + +void clear_prev_line(void) { + /* carriage return, cursor_up, clear_eol */ + /* cr, up, ce */ + fputs("\r\x1b[A\x1b[K", stdout); + +} + + +/* + * todo + * - tool break support + * - gs/os break support + * - p8 break support + * - r -> run to next rts/rtl + * - ! -> mini assembler + */ + + + +static void do_handle(word32 value, int action) { + /* action = I)nfo, W)who, H)handle */ + + enum { + MemList = 0xe11600, + PurgeList = 0xe11604, + FreeList = 0xe11608 + }; + + enum { + offset_address = 0, + offset_attr = 4, + offset_owner = 6, + offset_size = 8, + offset_prev = 12, + offset_next = 16 + }; + + unsigned mask = 0; + unsigned count = 0; + + /* return information on who owns an address. */ + /* Nifty list can get info from the GS/OS... we can't */ + + fputs("handle addr size flgs ownr\n", stdout); + fputs("------ ------ ------ ---- ----\n", stdout); + + + if (action == 'i') { + value &= 0xffff; + mask = 0x0000; + if (value & 0xf000) mask |= 0xf000; + if (value & 0x0f00) mask |= 0x0f00; + if (value & 0x00f0) mask |= 0x00f0; + if (value & 0x000f) mask |= 0x000f; + } + + for (unsigned i = 0; i < 2; ++i) { + + word32 handle; + handle = get_memory24_c(i == 0 ? MemList : PurgeList, 0); + + for(; handle ; handle = get_memory24_c(handle + offset_next, 0)) { + + word32 address = get_memory32_c(handle + offset_address, 0); + word32 size = get_memory24_c(handle + offset_size, 0); + unsigned owner = get_memory16_c(handle + offset_owner, 0); + unsigned attr = get_memory16_c(handle + offset_attr, 0); + + /* size not 32-bit clean. may be $ffxxxxxx */ + + if (action == 'w') { + if (value < address || value >= address + size) continue; + } + + if (action == 'i') { + if ((owner & mask) != value) continue; + } + + if (action == 'h') { + if (value != handle) continue; + } + + fprintf(stdout, "%06x %06x %06x %04x %04x\n", + handle, address, size, attr, owner + ); + ++count; + if (action == 'w' || action == 'h') break; + } + + if (action == 'w') break; + if (action == 'h' && handle) break; + } + + + if (action == 'w' && !count) { + fputs("not allocated\n", stderr); + } + if (action == 'h' && !count) { + fputs("not handle\n", stderr); + } + +} + + +word32 do_hexdump(word32 address, int lines) { + static char hex[] = "0123456789abcdef"; + + char buffer1[64]; + char buffer2[20]; + int i; + + while (--lines) { + char *cp = buffer1; + for (i = 0; i < 16; ++i) { + uint8_t c = get_memory_c(address + i, 0); + *cp++ = hex[c >> 4]; + *cp++ = hex[c & 0x0f]; + *cp++ = ' '; + if (i == 7) *cp++ = ' '; + + buffer2[i] = (c < 0x80) && isprint(c) ? c : '.'; + } + *cp = 0; + buffer2[16] = 0; + printf("%02x/%04x: %s %s\n", + address >> 16, address & 0xffff, + buffer1, buffer2 + ); + address += 16; + address &= 0xffffff; + } + + return address; +} + +static int check_stack_rts(word32 address, unsigned bank, char *buffer) { + word32 rt; + unsigned op; + + rt = get_memory24_c(address, 0); + if (rt == 0) return 0; + + rt = (rt & 0xff0000) | ((rt - 3) & 0xffff); + op = get_memory_c(rt, 0); + if (op == 0x22) { + word32 tmp = get_memory24_c(rt + 1, 0); /* crosses bank :/ */ + /* todo -- check if tmp is known address, include below */ + /* todo -- if jsl e10000, check for prev. ldx # */ + sprintf(buffer, "%02x/%04x: JSL %06x", + rt >> 16, rt & 0xffff, tmp); + return 3; + } + /* sigh... this might re-check 0000 a lot */ + rt = get_memory16_c(address, 0); + rt = bank | ((rt - 2) & 0xffff); + + op = get_memory_c(rt, 0); + if (op == 0x20 || op == 0xfc) { + word32 tmp = get_memory16_c(rt + 1, 0); + if (op == 0x20) { + sprintf(buffer, "%02x/%04x: JSR %04x", + rt >> 16, rt & 0xffff, tmp); + } + if (op == 0xfc) { + sprintf(buffer, "%02x/%04x: JSR (%04x,x)", + rt >> 16, rt & 0xffff, tmp); + } + + return 2; + } + + + return 0; +} + +word32 do_stack(word32 address, unsigned bank) { + + /* scan through stack. + * if address looks like jsr return address + * or jsl return address, print it. + * otherwise, hexdump it. + * + * jsr absolute = 0x20 + * jsr (absolute,x) = 0xfc + * jsl abslong = 0x22 + * + * + * TODO - in Niftylist, JSL updates the bank. + * TODO - don't display c000, etc. + */ + + static char hex[] = "0123456789abcdef"; + + char buffer1[64]; + char buffer2[64]; + + unsigned offset = 0; + unsigned line = 0; + char *cp = buffer1; + + ++address; + + while(line < 20) { + unsigned c; + int tmp = check_stack_rts(address + offset, bank, buffer2); + if (tmp) { + /* flush any pending data */ + + if (offset) { + *cp = 0; + printf("%02x/%04x: %s\n", + address >> 16, address & 0xffff, buffer1); + ++line; + address += offset; + offset = 0; + cp = buffer1; + } + + for (offset = 0; offset < tmp; ++offset) { + c = get_memory_c(address + offset, 0); + *cp++ = hex[c >> 4]; + *cp++ = hex[c & 0x0f]; + *cp++ = ' '; + } + + *cp = 0; + printf("%02x/%04x: %-12s%s\n", + address >> 16, address & 0xffff, buffer1, buffer2); + ++line; + address += offset; + offset = 0; + cp = buffer1; + continue; + } + + c = get_memory_c(address + offset, 0); + *cp++ = hex[c >> 4]; + *cp++ = hex[c & 0x0f]; + *cp++ = ' '; + + if (offset == 7) *cp++ = ' '; + ++offset; + + if (offset == 16) { + *cp = 0; + printf("%02x/%04x: %s\n", + address >> 16, address & 0xffff, buffer1); + ++line; + address += offset; + offset = 0; + cp = buffer1; + } + } + + return address; + +} + + +static int is_jsl_e10000(word32 address) { + return get_memory_c(address, 0) == 0x22 && + get_memory24_c(address + 1, 0) == 0xe10000; +} + +static int is_jsl_e10008(word32 address) { + return get_memory_c(address, 0) == 0x22 && + get_memory24_c(address + 1, 0) == 0xe10008; +} +static int is_jsl_e100a8(word32 address) { + return get_memory_c(address, 0) == 0x22 && + get_memory24_c(address + 1, 0) == 0xe100a8; +} + + +static int is_jsl_e100b0(word32 address) { + return get_memory_c(address, 0) == 0x22 && + get_memory24_c(address + 1, 0) == 0xe100b0; +} + +static int is_jsr_bf00(word32 address) { + return get_memory_c(address, 0) == 0x20 && + get_memory16_c(address + 1, 0) == 0xbf00; +} + +static int g_disasm_psr; + +static const char *get_inline_debug_name(word32 address) { + static char buffer[256]; + + /* see IIgs technote #103 */ + /* 82 xx xx brl pastname + 71 77 + name + pastname: + */ + + /* uthernet uses bra ... tsk tsk. */ + + int match = 0; + int offset = 0; + + unsigned op = get_memory_c(address, 0); + if (op == 0x82 + && get_memory_c(address + 3, 0) == 0x71 + && get_memory_c(address + 4, 0) == 0x77) { + match = 1; + address += 5; + + offset = (int16_t)get_memory16_c(address + 1, 0); + } + + if (op == 0x80 + && get_memory_c(address + 2, 0) == 0x71 + && get_memory_c(address + 3, 0) == 0x77) { + match = 1; + address += 4; + + offset = (int8_t)get_memory_c(address + 1, 0); + } + + + if (match) { + unsigned i, n; + + /* sanity check offset? should be positive. */ + + n = get_memory_c(address++, 0); + for (i = 0; i < n; ++i) { + unsigned char c = get_memory_c(address++, 0); + if (c & 0x80) return NULL; + if (!isprint(c)) return NULL; + buffer[i] = c; + } + buffer[i] = 0; + return buffer; + } + + return NULL; +} + +word32 do_list(word32 address, int lines) { + + unsigned char buffer2[32]; + char buffer[32]; + + const char *opcode_string; + const char *comment; + + unsigned opcode; + unsigned dtype; + unsigned operand; + + word32 pc; + int i; + int args; + int n; + + while (lines--) { + + int bsize = 0; + unsigned bank; + pc = address; + + opcode = get_memory_c(address++, 0); + dtype = disasm_types[opcode]; + args = dtype >> 8; + + buffer2[bsize++] = opcode; + opcode_string = disasm_opcodes[opcode]; + comment = NULL; + + switch (args) { + case 4: + args = g_disasm_psr & 0x20 ? 1 : 2; + break; + case 5: + args = g_disasm_psr & 0x10 ? 1 : 2; + break; + } + operand = 0; + switch(args) { + case 1: + operand = get_memory_c(address, 0); + buffer2[bsize++] = operand; + break; + case 2: + operand = get_memory16_c(address, 0); + buffer2[bsize++] = operand; + buffer2[bsize++] = operand >> 8; + break; + case 3: + operand = get_memory24_c(address, 0); + buffer2[bsize++] = operand; + buffer2[bsize++] = operand >> 8; + buffer2[bsize++] = operand >> 16; + break; + } + address += args; + buffer[0] = 0; + + switch(dtype & 0xff) { + case ABS: + sprintf(buffer, "$%04x", operand); + break; + case ABSX: + sprintf(buffer, "$%04x,x", operand); + break; + case ABSY: + sprintf(buffer, "$%04x,y", operand); + break; + + case ABSIND: + sprintf(buffer,"($%04x)",operand ); + break; + case ABSXIND: + sprintf(buffer,"($%04x,x)",operand ); + break; + case IMPLY: + break; + case ACCUM: + break; + case IMMED: + sprintf(buffer,"#$%0*x",args * 2, operand); + break; + case JUST8: + sprintf(buffer,"$%02x",operand); + break; + case DLOC: + sprintf(buffer,"$%02x",operand); + break; + case DLOCX: + sprintf(buffer,"$%02x,x",operand); + break; + case DLOCY: + sprintf(buffer,"$%02x,y",operand); + break; + case ABSLONG: + sprintf(buffer,"$%06x",operand); + bank = operand >> 16; + if (bank == 0xe0 || bank == 0xe1 || bank == 0x01 || bank == 0xff) + comment = debug_tool_name(operand & 0xffff, bank); + break; + case ABSLONGX: + sprintf(buffer,"$%06x,x",operand); + bank = operand >> 16; + if (bank == 0xe0 || bank == 0xe1 || bank == 0x01 || bank == 0xff) + comment = debug_tool_name(operand & 0xffff, bank); + break; + case DLOCIND: + sprintf(buffer,"($%02x)",operand); + break; + case DLOCINDY: + sprintf(buffer,"($%02x),y",operand); + break; + case DLOCXIND: + sprintf(buffer,"($%02x,x)",operand); + break; + case DLOCBRAK: + sprintf(buffer,"[$%02x]",operand); + break; + case DLOCBRAKY: + sprintf(buffer,"[$%02x],y",operand); + break; + case DISP8: + sprintf(buffer,"$%04x", + (address+(int8_t)operand) & 0xffff); + break; + case DISP8S: + sprintf(buffer,"$%02x,s",operand); + break; + case DISP8SINDY: + sprintf(buffer,"($%02x,s),y",operand); + break; + case DISP16: + sprintf(buffer,"$%04x", + (address+(int16_t)(operand)) & 0xffff); + break; + case MVPMVN: + sprintf(buffer,"$%02x,$%02x",operand >> 8, operand & 0xff); + break; + case SEPVAL: + case REPVAL: + sprintf(buffer,"#$%02x",operand); + break; + } + + if (!comment) { + bank = pc >> 16; + if (bank == 0xe0 || bank == 0xe1 || bank == 0x01 || bank == 0xff) + comment = debug_tool_name(pc & 0xffff, bank); + } + + uint32_t ea = 0; + switch (opcode) { + case 0xe2: /* sep */ + g_disasm_psr|= operand; + break; + case 0xc2: /* rep */ + g_disasm_psr &= ~operand; + break; + case 0xfb: /* xce */ + g_disasm_psr |= 0x0130; + break; + case 0xa2: /* ldx # */ + if (is_jsl_e10000(address)) { + /* tool call ... */ + const char *name = debug_tool_name(operand, 0xe10000); + if (name) { + opcode_string = name; + buffer[0] = 0; + for (i = 0; i < 4; ++i) { + buffer2[bsize++] = get_memory_c(address++, 0); + } + } + } + break; +#if 0 + case 0xae: /* ldx ... */ + case 0xbe: + case 0xa6: + case 0xb6: + case 0xfa: /* plx */ + case 0xaa: /* tax */ + case 0xba: /* tsx */ + case 0xbb: /* tyx */ + case 0xca: /* dex */ + case 0xe8: /* inx */ + break; +#endif + case 0x22: /* jsl */ + if (operand == 0xe100a8) { + /* inline GS/OS call? */ + unsigned num = get_memory16_c(address, 0); + const char *name = debug_tool_name(num, operand); + if (name) { + comment = NULL; + opcode_string = name; + unsigned parms = get_memory24_c(address + 2, 0); + sprintf(buffer, "$%06x", parms); + + for (i = 0; i < 6; ++i) { + buffer2[bsize++] = get_memory_c(address++, 0); + } + } + } else { + ea = operand; + } + break; + case 0x20: /* jsr */ + if (operand == 0xbf00) { + unsigned num = get_memory_c(address, 0); + const char *name = debug_tool_name(num, operand); + if (name) { + opcode_string = name; + unsigned parms = get_memory16_c(address + 1, 0); + sprintf(buffer, "$%04x", parms); + + for (i = 0; i < 3; ++i) { + buffer2[bsize++] = get_memory_c(address++, 0); + } + } + } else { + ea = (operand | (address & 0xff0000)); + } + break; + case 0x82: { + ea = address + (int16_t)operand; + ea &= 0xffff; + ea |= pc & 0xff0000; + + const char *name = get_inline_debug_name(pc); + /* start of an inline debug name? */ + if (name) { + opcode_string = name; + buffer[0] = 0; + + /* include the 0x77 71 magic bytes */ + for (i = 0; i < 2; ++i) { + buffer2[bsize++] = get_memory_c(address++, 0); + } + address = ea; + ea = 0; + } + break; + } + case 0x80: { + ea = address + (int8_t)operand; + ea &= 0xffff; + ea |= pc & 0xff0000; + + const char *name = get_inline_debug_name(pc); + /* start of an inline debug name? */ + if (name) { + opcode_string = name; + buffer[0] = 0; + + /* include the 0x77 71 magic bytes */ + for (i = 0; i < 2; ++i) { + buffer2[bsize++] = get_memory_c(address++, 0); + } + address = ea; + ea = 0; + } + break; + } + + + case 0x10: + case 0x30: + case 0x50: + case 0x70: + case 0x90: + case 0xb0: + case 0xd0: + case 0xf0: { + ea = address + (int8_t)operand; + ea &= 0xffff; + ea |= pc & 0xff0000; + break; + } + + } + + if (ea && !comment) { + comment = get_inline_debug_name(ea); + } + +#if 0 + + n = printf("%02x/%04x: %s %s", + pc >> 16, pc & 0xffff, + opcode_string, buffer); + for(; n < 40; ++n) putchar(' '); + + for(i = 0; i < bsize; ++i) { + n += printf(" %02x", buffer2[i]); + } + if (comment) { + printf("%*s; %s", 60 - n, "", comment); + } + +#else + /* 12/3456: 01 23 45 LDA #1 ; comment */ + n = printf("%02x/%04x:", + pc >> 16, pc & 0xffff); + + for(i = 0; i < bsize; ++i) { + n += printf(" %02x", buffer2[i]); + } + while (n < 40) { fputc(' ', stdout); ++n; } + n += printf("%s %s", opcode_string, buffer); + if (comment) { + while (n < 65) { fputc(' ', stdout); ++n; } + printf("; %s", comment); + } +#endif + fputc('\n', stdout); + + } + return address; +} + +#if 0 +word32 next_pc(void) { + /* return next pc, skipping subroutines, + accounting for inline calls, and branches + */ + word32 pc = engine.kpc; + + enum { + C = 1 << 0, + Z = 1 << 1, + I = 1 << 2, + D = 1 << 3, + X = 1 << 4, + M = 1 << 5, + V = 1 << 6, + N = 1 << 7, + E = 1 << 8 + }; + + unsigned opcode = get_memory_c(pc++, 0); + unsigned operand = 0; + + unsigned dtype = disasm_types[opcode]; + unsigned args = dtype >> 8; + + switch (args) { + case 4: + args = engine.psr & M ? 1 : 2; + break; + case 5: + args = engine.psr & X ? 1 : 2; + break; + } + operand = 0; + switch(args) { + case 1: + operand = get_memory_c(pc, 0); + break; + case 2: + operand = get_memory16_c(pc, 0); + break; + case 3: + operand = get_memory24_c(pc, 0); + break; + } + pc += args; + + switch (opcode) { + case 0x20: + if ((pc & 0xff0000) == 0 && operand == 0xbf00) + return pc + 3; + break; + case 0x22: + if (operand == 0xe100a8) + return pc + 6; + break; + + case 0x82: /* brl */ + operand += pc & 0xffff; + return (pc & 0xff0000) | operand; + break; + case 0x80: /* bra */ + operand = (pc + (int8_t)operand) & 0xffff; + return (pc & 0xff0000) | operand; + break; + + case 0x90: /* bcc */ + operand = (pc + (int8_t)operand) & 0xffff; + if (~engine.psr & C) + return (pc & 0xff0000) | operand; + break; + case 0xb0: /* bcc */ + operand = (pc + (int8_t)operand) & 0xffff; + if (engine.psr & C) + return (pc & 0xff0000) | operand; + break; + + case 0x10: /* bpl */ + operand = (pc + (int8_t)operand) & 0xffff; + if (~engine.psr & N) + return (pc & 0xff0000) | operand; + break; + case 0x30: /* bmi */ + operand = (pc + (int8_t)operand) & 0xffff; + if (engine.psr & N) + return (pc & 0xff0000) | operand; + break; + + case 0x50: /* bvc */ + operand = (pc + (int8_t)operand) & 0xffff; + if (~engine.psr & V) + return (pc & 0xff0000) | operand; + break; + case 0x70: /* bvs */ + operand = (pc + (int8_t)operand) & 0xffff; + if (engine.psr & V) + return (pc & 0xff0000) | operand; + break; + + case 0xd0: /* bvc */ + operand = (pc + (int8_t)operand) & 0xffff; + if (~engine.psr & Z) + return (pc & 0xff0000) | operand; + break; + case 0xf0: /* beq */ + operand = (pc + (int8_t)operand) & 0xffff; + if (engine.psr & Z) + return (pc & 0xff0000) | operand; + break; + + } + + + return 0; +} +#endif + +/* + * todo -- + * should use tmp breakpoint instead of g_stepping? + * don't want to step into an interrupt, for example. + * also, step should steps over gs/os, toolbox calls + * (gsbug has protected memory ranges) + */ +int next_pc(void) { + + word32 pc = engine.kpc; + unsigned opcode = get_memory_c(pc++, 0); + unsigned operand = 0; + + switch (opcode) { + case 0x20: /* jsr abs */ + operand = get_memory16_c(pc, 0); + pc += 2; + if ((pc & 0xff0000) == 0 && operand == 0xbf00) + pc += 3; + return pc; + break; + case 0xfc: /* jsr (abs,x) */ + return pc + 2; + break; + case 0x22: /* jsl */ + operand = get_memory24_c(pc, 0); + pc += 3; + if (operand == 0xe100a8) + pc += 6; + return pc; + break; + case 0x00: /* brk arg */ + case 0x02: /* cop arg */ + return pc + 2; + break; + } + + return -1; +} + + +enum { + REG_A, + REG_B, + REG_D, + REG_E, + REG_K, + REG_MX, + REG_P, + REG_PC, + REG_S, + REG_X, + REG_Y, +}; + +static word32 to_hex(const char *iter, const char *end) { + word32 rv = 0; + while(iter != end) { + char c = *iter++; + rv <<= 4; + if (isdigit(c)) rv |= c - '0'; + else rv |= (c | 0x20) - 'a' + 10; + } + return rv; +} + + +/*!re2c + re2c:define:YYCTYPE = char; + re2c:yyfill:enable = 0; + eol = "\x00"; + ws = [ \t]; + x = [A-Fa-f0-9]; +*/ + +static int do_assign(const char *cp, int reg) { + + word32 addr = 0; + int has_bank = 0; + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + /*!re2c + + * { return -1; } + x{6} eol { + addr = to_hex(cp, cp + 6); + has_bank = 1; + goto next; + } + x{2} "/" x{4} eol { + addr = to_hex(cp, cp + 2) << 16; + addr |= to_hex(cp + 3, cp + 7); + has_bank = 1; + goto next; + } + x{4} eol { + addr = to_hex(cp, cp + 4); + has_bank = 0; + goto next; + } + "%"[01]{2} eol { + if (reg != REG_MX) return -1; + if (cp[1] == '1') addr |= 0x20; + if (cp[2] == '1') addr |= 0x10; + goto next; + } + "%pc" eol { + addr = engine.kpc; + has_bank = 1; + goto next; + } + "%a" eol { + addr = engine.acc; + goto next; + } + "%x" eol { + addr = engine.xreg; + goto next; + } + "%y" eol { + addr = engine.yreg; + goto next; + } + "%d" eol { + addr = engine.direct; + goto next; + } + "%s" eol { + addr = engine.stack; + goto next; + } + "%b" eol { + addr = engine.dbank; + goto next; + } + "%k" eol { + addr = engine.kpc >> 16; + goto next; + } + "%p" eol { + addr = engine.psr & 0xff; + goto next; + } + "%e" eol { + addr = engine.psr >> 8; + goto next; + } + */ + +next: + + if (has_bank && reg != REG_PC) return -1; + + switch(reg) { + case REG_A: engine.acc = addr; break; + case REG_X: engine.xreg = addr; break; + case REG_Y: engine.yreg = addr; break; + case REG_D: engine.direct = addr; break; + case REG_S: engine.stack = addr; break; + case REG_B: engine.dbank = addr & 0xff; break; + + case REG_E: + engine.psr &= 0xff; + if (addr) engine.psr |= 0x0100; + break; + + case REG_K: + addr = (addr & 0xff) << 16; + engine.kpc = (engine.kpc & 0xffff) | addr; + break; + + case REG_PC: + if (!has_bank) addr |= (engine.kpc & 0xff0000); + engine.kpc = addr; + break; + + case REG_P: + engine.psr &= ~0xff; + engine.psr |= (addr & 0xff); + break; + + case REG_MX: + /* only 00, 10, 20, 30 are legal values */ + if ((addr | 0x30) != 0x30) return -1; + engine.psr &= ~0x30; + engine.psr |= addr; + break; + + + } + + /* fixup registers */ + if (engine.psr & 0x0100) { + engine.psr |= 0x30; + engine.stack = (engine.stack & 0xff) | 0x0100; + } + if (engine.psr & 0x10) { + engine.xreg &= 0xff; + engine.yreg &= 0xff; + } + return 0; +} + +static int do_setting(const char *cp, int value) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + unsigned psr_bits = 0; + + + /* TODO - nl uses 'a' to track sep/rep/xce */ + + /*!re2c + * { + fputs("invalid setting\n", stderr); + return -1; + } + "brk" eol { + engine.flags &= ~FLAG_WANT_BRK; + if (value) engine.flags |= FLAG_WANT_BRK; + printf("brk intercept %s\n", value ? "on" : "off"); + return 0; + } + "cop" eol { + engine.flags &= ~FLAG_WANT_COP; + if (value) engine.flags |= FLAG_WANT_COP; + printf("cop intercept %s\n", value ? "on" : "off"); + return 0; + } + + "e" eol { psr_bits = 0x0100; goto set_psr; } + "m" eol { psr_bits = 0x0020; goto set_psr; } + "x" eol { psr_bits = 0x0010; goto set_psr; } + "mx" eol { psr_bits = 0x0030; goto set_psr; } + */ + +set_psr: + if (value) g_disasm_psr |= psr_bits; + else g_disasm_psr &= ~psr_bits; + if (g_disasm_psr & 0x0100) g_disasm_psr = 0x0130; + printf("disasm psr %03x\n", g_disasm_psr); + return 0; +} + +#if 0 +static int do_brk_cop(const char *cp, int which) { + /* brk=1 / brk=0 */ + + const char *YYCURSOR = cp; + int value = 0; + + /*!re2c + [01] eol { + value = *cp - '0'; + goto next; + } + * { return -1; } + */ +next: + + switch(which) { + case 0x00: + engine.flags &= ~FLAG_WANT_BRK; + if (value) engine.flags |= FLAG_WANT_BRK; + printf("brk intercept %s\n\n", value ? "on" : "off"); + break; + case 0x02: + engine.flags &= ~FLAG_WANT_COP; + if (value) engine.flags |= FLAG_WANT_COP; + printf("cop intercept %s\n\n", value ? "on" : "off"); + break; + } + return 0; +} +#endif + + +static word32 do_mem_assign(word32 addr, const char *cp) { + /* "string" -> pokes ASCII chars */ + /* 'string' -> pokes ASCII chars | 0x80 */ + /* xx -> pokes hex byte */ + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + for(;;) { + const char *start = YYCURSOR; + /*!re2c + eol { return addr; } + ws { continue; } + * { + fputs("Invalid data\n", stderr); + return addr; + } + x{2} { + set_memory_c(addr++, to_hex(start, YYCURSOR), 0); + continue; + } + ["] [^"\x00]* ["] { + for(++start; start < YYCURSOR -1; ++start) { + set_memory_c(addr++, *start, 0); + } + continue; + } + ['] [^'\x00]* ['] { + for(++start; start < YYCURSOR -1; ++start) { + set_memory_c(addr++, *start | 0x80, 0); + } + continue; + } + + */ + } +} + + +static int addr_cmp(const void *a, const void *b) { + word32 aa = *(const word32 *)a; + word32 bb = *(const word32 *)b; + + return (int)aa - (int)bb; +} + + + +void show_bp(int type) { + int i; + word32 addr; + word32 *breakpoints; + int num_breakpoints; + + switch(type) { + case 'B': + breakpoints = g_bp_breakpoints; + num_breakpoints = g_num_bp_breakpoints; + break; + case 'M': + breakpoints = g_mp_breakpoints; + num_breakpoints = g_num_mp_breakpoints; + break; + + case 'T': + breakpoints = g_tp_breakpoints; + num_breakpoints = g_num_tp_breakpoints; + break; + + + default: + fputs("Invalid breakpoint type\n", stderr); + return; + } + + fputs("Breakpoints:\n", stdout); + for (i = 0; i < num_breakpoints; ++i) { + addr = breakpoints[i]; + printf("%02x/%04x\n", addr >> 16, addr & 0xffff); + } +} + +int set_bp(int type, word32 addr) { + int i; + + word32 *breakpoints; + int num_breakpoints; + + switch(type) { + case 'B': + breakpoints = g_bp_breakpoints; + num_breakpoints = g_num_bp_breakpoints; + break; + case 'M': + breakpoints = g_mp_breakpoints; + num_breakpoints = g_num_mp_breakpoints; + break; + case 'T': + breakpoints = g_tp_breakpoints; + num_breakpoints = g_num_tp_breakpoints; + break; + + default: + fputs("Invalid breakpoint type\n", stderr); + return 0; + } + + for (i = 0; i < num_breakpoints; ++i) { + if (breakpoints[i] == addr) break; + } + + if (i < num_breakpoints) return 1; /* already set */ + if (num_breakpoints == MAX_BREAK_POINTS) { + printf("Too many breakpoints.\n"); + return 0; + } + breakpoints[num_breakpoints++] = addr; + + switch(type) { + case 'B': g_num_bp_breakpoints = num_breakpoints; break; + case 'M': g_num_mp_breakpoints = num_breakpoints; break; + case 'T': g_num_tp_breakpoints = num_breakpoints; break; + } + + qsort(breakpoints, num_breakpoints, sizeof(word32), addr_cmp); + fixup_brks(); + return 1; +} + +/* returns 1 if address deleted */ +int delete_bp(int type, word32 addr) { + int i; + + word32 *breakpoints; + int num_breakpoints; + + switch(type) { + case 'B': + breakpoints = g_bp_breakpoints; + num_breakpoints = g_num_bp_breakpoints; + break; + case 'M': + breakpoints = g_mp_breakpoints; + num_breakpoints = g_num_mp_breakpoints; + break; + case 'T': + breakpoints = g_tp_breakpoints; + num_breakpoints = g_num_tp_breakpoints; + break; + + default: + fputs("Invalid breakpoint type\n", stderr); + return 0; + } + + for (i = 0; i < num_breakpoints; ++i) { + if (breakpoints[i] == addr) break; + } + + if (i == num_breakpoints) return 0; /* not set */ + breakpoints[i] = 0; + breakpoints[i] = breakpoints[--num_breakpoints]; + + switch(type) { + case 'B': g_num_bp_breakpoints = num_breakpoints; break; + case 'M': g_num_mp_breakpoints = num_breakpoints; break; + case 'T': g_num_tp_breakpoints = num_breakpoints; break; + } + + qsort(breakpoints, num_breakpoints, sizeof(word32), addr_cmp); + fixup_brks(); + return 1; +} + + +static void do_help(void) { + + fputs( + " * Print registers\n" + " reg=value Assign register (a,x,y,etc)\n" + " reset Reset computer\n" + " quit Exit debugger\n" + " s Single step\n" + " g Go\n" + " bp List PC breakpoints\n" + " mp List memory breakpoints\n" + "\n" + " [address];l List\n" + " [address];h Hexdump\n" + " [address];bp Set PC breakpoint\n" + " [address];bp- Remove PC breakpoint\n" + " [address];mp Set memory breakpoint\n" + " [address];mp- Remove memory breakpoint\n" + " [address]\\temp name Display template\n" + "\n" + "\n" + "Address = 12/3456, 123456, or 1234\n" + "Register = %%a, %%x, %%y, %%pc, etc\n", + stdout); +} + + + +/* return -1 on error, 0 on success, 1 if debug shell should exit. */ +static int parse_command(const char *cp) { + + + /* TODO: + ! -> mini assembler mode. + */ + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + int addr = 0; + int has_bank = 0; + int has_addr = 0; + + while (*cp == ' ') ++cp; + + /*!re2c + + _ = (ws | eol); + + * { --YYCURSOR; if (cp == YYCURSOR) goto command; return -1; } + + "bp" eol { show_bp('B'); return 0; } + "mp" eol { show_bp('M'); return 0; } + + "*" eol { show_regs(); return 0; } + + ("q" | "quit" | "exit" | "bye") eol { return 'q'; } + "reset" eol { do_reset(); return 0; } + ("help" | "?") eol { do_help(); return 0; } + + "!!" eol { + extern uint32_t sweet16_asm_shell(uint32_t addr); + sweet16_asm_shell(0x300); + return 0; + } + + "0>" { return do_setting(YYCURSOR, 0); } + "1>" { return do_setting(YYCURSOR, 1); } + + // register stuff + + "%pc++" eol { + /* todo */ + unsigned opcode = get_memory_c(engine.kpc, 0); + unsigned dtype = disasm_types[opcode]; + unsigned args = dtype >> 8; + word32 tmp; + + switch (args) { + case 4: + args = engine.psr & 0x20 ? 1 : 2; + break; + case 5: + args = engine.psr & 0x10 ? 1 : 2; + break; + } + tmp = engine.kpc + 1 + args; + tmp &= 0xffff; + engine.kpc = (engine.kpc & 0xff0000) | tmp; + return 0; + } + + "%s++" eol { + unsigned tmp = engine.stack + 1; + if (engine.psr & 0x0100) { + tmp &= 0xff; + tmp |= 0x0100; + } else { + tmp &= 0xffff; + } + engine.stack = tmp; + } + + "%s--" eol { + unsigned tmp = engine.stack + 1; + if (engine.psr & 0x0100) { + tmp &= 0xff; + tmp |= 0x0100; + } else { + tmp &= 0xffff; + } + engine.stack = tmp; + } + + "%a=" { return do_assign(YYCURSOR, REG_A); } + "%x=" { return do_assign(YYCURSOR, REG_X); } + "%y=" { return do_assign(YYCURSOR, REG_Y); } + "%d=" { return do_assign(YYCURSOR, REG_D); } + "%e=" { return do_assign(YYCURSOR, REG_E); } + "5s=" { return do_assign(YYCURSOR, REG_S); } + "%k=" { return do_assign(YYCURSOR, REG_K); } + "%b=" { return do_assign(YYCURSOR, REG_B); } + "%p=" { return do_assign(YYCURSOR, REG_P); } + "%pc=" { return do_assign(YYCURSOR, REG_PC); } + "%mx=" { return do_assign(YYCURSOR, REG_MX); } + + + "%pc" { + addr = engine.kpc; + has_addr = 1; + has_bank = 1; + goto indir; + } + "%a" { + addr = engine.acc; + has_addr = 1; + has_bank = 0; + goto indir; + } + "%x" { + addr = engine.xreg; + has_addr = 1; + has_bank = 0; + goto indir; + } + "%y" { + addr = engine.yreg; + has_addr = 1; + has_bank = 0; + goto indir; + } + "%s" { + addr = engine.stack; + has_addr = 1; + has_bank = 1; + goto indir; + } + "%d" { + addr = engine.direct; + has_addr = 1; + has_bank = 1; + goto indir; + } + + + + x{6} { + addr = to_hex(cp, cp + 6); + has_bank = 1; + has_addr = 1; + goto indir; + } + x{2} "/" x{4} { + addr = to_hex(cp, cp + 2) << 16; + addr |= to_hex(cp + 3, cp + 7); + has_bank = 1; + has_addr = 1; + goto indir; + } + x{1,4} { + addr = to_hex(cp, YYCURSOR); + has_bank = 0; + has_addr = 1; + goto indir; + } + */ +indir: + cp = YYCURSOR; + /* only gets here if address specified */ + for(;;) { + /*!re2c + "" { break; } + "^" { + /* 3-byte indirection */ + if (!has_bank) addr = (g_prev_address & 0xff0000) | addr; + addr = get_memory24_c(addr, 0); + has_bank = 1; + continue; + } + "@" { + /* 2-byte indirection */ + /* 3-byte indirection */ + if (!has_bank) addr = (g_prev_address & 0xff0000) | addr; + word32 b = addr & 0xff0000; + addr = get_memory16_c(addr, 0) | b; + has_bank = 1; + continue; + } + */ + } + +command: + if (!has_bank) { + addr |= (g_prev_address & 0xff0000); + } + if (!has_addr) { + addr = g_prev_address; + } + + cp = YYCURSOR; + /*!re2c + * { return -1; } + + ":" { + g_prev_address = do_mem_assign(addr, YYCURSOR); + return 0; + } + + (";l" | "l") eol { + g_prev_address = do_list(addr, 20); + return 0; + } + ";h" eol { + g_prev_address = do_hexdump(addr, 20); + return 0; + } + + ";s" eol { + /* print the stack */ + word32 bank; + if (!has_addr) { + addr = g_prev_stack_address; + bank = g_prev_stack_bank; + } + if (has_bank) { + bank = addr & 0xff0000; + addr &= 0xffff; + } + g_prev_stack_address = do_stack(addr,bank); + return 0; + } + + "g" eol { + /* GO! */ + if (has_addr) { + engine.kpc = addr; + } + g_stepping = 0; + return 1; + } + "s" eol { + /* step */ + if (has_addr) { + engine.kpc = addr; + } + g_stepping = 1; + + clear_prev_line(); + return 1; + } + + "n" eol { + /* next. steps OVER jsr/jsl */ + + if (has_addr) { + engine.kpc = addr; + } + int tmp = next_pc(); + if (tmp < 0) { + g_stepping = 1; + } else { + g_stepping = 0; + set_bp('T', tmp); + } + + clear_prev_line(); + return 1; + } + + ";bp" [+-]? eol { + char plus = cp[3]; + if (!has_addr && plus == 0) { show_bp('B'); return 0; } + if (!has_addr) return -1; + if (plus == '-') delete_bp('B', addr); + else set_bp('B', addr); + return 0; + } + + ";mp" [+-]? eol { + char plus = cp[3]; + if (!has_addr && plus == 0) { show_bp('M'); return 0; } + if (!has_addr) return -1; + if (plus == '-') delete_bp('M', addr); + else set_bp('M', addr); + return 0; + } + "\\temp" / (ws|eol) { + /* apply a gsbug template to memory */ + /* address\temp name */ + while (isspace(*YYCURSOR)) ++YYCURSOR; + g_prev_address = debug_apply_template(addr, YYCURSOR); + return 0; + } + + "h" eol { + g_prev_address = addr; + do_handle(addr, 'h'); + return 0; + } + + "i" eol { + g_prev_address = addr; + do_handle(addr, 'i'); + return 0; + } + + "w" eol { + g_prev_address = addr; + do_handle(addr, 'w'); + return 0; + } + + + */ +} + + +int debug_shell(int code) { + int c; + char *cp; + int control_d_count = 0; + word32 kpc = engine.kpc; + + fflush(stderr); + fflush(stdout); + + if (!g_templates_loaded) { + char *path; + g_templates_loaded = 1; + + path = get_resource_path("GSBug.Templates"); + if (path) { + debug_load_templates(path); + free(path); + } + path = get_resource_path("NList.Data"); + if (path) { + debug_load_nifty(path); + free(path); + } + } + + + if (code == RET_BP) { + + /* check for temp. breakpoint */ + if (!delete_bp('T', engine.kpc)) { + printf("Breakpoint hit:\n"); + } + } + if (code == RET_MP) { + printf("Memory breakpoint hit\n"); + switch (g_abort_bytes) { + case 1: g_abort_value &= 0xff; break; + case 2: g_abort_value &= 0xffff; break; + case 3: g_abort_value &= 0xffffff; break; + } + printf("%06x: %0*x\n", g_abort_address, g_abort_bytes * 2, g_abort_value); + } + if (code == RET_BRK || code == RET_COP) { + /* hit a BRK op */ + } + if (code == RET_HALT) { + /* halt_printf or ^C */ + fputs("\n", stdout); + } + + + g_prev_stack_address = engine.stack; + g_prev_stack_bank = engine.kpc & 0xff0000; + g_prev_address = engine.kpc; + g_disasm_psr = engine.psr; + do_list(engine.kpc, 1); + + for(;;) { + cp = x_readline("] "); + if (!cp) { + if (++control_d_count < 2) + continue; + fputs("quit\n", stdout); + fflush(stdout); + return 0; + } + control_d_count = 0; + if (!*cp) continue; + c = parse_command(cp); + if (c < 0) printf("error.\n"); + if (c == 'q') return 0; + if (c == 1) break; + } + + if (engine.kpc == kpc) { + switch(code) { + case RET_BRK: + case RET_COP: + engine.flags |= FLAG_IGNORE_BRK; + break; + case RET_MP: + engine.flags |= FLAG_IGNORE_MP; + break; + case RET_BP: + engine.flags |= FLAG_IGNORE_BP; + break; + } + } + + return 1; +} + +static void do_sig_intr(int sig) { + if (halt_sim & 4) { + abort(); + } + set_halt(4); +} + + +#ifdef _WIN32 +static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) { + /* handled via a new thread */ + if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) { + do_sig_intr(SIGINT); + return TRUE; + } + return FALSE; +} +#endif + + +/* also called by do_step */ +void do_go() { + int ret; + int ok; + + #ifdef _WIN32 + SetConsoleCtrlHandler(ctrl_handler, 1); + #else + /* if -g flag, start with debug shell ... */ + if (isatty(STDIN_FILENO)) { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = do_sig_intr; + sigaction(SIGINT, &sa, NULL); + + } else { + g_dbg_shell = 0; + } + #endif + + g_config_control_panel = 1; + if (g_dbg_shell) { + ok = debug_shell(0); + if (!ok) return; + } + + g_config_control_panel = 0; + clear_halt(); + + for(;;) { + + ret = run_prog(); + if (halt_sim & HALT_WANTTOQUIT) return; + + if (ret || g_stepping) { + g_config_control_panel = 1; + ok = debug_shell(ret); + if (!ok) return; + g_config_control_panel = 0; + halt_sim &= ~0x07; /* clear any pending control-Cs, etc. */ + } + } +} + +/* legacy */ + + + +void halt_printf(const char *fmt, ...) { + va_list args; + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + set_halt(1); +} + +void halt2_printf(const char *fmt, ...) { + va_list args; + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + set_halt(2); +} diff --git a/src/debug_sweet16.re2c b/src/debug_sweet16.re2c new file mode 100644 index 0000000..fcb716d --- /dev/null +++ b/src/debug_sweet16.re2c @@ -0,0 +1,400 @@ + + +#include +#include +#include + +#include "defc.h" + + +enum modes { + none = 0, + reg = 1 << 1, + indir_reg = 1 << 2, + reg_imm = 1 << 3, + relative = 1 << 4 +}; + + +static word32 to_hex(const char *iter, const char *end) { + word32 rv = 0; + while(iter != end) { + char c = *iter++; + rv <<= 4; + if (isdigit(c)) rv |= c - '0'; + else rv |= (c | 0x20) - 'a' + 10; + } + return rv; +} + +const char *ltrim(const char *cp) { + while (isspace(*cp)) ++cp; + return cp; +} + +/*!re2c + re2c:define:YYCTYPE = char; + re2c:yyfill:enable = 0; + eol = "\x00"; + ws = [ \t]; + x = [A-Fa-f0-9]; +*/ + + +const char *parse_pc(const char *cp, uint32_t *pc) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + if (isspace(*cp)) return ltrim(cp); + + /*!re2c + * { return NULL; } + x{4} ':' { + *pc &= 0xff0000; + *pc |= to_hex(cp, YYCURSOR - 1); + goto next; + } + x{6} ':' { + *pc = to_hex(cp, YYCURSOR - 1); + goto next; + } + + x{2} '/' x{4} ':' { + uint32_t tmp = to_hex(cp, cp + 2) << 16; + tmp |= to_hex(cp + 3, YYCURSOR - 1); + *pc = tmp; + goto next; + } + + */ + +next: + return ltrim(YYCURSOR); +} + +const char *parse_opcode(const char *cp, int *opcode, int *mode) { + int op = -1; + int m = 0; + unsigned c; + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + /* TODO - db, dw ? */ + + /*!re2c + * { return NULL; } + 'set' { op = 0x10; m = reg_imm; goto next; } + 'ld' { op = 0x20; m = reg | indir_reg; goto next; } + 'st' { op = 0x30; m = reg | indir_reg; goto next; } + 'ldd' { op = 0x60; m = indir_reg; goto next; } + 'std' { op = 0x70; m = indir_reg; goto next; } + 'pop' { op = 0x80; m = indir_reg; goto next; } + 'stp' { op = 0x90; m = indir_reg; goto next; } + 'add' { op = 0xa0; m = reg; goto next; } + 'sub' { op = 0xb0; m = reg; goto next; } + 'popd' { op = 0xc0; m = indir_reg; goto next; } + 'cpr' { op = 0xd0; m = reg; goto next; } + 'inr' { op = 0xe0; m = reg; goto next; } + 'dcr' { op = 0xf0; m = reg; goto next; } + + 'rtn' { op = 0x00; goto next; } + 'br' { op = 0x01; m = relative; goto next; } + 'bnc' { op = 0x02; m = relative; goto next; } + 'bc' { op = 0x03; m = relative; goto next; } + 'bp' { op = 0x04; m = relative; goto next; } + 'bm' { op = 0x05; m = relative; goto next; } + 'bz' { op = 0x06; m = relative; goto next; } + 'bnz' { op = 0x07; m = relative; goto next; } + 'bm1' { op = 0x08; m = relative; goto next; } + 'bnm1' { op = 0x09; m = relative; goto next; } + 'bk' { op = 0x0a; goto next; } + 'rs' { op = 0x0b; goto next; } + 'bs' { op = 0x0c; m = relative; goto next; } +*/ + +next: + c = *YYCURSOR; + if (c && !isspace(c)) return NULL; + + *opcode = op; + *mode = m; + return ltrim(YYCURSOR); +} + +const char *parse_register(const char *cp, int *opcode) { + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + /*!re2c + * { return NULL; } + + 'R' ([0-9]{1,2}) { + int r = 0; + for(cp = cp + 1; cp < YYCURSOR; ++cp) { + r = r * 10 + *cp - '0'; + } + if (r > 15) return NULL; + *opcode |= r; + goto next; + } + + /* + 'R' x { + int r = to_hex(cp + 1, YYCURSOR); + *opcode |= r; + goto next; + } + */ + 'ACC' { *opcode |= 0x00; goto next; } + 'PC' { *opcode |= 0x0f; goto next; } + 'SR' { *opcode |= 0x0e; goto next; } + */ + +next: + return ltrim(YYCURSOR); +} + +const char *parse_address(const char *cp, int *address, int pc) { + + const char *YYCURSOR = cp; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + int ea = 0; + + /*!re2c + + * { return NULL; } + '*' { ea = pc; goto next; } + '*' [+-] x{1,4} { + ea = to_hex(cp + 2, YYCURSOR); + if (cp[1] == '+') ea += pc; + else ea -= pc; + goto next; + } + x{1,4} { + ea = to_hex(cp, YYCURSOR); + goto next; + } + */ + +next: + *address = ea & 0xffff; + return ltrim(YYCURSOR); +} + + +uint32_t sweet16_disasm(uint32_t addr, int lines) { + + unsigned op; + const char *opcode; + unsigned mode = none; + unsigned operand; + unsigned x; + int i; + + uint8_t bytes[4]; + + while (lines--) { + unsigned size = 0; + uint32_t pc = addr; + op = get_memory_c(addr++, 0); + bytes[size++] = op; + + switch (op >> 4) { + case 0x00: + switch(op) { + case 0x00: opcode = "RTN"; break; + case 0x01: opcode = "BR"; mode = relative; break; + case 0x02: opcode = "BNC"; mode = relative; break; + case 0x03: opcode = "BC"; mode = relative; break; + case 0x04: opcode = "BP"; mode = relative; break; + case 0x05: opcode = "BM"; mode = relative; break; + case 0x06: opcode = "BZ"; mode = relative; break; + case 0x07: opcode = "BNZ"; mode = relative; break; + case 0x08: opcode = "BM1"; mode = relative; break; + case 0x09: opcode = "BNM1"; mode = relative; break; + case 0x0a: opcode = "BK"; break; + case 0x0b: opcode = "RS"; break; + case 0x0c: opcode = "BS"; mode = relative; break; + case 0x0d: opcode = "???"; break; + case 0x0e: opcode = "???"; break; + case 0x0f: opcode = "???"; break; + } + break; + case 0x01: opcode = "SET"; mode = reg_imm; break; + case 0x02: opcode = "LD"; mode = reg; break; + case 0x03: opcode = "ST"; mode = reg; break; + case 0x04: opcode = "LD"; mode = indir_reg; break; + case 0x05: opcode = "ST"; mode = indir_reg; break; + case 0x06: opcode = "LDD"; mode = indir_reg; break; + case 0x07: opcode = "STD"; mode = indir_reg; break; + case 0x08: opcode = "POP"; mode = indir_reg; break; + case 0x09: opcode = "STP"; mode = indir_reg; break; + case 0x0a: opcode = "ADD"; mode = reg; break; + case 0x0b: opcode = "SUB"; mode = reg; break; + case 0x0c: opcode = "POPD"; mode = indir_reg; break; + case 0x0d: opcode = "CPR"; mode = reg; break; + case 0x0e: opcode = "INR"; mode = reg; break; + case 0x0f: opcode = "DCR"; mode = reg; break; + } + + + switch(mode) { + case none: + case reg: + case indir_reg: + break; + case relative: + operand = (int8_t)get_memory_c(addr++, 0); + bytes[size++] = operand; + operand += addr; + operand &= 0xffff; + break; + case reg_imm: + operand = get_memory16_c(addr, 0); + addr += 2; + bytes[size++] = operand & 0xff; + bytes[size++] = operand >> 8; + break; + } + + x = printf("%02x/%04x:", pc >> 16, pc & 0xffff); + for (i = 0; i < size; ++i) { + x += printf(" %02x", bytes[i]); + } + + for( ; x < 20; ++x) fputc(' ', stdout); + printf("%-5s", opcode); + switch(mode) { + case none: break; + case reg: x += printf("R%d", op & 0x0f); break; + case indir_reg: x += printf("@R%d", op & 0x0f); break; + case relative: + x += printf("%04x", operand); + break; + case reg_imm: + x += printf("R%d, %04x", op & 0x0f, operand); + break; + } + + fputc('\n', stdout); + } + return addr; +} + + +static int error(int offset, const char *msg) { + while (offset > 0) { fputc(' ', stderr); --offset; } + fputs(" ^", stderr); + fputs(msg, stderr); + fputc('\n', stderr); + return -1; +} +int parse_line(const char *cp, uint32_t *pc) { + + uint32_t addr = *pc; + int opcode; + int operand; + int indir = 0; + int mode = 0; + int i; + unsigned offset = 0; + const char *start = cp; + + uint8_t bytes[3]; + int size = 0; + + cp = parse_pc(cp, &addr); + if (!cp) return error(0, "error"); + offset = cp - start; + + /* label only? */ + if (!*cp) { + *pc = addr; + return 0; + } + + cp = parse_opcode(cp, &opcode, &mode); + if (!cp) return error(offset, "bad opcode"); + offset = cp - start; + + if (mode & (reg | indir_reg | reg_imm)) { + if (*cp == '@') { + indir = 1; + ++cp; + } + cp = parse_register(cp, &opcode); + if (!cp) return error(offset, "bad register"); + offset = cp - start; + + /* cleanup indir */ + /* LD / ST */ + if (indir && mode == (reg|indir_reg)) { + opcode += 0x20; + mode = indir_reg; + } + if ((mode == indir_reg) != indir) + return error(offset, "bad operand"); + } + + + bytes[size++] = opcode; + if (mode == reg_imm) { + if (*cp++ != ',') + return error(offset, "expected ,"); + + cp = ltrim(cp); + offset = cp - start; + } + + if (mode & (relative | reg_imm)) { + cp = parse_address(cp, &operand, addr); + if (!cp) return error(offset, "bad operand"); + offset = cp - start; + + if (mode == relative) { + int tmp = (addr + 2) & 0xffff; + operand -= tmp; + if (operand > 127 || operand < -128) + return error(offset, "out of range"); + bytes[size++] = operand; + } else { + bytes[size++] = operand & 0xff; + bytes[size++] = operand >> 8; + } + } + if (!cp) return error(offset, "bad operand"); + + + for (i = 0; i < size; ++i) { + set_memory_c(addr + i, bytes[i], 0); + } + *pc = addr + size; + + fputs("\r\x1b[A\x1b[K", stdout); + sweet16_disasm(addr, 1); + return 1; +} + + + + +extern char *x_readline(const char *prompt); + + +uint32_t sweet16_asm_shell(uint32_t addr) { + + for(;;) { + const char *cp = x_readline("!!"); + if (!cp || !*cp) return addr; + + parse_line(cp, &addr); + + } +} diff --git a/src/debug_template.re2c b/src/debug_template.re2c new file mode 100644 index 0000000..f9c6dee --- /dev/null +++ b/src/debug_template.re2c @@ -0,0 +1,577 @@ +/* + * + * Load and parse GSBug templates and Nifty List Data. + */ + +#include +#include +#include +#include + +#include "defc.h" + + +#ifdef WIN32 +char *strndup(const char *s, size_t maxlen) { + char *cp; + size_t l = strlen(s); + + if (l > maxlen) l = maxlen; + cp = malloc(l + 1); + if (cp) { + memcpy(cp, s, l); + cp[l] = 0; + } + return cp; +} +#endif + +/*!re2c + re2c:define:YYCTYPE = char; + re2c:define:YYCURSOR = cp; + re2c:yyfill:enable = 0; + eol = "\x00"; + ws = [ \t\r\n]; + x = [0-9a-fA-F]; +*/ + + +/* format + _START name + name [type [size]] * + _END + */ + + +struct field { + char *name; + int type; + int count; +}; + +struct record { + char *name; + int total_size; /* total size */ + int field_count; /* # of fields */ + int field_index; /* starting index into the fields array */ +}; + +static struct record *records = NULL; +static int record_count = 0; +static int record_alloc = 0; + +static struct field *fields = NULL; +static int field_count = 0; +static int field_alloc = 0; + +static int record_compare(const void *a, const void *b) { + const struct record *aa = a; + const struct record *bb = b; + int rv; + rv = strcasecmp(aa->name, bb->name); + //if (rv == 0) return aa->total_size - bb->total_size; + return rv; +} + +/* 192 records in the standard file... */ +static void add_record(struct record *r) { + /* calc size and count */ + int i; + + r->field_count = field_count - r->field_index; + for (i = r->field_index; i < field_count; ++i) { + int size = fields[i].type; + if (size > 4) size = 4; + r->total_size += size * fields[i].count; + } + + if (record_count == record_alloc) { + size_t size = (record_alloc + 256) * sizeof(struct record); + void *tmp = realloc(records, size); + if (!tmp) return; /* oops */ + records = tmp; + record_alloc += 256; + } + records[record_count++] = *r; +} + + +/* average ~14 fields per record */ +static void add_field(struct field *f) { + if (field_count == field_alloc) { + size_t size = (field_alloc + 512) * sizeof(struct field); + void *tmp = realloc(fields, size); + if (!tmp) return; /* oops */ + fields = tmp; + field_alloc += 512; + } + fields[field_count++] = *f; +} + +static char *rtrim(char *cp) { + int l = strlen(cp); + while (l && isspace(cp[l-1])) --l; + cp[l] = 0; + return cp; +} + +static char *ltrim(char *cp) { + while (isspace(*cp)) ++cp; + return cp; +} + +/* 0 - no field, 1 - ok, -1 - warning */ +static int parse_field(const char *cp, struct field *f) { + const char *start; + const char *end; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + int type = 0; + int count = 0; + + start = cp; + for(;;) { + /*!re2c + eol | ws { --cp; break; } + * { continue; } + */ + } + end = cp; + if (start == end) return 0; + + f->name = strndup(start, end - start); + f->type = 0; + f->count = 0; + + while (isspace(*cp)) ++cp; + + /* optional type */ + /*!re2c + "BYTE" / (ws | eol) { type = 1; goto next; } + "WORD" / (ws | eol) { type = 2; goto next; } + "LONG" / (ws | eol) { type = 4; goto next; } + "CSTRING" / (ws | eol) { type = 5; goto next; } + "PSTRING" / (ws | eol) { type = 6; goto next; } + "GSSTRING" / (ws | eol) { type = 7; goto next; } + "" { type = 0; goto next; } + */ + +next: + while (isspace(*cp)) ++cp; + if (type) { + count = 0; + while(isdigit(*cp)) { + count = count * 10 + *cp - '0'; + ++cp; + } + if (!count) count = 1; + } + while (isspace(*cp)) ++cp; + if (*cp != 0) { + return -1; + } + f->type = type; + f->count = count; + return 1; +} + + +void debug_load_templates(const char *path) { + FILE *f; + char buffer[1024]; + int ok; + int in_struct = 0; + struct record record; + struct field field; + unsigned line = 0; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + + f = fopen(path, "r"); + if (!f) { + fprintf(stderr, "Unable to load %s: %s\n", path, strerror(errno)); + return; + } + for (line = 1;;++line) { + const char *start = NULL; + const char *end = NULL; + + const char *cp = fgets(buffer, sizeof(buffer), f); + if (!cp) break; + rtrim(buffer); + + /*!re2c + "" { goto _field; } + ";" { continue; } + ws* eol { continue; } + "_END" / (ws | eol) { goto _end; } + "_START" / (ws | eol) { goto _start; } + */ + +_field: + if (!in_struct) { + /* warn once */ + fprintf(stderr, "%s:%d: Missing _START.\n", path, line); + memset(&record, 0, sizeof(record)); + in_struct = -1; + } + if (in_struct < 0) continue; + + memset(&field, 0, sizeof(field)); + ok = parse_field(cp, &field); + if (ok == 0) continue; + if (ok < 1) { + /* warn but add */ + fprintf(stderr, "%s:%d: Bad field line: %s\n", path, line, buffer); + } + add_field(&field); + continue; + +_start: + if (in_struct) { + /* warn and close it */ + if (in_struct > 0) add_record(&record); + } + memset(&record, 0, sizeof(record)); + + while (isspace(*cp)) ++cp; + start = cp; + for(;;) { + /*!re2c + eol | ws { --cp; break; } + * { continue; } + */ + } + end = cp; + if (start == end) { + /* warning ... */ + fprintf(stderr, "%s:%d: _START missing name.\n", path, line); + in_struct = -1; + } else { + in_struct = 1; + record.name = strndup(start, end - start); + record.field_index = field_count; + } + + while (isspace(*cp)) ++cp; + if (*cp != 0) { + /* warning */ + fprintf(stderr, "%s:%d: Bad _START line: %s\n", path, line, buffer); + } + continue; + +_end: + while (isspace(*cp)) ++cp; + if (*cp != 0) { + /* warning ... */ + fprintf(stderr, "%s:%d: Bad _END line: %s\n", path, line, buffer); + } + + if (in_struct) { + if (in_struct > 0) add_record(&record); + } else { + /* warning */ + fprintf(stderr, "%s:%d: _END without _START.\n", path, line); + } + in_struct = 0; + memset(&record, 0, sizeof(record)); + + continue; + } + + if (in_struct) { + /* warn & close */ + fprintf(stderr, "%s:%d: Missing _END.\n", path, line); + if (in_struct > 0) add_record(&record); + } + fclose(f); + + qsort(records, record_count, sizeof(struct record), record_compare); +} + +static int record_search(const void *a, const void *b) { + const struct record *r = b; + return strcasecmp(a, r->name); +} + +static void print_string(int type, word32 address) { + + unsigned c; + unsigned length; + unsigned more = 0; + if (!address) return; + fputc('"', stdout); + + + switch(type) { + case 5: + length = 32; + break; + case 6: + length = get_memory_c(address, 0); + ++address; + break; + case 7: + length = get_memory16_c(address, 0); + address += 2; + break; + } + if (length > 32) { + length = 32; + more = 1; + } + + for (unsigned i = 0; i < length; ++i) { + c = get_memory_c(address++, 0); + if (type == 5 && c == 0) break; + + if ((~c & 0x80) && isprint(c)) { + fputc(c, stdout); + } else fprintf(stdout, "\\x%02x", c); + } + + if (type == 5 && c != 0) more = 1; + if (more) fputs("...", stdout); + + fputc('"', stdout); + fputc(' ', stdout); + +} +word32 debug_apply_template(word32 address, const char *name) { + /* 1 - lookup template */ + struct record *r; + int i, j; + struct field *f; + + r = bsearch(name, records, record_count, sizeof(struct record), record_search); + if (r == NULL) { + fprintf(stderr, "Invalid template: %s\n", name); + return address; + } + f = fields + r->field_index; + if (r->total_size == 0) { + /* just print the fields */ + for (i = 0; i < r->field_count; ++i) { + fputs(f[i].name, stdout); + fputc('\n', stdout); + } + fputc('\n', stdout); + return address; + } + + for (i = 0; i < r->field_count; ++i) { + word32 value; + unsigned type = f[i].type; + printf("%-16s", f[i].name); + for (j = 0; j < f[i].count; ++j) { + switch(type) { + case 1: + value = get_memory_c(address, 0); + address += 1; + printf("%02x ", value); + break; + case 2: + value = get_memory16_c(address, 0); + address += 2; + printf("%04x ", value); + break; + case 4: + case 5: /* cstring */ + case 6: /* pstring */ + case 7: /* gs/os string */ + value = get_memory24_c(address, 0); + address += 4; + printf("%08x ", value); + if (type > 4) { + print_string(type, value); + } + break; + } + address &= 0xffffff; + } + fputc('\n', stdout); + } + fputc('\n', stdout); + return address; +} + + + +struct tool { + char *name; + unsigned number; + unsigned vector; +}; + +struct tool *tools = NULL; +int tool_count = 0; +int tool_alloc = 0; + +static void add_tool(struct tool *t) { + if (tool_count == tool_alloc) { + size_t size = (tool_alloc + 1024) * sizeof(struct tool); + void *tmp = realloc(tools, size); + if (!tmp) return; + tools = tmp; + tool_alloc += 1024; + } + tools[tool_count++] = *t; +} + +static word32 to_hex(const char *iter, const char *end) { + word32 rv = 0; + while(iter != end) { + char c = *iter++; + rv <<= 4; + if (isdigit(c)) rv |= c - '0'; + else rv |= (c | 0x20) - 'a' + 10; + } + return rv; +} + +static int tool_compare(const void *a, const void *b) { + const struct tool *aa = a; + const struct tool *bb = b; + + int rv = (int)aa->vector - (int)bb->vector; + if (rv == 0) + rv = (int)aa->number - (int)bb->number; + return rv; +} + +/* nifty list */ +/* + * format: + * fffx ... header comments + * xxxx name ; p8 mli calls + * * + * xxxx name ; p16/gsos calls + * * + * xxxx name ; tool calls + * * + * xxxx name ; user tool calls + * * + * xxxx name ; e1 vectors + * * + * xxxx name ; e0 vectors + * * + * xxxx name ; softswitch/f8 rom + * * + * xxxx name ; 01 vectors + * * + * xxxx name ; nifty list service calls + * * + * xxxx name ; resource types + * * + * xxxx name ; error codes + * * + * xxxx name ; HC IIgs callbacks + * * + * xxxx name ; request codes + * * + * + */ + +void debug_load_nifty(const char *path) { + + FILE *f; + char buffer[1024]; + unsigned line = 0; + const char *YYMARKER = NULL; + const char *YYCTXMARKER = NULL; + + int section = 0; + unsigned vector = 0; + static unsigned vectors[] = { + 0xbf00, 0xe100a8, 0xe10000, 0xe10008, 0xe1, 0xe0, 0xff, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + + f = fopen(path, "r"); + if (!f) { + fprintf(stderr, "Unable to load %s: %s\n", path, strerror(errno)); + return; + } + for (line = 1;;++line) { + const char *start; + const char *end; + struct tool tool = { 0, 0, vector }; + + const char *cp = fgets(buffer, sizeof(buffer), f); + if (!cp) break; + rtrim(buffer); + + start = cp; + /*!re2c + [\r\n\x00] { continue; } + * { + fprintf(stderr, "%s:%d: Bad line: %s", path, line, buffer); + continue; + } + "*" { + ++section; + vector = 0; + if (section < sizeof(vectors) / sizeof(vectors[0])) + vector = vectors[section]; + continue; + } + x{4} / ws { goto ok; } + */ +ok: + end = cp; + tool.number = to_hex(start, end); + if (section == 0 && tool.number >= 0xfff0) continue; + if (!vector) continue; + + while (isspace(*cp)) ++cp; + /* skip p8/p16/ prefix */ + /*!re2c + "P8:" | "P16:" | "Shell:" | "GS/OS:" { goto prefix; } + "" { goto prefix; } + */ +prefix: + start = cp; + for(;;) { + /*!re2c + "" / eol { break; } + "(" | ws { + if (vector > 0x100 ) { + --cp; + break; + } + continue; + } + * { continue; } + */ + } + end = cp; + if (end > start) { + int l = end - start; + + if (vector > 0x0100) { + /* add a leading _ */ + tool.name = malloc(l + 2); + tool.name[0] = '_'; + strncpy(tool.name + 1, start, l); + tool.name[l + 1] = 0; + } + else tool.name = strndup(start, l); + add_tool(&tool); + } + + + } + + qsort(tools, tool_count, sizeof(struct tool), tool_compare); + fclose(f); +} + +const char *debug_tool_name(unsigned number, unsigned vector) { + struct tool tmp = { 0, number, vector }; + struct tool *t = bsearch(&tmp, tools, tool_count, sizeof(struct tool), tool_compare); + if (t) return t->name; + return NULL; +} \ No newline at end of file diff --git a/src/defc.h b/src/defc.h index 51cff56..d8d5470 100644 --- a/src/defc.h +++ b/src/defc.h @@ -43,11 +43,13 @@ void U_STACK_TRACE(); #ifdef GSPLUS_LITTLE_ENDIAN // @todo: look at using for fastest platform implementations -# define BIGEND(a) ((((a) >> 24) & 0xff) + \ - (((a) >> 8) & 0xff00) + \ - (((a) << 8) & 0xff0000) + \ - (((a) << 24) & 0xff000000)) -# define GET_BE_WORD16(a) ((((a) >> 8) & 0xff) + (((a) << 8) & 0xff00)) +# define BIGEND(a) (\ + (((a) >> 24) & 0xff) + \ + (((a) >> 8) & 0xff00) + \ + (((a) & 0xff00) << 8) + \ + (((a) & 0xff ) << 24) \ + ) +# define GET_BE_WORD16(a) ((((a) >> 8) & 0xff) + ((((a) & 0xff) << 8))) # define GET_BE_WORD32(a) (BIGEND(a)) #else # define BIGEND(a) (a) @@ -151,6 +153,7 @@ STRUCT(Fplus) { }; STRUCT(Engine_reg) { + Fplus *fplus_ptr; double fcycles; word32 kpc; word32 acc; @@ -163,7 +166,7 @@ STRUCT(Engine_reg) { word32 direct; word32 psr; - Fplus *fplus_ptr; + word32 flags; }; STRUCT(Kimage) { @@ -189,6 +192,7 @@ STRUCT(Cfg_menu) { const char *name_str; void *defptr; int cfgtype; + void *cookie; }; STRUCT(Cfg_dirent) { diff --git a/src/defcomm.h b/src/defcomm.h index 25b44cb..849b322 100644 --- a/src/defcomm.h +++ b/src/defcomm.h @@ -49,17 +49,21 @@ #define BANK_BAD_MEM (&g_dummy_memory1_ptr[0xff]) - -#define ENGINE_FCYCLES 0x00 -#define ENGINE_REG_KPC 0x08 -#define ENGINE_REG_ACC 0x0c -#define ENGINE_REG_XREG 0x10 -#define ENGINE_REG_YREG 0x14 -#define ENGINE_REG_STACK 0x18 -#define ENGINE_REG_DBANK 0x1c -#define ENGINE_REG_DIRECT 0x20 -#define ENGINE_REG_PSR 0x24 -#define ENGINE_FPLUS_PTR 0x28 +/* + * this is only relevant for the PA RISC asm. + * + */ +#define ENGINE_FPLUS_PTR 0x00 +#define ENGINE_FCYCLES 0x08 +#define ENGINE_REG_KPC 0x10 +#define ENGINE_REG_ACC 0x14 +#define ENGINE_REG_XREG 0x18 +#define ENGINE_REG_YREG 0x1c +#define ENGINE_REG_STACK 0x20 +#define ENGINE_REG_DBANK 0x24 +#define ENGINE_REG_DIRECT 0x28 +#define ENGINE_REG_PSR 0x2c +#define ENGINE_FLAGS 0x30 #define LOG_PC_DCYCS 0x00 #define LOG_PC_DBANK_KPC 0x08 @@ -77,20 +81,29 @@ #define FPLUS_PLUS_3 0x10 #define FPLUS_PLUS_X_M1 0x18 -#define RET_BREAK 0x1 +#define RET_BRK 0x1 #define RET_COP 0x2 #define RET_WDM 0x3 #define RET_MVP 0x4 #define RET_MVN 0x5 #define RET_WAI 0x6 #define RET_STP 0x7 -#define RET_ADD_DEC_8 0x8 -#define RET_ADD_DEC_16 0x9 +#define RET_HALT 0x8 #define RET_C700 0xa #define RET_C70A 0xb #define RET_C70D 0xc #define RET_IRQ 0xd +#define RET_BP 0xe +#define RET_MP 0xf +#define FLAG_IGNORE_MP 0x01 +#define FLAG_IGNORE_BP 0x02 +#define FLAG_STEP 0x04 +#define FLAG_WANT_BRK 0x08 +#define FLAG_WANT_COP 0x10 +#define FLAG_WANT_RET 0x20 +#define FLAG_WANT_JSL 0x40 +#define FLAG_IGNORE_BRK 0x80 /* and cop */ #define MODE_BORDER 0 #define MODE_TEXT 1 diff --git a/src/defs_instr.h b/src/defs_instr.h index 79257bc..b8a66e7 100644 --- a/src/defs_instr.h +++ b/src/defs_instr.h @@ -1055,14 +1055,14 @@ defs_instr_start_16 .word 0 # define TSB_INST(in_bank) \ tmp1 = arg | acc; \ CYCLES_PLUS_1; \ - zero = arg & acc; \ - SET_MEMORY8(addr_latch, tmp1); + SET_MEMORY8(addr_latch, tmp1); \ + zero = arg & acc; # else # define TSB_INST(in_bank) \ tmp1 = arg | acc; \ CYCLES_PLUS_1; \ - zero = arg & acc; \ - SET_MEMORY16(addr_latch, tmp1, in_bank); + SET_MEMORY16(addr_latch, tmp1, in_bank); \ + zero = arg & acc; # endif #endif @@ -1107,15 +1107,15 @@ defs_instr_start_16 .word 0 psr = (psr & 0x1fe) + ((arg >> 7) & 1); \ tmp1 = (arg << 1) & 0xff; \ CYCLES_PLUS_1; \ - SET_NEG_ZERO8(tmp1); \ - SET_MEMORY8(addr_latch, tmp1); + SET_MEMORY8(addr_latch, tmp1); \ + SET_NEG_ZERO8(tmp1); # else # define ASL_INST(in_bank) \ psr = (psr & 0x1fe) + ((arg >> 15) & 1);\ tmp1 = (arg << 1) & 0xffff; \ CYCLES_PLUS_1; \ - SET_NEG_ZERO16(tmp1); \ - SET_MEMORY16(addr_latch, tmp1, in_bank); + SET_MEMORY16(addr_latch, tmp1, in_bank);\ + SET_NEG_ZERO16(tmp1); # endif #endif @@ -1302,14 +1302,14 @@ defs_instr_start_16 .word 0 arg = arg & 0xff; \ tmp1 = arg & ~acc; \ CYCLES_PLUS_1; \ - zero = arg & acc; \ - SET_MEMORY8(addr_latch, tmp1); + SET_MEMORY8(addr_latch, tmp1); \ + zero = arg & acc; # else # define TRB_INST(in_bank) \ tmp1 = arg & ~acc; \ CYCLES_PLUS_1; \ - zero = arg & acc; \ - SET_MEMORY16(addr_latch, tmp1, in_bank); + SET_MEMORY16(addr_latch, tmp1, in_bank);\ + zero = arg & acc; # endif #endif diff --git a/src/dis.c b/src/dis.c deleted file mode 100644 index a84feb2..0000000 --- a/src/dis.c +++ /dev/null @@ -1,1125 +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) - */ - -#include -#include "defc.h" -#include - -#include "disas.h" - -#define LINE_SIZE 160 - -extern byte *g_memory_ptr; -extern byte *g_slow_memory_ptr; -extern int halt_sim; -extern int enter_debug; -extern int g_dbg_step; //debug.c -extern int timeout; //debug.c -extern int g_c068_statereg; -extern word32 stop_run_at; -extern int Verbose; -extern int Halt_on; - -extern int g_fullscreen; -extern int g_config_control_panel; - -int g_num_breakpoints = 0; -word32 g_breakpts[MAX_BREAK_POINTS]; - -extern int g_irq_pending; - -extern Engine_reg engine; - -#define W_BUF_LEN 128 -char w_buff[W_BUF_LEN]; - -int g_stepping = 0; - -word32 list_kpc; -int hex_line_len; -word32 a1,a2,a3; -word32 g_a4, g_a4bank; -int a1bank, a2bank, a3bank; -char *line_ptr; -int mode,old_mode; -int got_num; - -// OG replaced by HALT_WANTTOQUIT -//int g_quit_sim_now = 0; - -int get_num() { - int tmp1; - - a2 = 0; - got_num = 0; - while(1) { - if(mode == 0 && got_num != 0) { - a3 = a2; - a3bank = a2bank; - a1 = a2; - a1bank = a2bank; - } - tmp1 = *line_ptr++ & 0x7f; - if(tmp1 >= '0' && tmp1 <= '9') { - a2 = (a2 << 4) + tmp1 - '0'; - got_num = 1; - continue; - } - if(tmp1 >= 'a' && tmp1 <= 'f') { - a2 = (a2 << 4) + tmp1 - 'a' + 10; - got_num = 1; - continue; - } - if(tmp1 == '/') { - a2bank = a2; - a2 = 0; - continue; - } - return tmp1; - } -} - -void debugger_help() { - printf("GSplus Debugger Help (courtesy Fredric Devernay)\n\n"); - printf("General command syntax:\n"); - printf(" [bank]/[address][command]\n\n"); - printf("Example: > e1/0010B Set a Breakpoint at the interrupt jump pt\n\n"); - printf("Enter all addresses using lower-case.\n"); - printf("As with the IIgs monitor, you can omit the bank number after\n"); - printf("having set it: 'e1/0010B' followed by '14B' will set breakpoints\n"); - printf("at e1/0010 and e1/0014\n\n"); - printf(" g Go\n"); - printf(" [bank]/[addr]g Go from [bank]/[address]\n"); - printf(" s Step one instruction\n"); - printf(" [bank]/[addr]s Step one instr at [bank]/[address]\n"); - printf(" [bank]/[addr]B Set breakpoint at [bank]/[address]\n"); - printf(" B Show all breakpoints\n"); - printf(" [bank]/[addr]D Delete breakpoint at [bank]/[address]\n"); - printf(" [bank]/[addr].[addr2] View memory\n"); - printf(" [bank]/[addr]L Disassemble memory\n"); - printf(" P Dump the trace to 'pc_log_out'\n"); - printf(" Z Dump SCC state\n"); - printf(" I Dump IWM state\n"); - printf("[drive].[track]I Dump IWM state\n"); - printf(" E Dump Ensoniq state\n"); - printf(" [osc]E Dump oscillator [osc] state\n"); - printf(" R Dump dtime array and events\n"); - printf(" T Show toolbox log\n"); - printf(" [bank]/[addr]T Dump tools using ptr [bank]/[addr]\n"); - printf(" as 'tool_set_info'\n"); - printf(" [mode]V XOR verbose with 1=DISK, 2=IRQ,\n"); - printf(" 4=CLK,8=SHADOW,10=IWM,20=DOC,\n"); - printf(" 40=ABD,80=SCC, 100=TEST, 200=VIDEO\n"); - printf(" [mode]H XOR halt_on with 1=SCAN_INT,\n"); - printf(" 2=IRQ, 4=SHADOW_REG, 8=C70D_WRITES\n"); - printf(" r Reset\n"); - printf(" [0/1]=m Changes m bit for l listings\n"); - printf(" [0/1]=x Changes x bit for l listings\n"); - printf(" [t]=z Stops at absolute time t (obsolete)\n"); - printf(" S show_bankptr_bank0 & smartport errs\n"); - printf(" P show_pmhz\n"); - printf(" A show_a2_line_stuff show_adb_log\n"); - printf(" Ctrl-e Dump registers\n"); - printf("[bank]/[addr1].[addr2]us[file] Save mem area to [file]\n"); - printf("[bank]/[addr1].[addr2]ul[file] Load mem area from [file]\n"); - printf(" v Show video information\n"); - printf(" q Quit Debugger (and GSplus)\n"); -} - -void do_debug_intfc() { - char linebuf[LINE_SIZE]; - int slot_drive; - int track; - int osc; - int done; - int ret_val; - - g_config_control_panel = 1; - - hex_line_len = 0x10; - a1 = 0; a2 = 0; a3 = 0; g_a4 = 0; - a1bank = 0; a2bank = 0; a3bank = 0; g_a4bank = 0; - list_kpc = engine.kpc; - g_stepping = 0; - mode = 0; old_mode = 0; - done = 0; - stop_run_at = -1; - - x_auto_repeat_on(0); - g_fullscreen = 0; - x_full_screen(0); - - // OG use HALT_WANTTOQUIT instead of g_quit_sim_now - if (halt_sim&HALT_WANTTOQUIT) - { - printf("Exiting immediately\n"); - return; - } - - printf("Type 'h' for help\n"); - - while(!done) { - printf("> "); fflush(stdout); - if(read_line(linebuf,LINE_SIZE-1) <= 0) { - done = 1; - continue; - } - line_ptr = linebuf; - -/* - printf("input line: :%s:\n", linebuf); - printf("mode: %d\n", mode); - */ - mode = 0; - - while(*line_ptr != 0) { - ret_val = get_num(); -/* - printf("ret_val: %x, got_num= %d\n", ret_val, - got_num); - */ - old_mode = mode; - mode = 0; - switch(ret_val) { - case 'h': - debugger_help(); - break; - case 'R': - show_dtime_array(); - show_all_events(); - break; - case 'I': - slot_drive = -1; - track = -1; - if(got_num) { - if(old_mode == '.') { - slot_drive = a1; - } - track = a2; - } - iwm_show_track(slot_drive, track); - iwm_show_stats(); - break; - case 'E': - osc = -1; - if(got_num) { - osc = a2; - } - doc_show_ensoniq_state(osc); - break; - case 'T': - if(got_num) { - show_toolset_tables(a2bank, a2); - } else { - show_toolbox_log(); - } - break; - case 'v': - if(got_num) { - dis_do_compare(); - } else { - video_show_debug_info(); - } - break; - case 'V': - printf("g_irq_pending: %05x\n", g_irq_pending); - printf("Setting Verbose ^= %04x\n", a1); - Verbose ^= a1; - printf("Verbose is now: %04x\n", Verbose); - break; - case 'H': - printf("Setting Halt_on ^= %04x\n", a1); - Halt_on ^= a1; - printf("Halt_on is now: %04x\n", Halt_on); - break; - case 'r': - do_reset(); - list_kpc = engine.kpc; - break; - case 'm': - if(old_mode == '=') { - if(!a1) { - engine.psr &= ~0x20; - } else { - engine.psr |= 0x20; - } - if(engine.psr & 0x100) { - engine.psr |= 0x30; - } - } else { - dis_do_memmove(); - } - break; - case 'p': - dis_do_pattern_search(); - break; - case 'x': - if(old_mode == '=') { - if(!a1) { - engine.psr &= ~0x10; - } else { - engine.psr |= 0x10; - } - if(engine.psr & 0x100) { - engine.psr |= 0x30; - } - } - break; - case 'z': - if(old_mode == '=') { - stop_run_at = a1; - printf("Calling add_event for t:%08x\n", - a1); - add_event_stop((double)a1); - printf("set stop_run_at = %x\n", a1); - } - break; - case 'l': case 'L': - do_debug_list(); - break; - case 'Z': - show_scc_log(); - show_scc_state(); - break; - case 'S': - show_bankptrs_bank0rdwr(); - smartport_error(); - break; - case 'C': - show_xcolor_array(); - break; - case 'P': - show_pc_log(); - break; - case 'M': - show_pmhz(); - break; - case 'A': - show_a2_line_stuff(); - show_adb_log(); - break; - case 's': - g_stepping = 1; - if(got_num) { - engine.kpc = (a2bank<<16) + (a2&0xffff); - } - mode = 's'; - list_kpc = engine.kpc; - break; - case 'B': - if(got_num) { - printf("got_num: %d, a2bank: %x, a2: %x\n", got_num, a2bank, a2); - set_bp((a2bank << 16) + a2); - } else { - show_bp(); - } - break; - case 'D': - if(got_num) { - printf("got_num: %d, a2bank: %x, a2: %x\n", got_num, a2bank, a2); - delete_bp((a2bank << 16) + a2); - } - break; - case 'g': - case 'G': - printf("Going..\n"); - g_stepping = 0; - if(got_num) { - engine.kpc = (a2bank<<16) + (a2&0xffff); - } - do_go(); - list_kpc = engine.kpc; - break; - case 'q': - case 'Q': - printf("Exiting debugger\n"); - return; - break; - case 'u': - printf("Unix commands\n"); - do_debug_unix(); - break; - case ':': case '.': - case '+': case '-': - case '=': case ',': - mode = ret_val; - printf("Setting mode = %x\n", mode); - break; - case ' ': case '\t': - if(!got_num) { - mode = old_mode; - break; - } - do_blank(); - break; - case '<': - g_a4 = a2; - g_a4bank = a2bank; - break; - case 0x05: /* ctrl-e */ - show_regs(); - break; - case '\n': - case '\r': - *line_ptr = 0; - if(old_mode == 's') { - do_blank(); - break; - } - if(line_ptr == &linebuf[1]) { - a2 = a1 | (hex_line_len - 1); - show_hex_mem(a1bank,a1,a2bank,a2, -1); - a1 = a2 + 1; - } else { - if(got_num == 1 || mode == 's') { - do_blank(); - } - } - break; - case 'w': - read_line(w_buff, W_BUF_LEN); - break; - default: - printf("\nUnrecognized command: %s\n",linebuf); - *line_ptr = 0; - break; - } - } - - } - printf("Console closed.\n"); -} - -word32 dis_get_memory_ptr(word32 addr) { - word32 tmp1, tmp2, tmp3; - - tmp1 = get_memory_c(addr, 0); - tmp2 = get_memory_c(addr + 1, 0); - tmp3 = get_memory_c(addr + 2, 0); - - return (tmp3 << 16) + (tmp2 << 8) + tmp1; -} - -void show_one_toolset(FILE *toolfile, int toolnum, word32 addr) { - word32 rout_addr; - int num_routs; - int i; - - num_routs = dis_get_memory_ptr(addr); - fprintf(toolfile, "Tool 0x%02x, table: 0x%06x, num_routs:%03x\n", - toolnum, addr, num_routs); - - for(i = 1; i < num_routs; i++) { - rout_addr = dis_get_memory_ptr(addr + 4*i); - fprintf(toolfile, "%06x = %02x%02x\n", rout_addr, i, toolnum); - } -} - -void show_toolset_tables(word32 a2bank, word32 addr) { - FILE *toolfile; - word32 tool_addr; - int num_tools; - int i; - - addr = (a2bank << 16) + (addr & 0xffff); - - toolfile = fopen("tool_set_info", "w"); - if(toolfile == 0) { - fprintf(stderr, "fopen of tool_set_info failed: %d\n", errno); - exit(2); - } - - num_tools = dis_get_memory_ptr(addr); - fprintf(toolfile, "There are 0x%02x tools using ptr at %06x\n", - num_tools, addr); - - for(i = 1; i < num_tools; i++) { - tool_addr = dis_get_memory_ptr(addr + 4*i); - show_one_toolset(toolfile, i, tool_addr); - } - - fclose(toolfile); -} - -void set_bp(word32 addr) { - int count; - - printf("About to set BP at %06x\n", addr); - count = g_num_breakpoints; - if(count >= MAX_BREAK_POINTS) { - printf("Too many (0x%02x) breakpoints set!\n", count); - return; - } - - g_breakpts[count] = addr; - g_num_breakpoints = count + 1; - fixup_brks(); -} - -void show_bp() { - int i; - - printf("Showing breakpoints set\n"); - for(i = 0; i < g_num_breakpoints; i++) { - printf("bp:%02x: %06x\n", i, g_breakpts[i]); - } -} - -void delete_bp(word32 addr) { - int count; - int hit; - int i; - - printf("About to delete BP at %06x\n", addr); - count = g_num_breakpoints; - - hit = -1; - for(i = 0; i < count; i++) { - if(g_breakpts[i] == addr) { - hit = i; - break; - } - } - - if(hit < 0) { - printf("Breakpoint not found!\n"); - } else { - printf("Deleting brkpoint #0x%02x\n", hit); - for(i = hit+1; i < count; i++) { - g_breakpts[i-1] = g_breakpts[i]; - } - g_num_breakpoints = count - 1; - setup_pageinfo(); - } - - show_bp(); -} - -void do_blank() { - int tmp, i; - - switch(old_mode) { - case 's': - tmp = a2; - if(tmp == 0) tmp = 1; - enter_debug = 0; - for(i = 0; i < tmp; i++) { - g_stepping = 1; - do_step(); - if(enter_debug || halt_sim != 0) { - if(halt_sim != HALT_EVENT) { - break; - } - } - } - list_kpc = engine.kpc; - /* video_update_through_line(262); */ - break; - case ':': - set_memory_c(((a3bank << 16) + a3), a2, 0); - a3++; - mode = old_mode; - break; - case '.': - case 0: - xam_mem(-1); - break; - case ',': - xam_mem(16); - break; - case '+': - printf("%x\n", a1 + a2); - break; - case '-': - printf("%x\n", a1 - a2); - break; - default: - printf("Unknown mode at space: %d\n", old_mode); - break; - } -} - - -/* also called by do_step */ -void do_go() { - g_config_control_panel = 0; - clear_halt(); - run_prog(); - show_regs(); - g_config_control_panel = 1; -} - -void do_step() { - int size; - int size_mem_imm, size_x_imm; - - // run an instruction - do_go(); - - // check accumulator size - size_mem_imm = 2; - if(engine.psr & 0x20) { - size_mem_imm = 1; - } - // check xy size - size_x_imm = 2; - if(engine.psr & 0x10) { - size_x_imm = 1; - } - // then disassemble - size = do_dis(stdout, engine.kpc, size_mem_imm, size_x_imm, 0, 0); -} - -void xam_mem(int count) { - show_hex_mem(a1bank, a1, a2bank, a2, count); - a1 = a2 + 1; -} - -void show_hex_mem(int startbank, word32 start, int endbank, word32 end, int count) { - char ascii[MAXNUM_HEX_PER_LINE]; - word32 i; - int val, offset; - - if(count < 0) { - count = 16 - (start & 0xf); - } - - offset = 0; - ascii[0] = 0; - printf("Showing hex mem: bank: %x, start: %x, end: %x\n", - startbank, start, end); - for(i = start; i <= end; i++) { - if( (i==start) || (count == 16) ) { - printf("%04x:",i); - } - printf(" %02x", get_memory_c((startbank <<16) + i, 0)); - val = get_memory_c((startbank << 16) + i, 0) & 0x7f; - if(val < 32 || val >= 0x7f) { - val = '.'; - } - ascii[offset++] = val; - ascii[offset] = 0; - count--; - if(count <= 0) { - printf(" %s\n", ascii); - offset = 0; - ascii[0] = 0; - count = 16; - } - } - if(offset > 0) { - printf(" %s\n", ascii); - } -} - - -int read_line(char *buf, int len) { - int space_left; - int ret; -#if !defined(_WIN32) - int flags, flags_save; - - /* Unix */ - flags = fcntl(0, F_GETFL, 0); - flags_save = flags; - if(flags == -1) { - return 0; - } - ret = fcntl(0, F_SETFL, flags | O_NONBLOCK); - if(ret == -1) { - return 0; - } -#endif - space_left = len; - - buf[0] = 0; - ret = 0; - while(space_left > 0) { -#if defined(_WIN32) && !defined(WIN_SDL) - - ret = win_nonblock_read_stdin(0, buf, 1); -#else - /* Unix */ - ret = read(0, buf, 1); -#endif - if(ret <= 0) { - micro_sleep(15.0/60.0); - if(errno == EAGAIN) { - /* it would block, so no chars--do update */ - video_update(); - ret = 0; - continue; - } - printf("read ret %d, errno: %d\n", ret, errno); - if(errno == EAGAIN || errno == EINTR) { - ret = 0; - continue; - } - break; - } - space_left -= ret; - if(buf[ret-1] == '\r' || buf[ret-1] == '\n') { - break; - } - buf = &buf[ret]; - } -#if !defined(_WIN32) - (void)fcntl(0, F_SETFL, flags_save); -#endif - - return (len-space_left); -} - -void do_debug_list() { - int i; - int size; - int size_mem_imm, size_x_imm; - - if(got_num) { - list_kpc = (a2bank << 16) + (a2 & 0xffff); - } - printf("%d=m %d=x %d=LCBANK\n", (engine.psr >> 5)&1, - (engine.psr >> 4) & 1, (g_c068_statereg & 0x4) >> 2); - - size_mem_imm = 2; - if(engine.psr & 0x20) { - size_mem_imm = 1; - } - size_x_imm = 2; - if(engine.psr & 0x10) { - size_x_imm = 1; - } - for(i=0; i<20; i++) { - size = do_dis(stdout, list_kpc, size_mem_imm, - size_x_imm, 0, 0); - list_kpc += size; - } -} - -void dis_do_memmove() { - word32 val; - - printf("Memory move from %02x/%04x.%04x to %02x/%04x\n", a1bank, a1, a2, g_a4bank, g_a4); - while(a1 <= (a2 & 0xffff)) { - val = get_memory_c((a1bank << 16) + a1, 0); - set_memory_c((g_a4bank << 16) + g_a4, val, 0); - a1++; - g_a4++; - } - a1 = a1 & 0xffff; - g_a4 = g_a4 & 0xffff; -} - -void dis_do_pattern_search() { - printf("Memory pattern search for %04x in %02x/%04x.%04x\n", g_a4, a1bank, a1, a2); -} - -void dis_do_compare() { - word32 val1, val2; - - printf("Memory Compare from %02x/%04x.%04x with %02x/%04x\n", a1bank, a1, a2, g_a4bank, g_a4); - while(a1 <= (a2 & 0xffff)) { - val1 = get_memory_c((a1bank << 16) + a1, 0); - val2 = get_memory_c((g_a4bank << 16) + g_a4, 0); - if(val1 != val2) { - printf("%02x/%04x: %02x vs %02x\n", a1bank, a1, val1, val2); - } - a1++; - g_a4++; - } - a1 = a1 & 0xffff; - g_a4 = g_a4 & 0xffff; -} - -void do_debug_unix() { - char localbuf[LINE_SIZE]; - word32 offset, len; - int fd, ret; - int load, save; - int i; - - load = 0; save = 0; - switch(*line_ptr++) { - case 'l': case 'L': - printf("Loading.."); - load = 1; - break; - case 's': case 'S': - printf("Saving..."); - save = 1; - break; - default: - printf("Unknown unix command: %c\n", *(line_ptr-1)); - *line_ptr = 0; - return; - } - while(*line_ptr == ' ' || *line_ptr == '\t') { - line_ptr++; - } - i = 0; - while(i < LINE_SIZE) { - localbuf[i++] = *line_ptr++; - if(*line_ptr==' ' || *line_ptr=='\t' || *line_ptr == '\n') { - break; - } - } - localbuf[i] = 0; - - - printf("About to open: %s,len: %d\n", localbuf, (int)strlen(localbuf)); - if(load) { - fd = open(localbuf,O_RDONLY | O_BINARY); - } else { - fd = open(localbuf,O_WRONLY | O_CREAT | O_BINARY, 0x1b6); - } - if(fd < 0) { - printf("Open %s failed: %d\n", localbuf, fd); - printf("errno: %d\n", errno); - return; - } - if(load) { - offset = a1 & 0xffff; - len = 0x20000 - offset; - } else { - if(old_mode == '.') { - len = a2 - a1 + 1; - } else { - len = 0x100; - } - } - if(load) { - if(a1bank >= 0xe0 && a1bank < 0xe2) { - ret = read(fd,(char*)&g_slow_memory_ptr[((a1bank & 1)<<16)+a1],len); - } else { - ret = read(fd,(char*)&g_memory_ptr[(a1bank << 16) + a1],len); - } - } else { - if(a1bank >= 0xe0 && a1bank < 0xe2) { - ret = write(fd,(char*)&g_slow_memory_ptr[((a1bank & 1)<<16)+a1],len); - } else { - ret = write(fd,(char*)&g_memory_ptr[(a1bank << 16) + a1],len); - } - } - printf("Read/write: addr %06x for %04x bytes, ret: %x bytes\n", - (a1bank << 16) + a1, len, ret); - if(ret < 0) { - printf("errno: %d\n", errno); - } - a1 = a1 + ret; -} - -void do_debug_load() { - printf("Sorry, can't load now\n"); -} - - -int do_dis(FILE *outfile, word32 kpc, int accsize, int xsize, - int op_provided, word32 instr) { - char buffer[150]; - const char *out; - int args, type; - int opcode; - word32 val; - word32 oldkpc; - word32 dtype; - int signed_val; - - oldkpc = kpc; - if(op_provided) { - opcode = (instr >> 24) & 0xff; - } else { - opcode = (int)get_memory_c(kpc, 0) & 0xff; - } - - kpc++; - - dtype = disas_types[opcode]; - out = disas_opcodes[opcode]; - type = dtype & 0xff; - args = dtype >> 8; - - if(args > 3) { - if(args == 4) { - args = accsize; - } else if(args == 5) { - args = xsize; - } - } - - val = -1; - switch(args) { - case 0: - val = 0; - break; - case 1: - if(op_provided) { - val = instr & 0xff; - } else { - val = get_memory_c(kpc, 0); - } - break; - case 2: - if(op_provided) { - val = instr & 0xffff; - } else { - val = get_memory16_c(kpc, 0); - } - break; - case 3: - if(op_provided) { - val = instr & 0xffffff; - } else { - val = get_memory24_c(kpc, 0); - } - break; - default: - fprintf(stderr, "args out of rang: %d, opcode: %08x\n", - args, opcode); - break; - } - kpc += args; - - if(!op_provided) { - instr = (opcode << 24) | (val & 0xffffff); - } - - switch(type) { - case ABS: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%04x",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case ABSX: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%04x,X",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case ABSY: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%04x,Y",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case ABSLONG: - if(args != 3) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%06x",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case ABSIND: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t($%04x)",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case ABSXIND: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t($%04x,X)",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case IMPLY: - if(args != 0) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s",out); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case ACCUM: - if(args != 0) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s",out); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case IMMED: - if(args == 1) { - sprintf(buffer,"%s\t#$%02x",out,val); - } else if(args == 2) { - sprintf(buffer,"%s\t#$%04x",out,val); - } else { - printf("arg # mismatch for opcode %x\n", opcode); - } - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case JUST8: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%02x",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOC: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%02x",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOCX: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%02x,X",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOCY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%02x,Y",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case LONG: - if(args != 3) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%06x",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case LONGX: - if(args != 3) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%06x,X",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOCIND: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t($%02x)",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOCINDY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t($%02x),Y",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOCXIND: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t($%02x,X)",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOCBRAK: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t[$%02x]",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DLOCBRAKY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t[$%02x],y",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DISP8: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - signed_val = (signed char)val; - sprintf(buffer,"%s\t$%04x",out, - (word32)(kpc+(signed_val)) & 0xffff); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DISP8S: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%02x,S",out,(word32)(byte)(val)); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DISP8SINDY: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t($%02x,S),Y",out,(word32)(byte)(val)); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case DISP16: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%04x", out, - (word32)(kpc+(signed)(word16)(val)) & 0xffff); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case MVPMVN: - if(args != 2) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t$%02x,$%02x",out,val&0xff,val>>8); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - case SEPVAL: - case REPVAL: - if(args != 1) { - printf("arg # mismatch for opcode %x\n", opcode); - } - sprintf(buffer,"%s\t#$%02x",out,val); - show_line(outfile, oldkpc,instr,args+1,buffer); - break; - default: - printf("argument type: %d unexpected\n", type); - break; - } - - return(args+1); -} - -void show_line(FILE *outfile, word32 kaddr, word32 operand, int size, - char *string) { - int i; - int opcode; - - fprintf(outfile, "%02x/%04x: ", kaddr >> 16, kaddr & 0xffff); - opcode = (operand >> 24) & 0xff; - fprintf(outfile,"%02x ", opcode); - - for(i=1; i> 8; - } - for(; i<5; i++) { - fprintf(outfile, " "); - } - fprintf(outfile,"%s\n", string); -} - -void halt_printf(const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - - set_halt(1); -} - -void halt2_printf(const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - - set_halt(2); -} diff --git a/src/disas.h b/src/disasm.c similarity index 85% rename from src/disas.h rename to src/disasm.c index 112d816..91c0082 100644 --- a/src/disas.h +++ b/src/disasm.c @@ -1,42 +1,7 @@ -/* - 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) -*/ -enum { - ABS = 1, - ABSX, - ABSY, - ABSLONG, - ABSIND, - ABSXIND, - IMPLY, - ACCUM, - IMMED, - JUST8, - DLOC, - DLOCX, - DLOCY, - LONG, - LONGX, - DLOCIND, - DLOCINDY, - DLOCXIND, - DLOCBRAK, - DLOCBRAKY, - DISP8, - DISP8S, - DISP8SINDY, - DISP16, - MVPMVN, - REPVAL, - SEPVAL -}; +#include "disasm.h" - -const char * const disas_opcodes[256] = { +const char * const disasm_opcodes[256] = { "BRK", "ORA", "COP", "ORA", "TSB", "ORA", "ASL", "ORA", /* 00-07 */ "PHP", "ORA", "ASL", "PHD", "TSB", "ORA", "ASL", "ORA", /* 08-0f */ "BPL", "ORA", "ORA", "ORA", "TRB", "ORA", "ASL", "ORA", /* 10-17 */ @@ -72,7 +37,7 @@ const char * const disas_opcodes[256] = { }; -const word32 disas_types[256] = { +const unsigned disasm_types[256] = { JUST8+0x100, DLOCXIND+0x100, /* 00-01 */ JUST8+0x100, DISP8S+0x100, /* 02-03 */ DLOC+0x100, DLOC+0x100, /* 04-05 */ @@ -80,7 +45,7 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* 08-9 */ ACCUM+0x000, IMPLY+0x000, /* 0a-b */ ABS+0x200, ABS+0x200, /* c-d */ - ABS+0x200, LONG+0x300, /* e-f */ + ABS+0x200, ABSLONG+0x300, /* e-f */ DISP8+0x100, DLOCINDY+0x100, /* 10-11 */ DLOCIND+0x100, DISP8SINDY+0x100, /* 12-13 */ DLOC+0x100, DLOCX+0x100, /* 14-15 */ @@ -88,7 +53,7 @@ const word32 disas_types[256] = { IMPLY+0x000, ABSY+0x200, /* 18-19 */ ACCUM+0x000, IMPLY+0x000, /* 1a-1b */ ABS+0x200, ABSX+0x200, /* 1c-1d */ - ABSX+0x200, LONGX+0x300, /* 1e-1f */ + ABSX+0x200, ABSLONGX+0x300, /* 1e-1f */ ABS+0x200, DLOCXIND+0x100, /* 20-21 */ ABSLONG+0x300, DISP8S+0x100, /* 22-23 */ DLOC+0x100, DLOC+0x100, /* 24-25 */ @@ -96,7 +61,7 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* 28-29 */ ACCUM+0x000, IMPLY+0x000, /* 2a-2b */ ABS+0x200, ABS+0x200, /* 2c-2d */ - ABS+0x200, LONG+0x300, /* 2e-2f */ + ABS+0x200, ABSLONG+0x300, /* 2e-2f */ DISP8+0x100, DLOCINDY+0x100, /* 30-31 */ DLOCIND+0x100, DISP8SINDY+0x100, /* 32-33 */ DLOCX+0x100, DLOCX+0x100, /* 34-35 */ @@ -104,7 +69,7 @@ const word32 disas_types[256] = { IMPLY+0x000, ABSY+0x200, /* 38-39 */ ACCUM+0x000, IMPLY+0x000, /* 3a-3b */ ABSX+0x200, ABSX+0x200, /* 3c-3d */ - ABSX+0x200, LONGX+0x300, /* 3e-3f */ + ABSX+0x200, ABSLONGX+0x300, /* 3e-3f */ IMPLY+0x000, DLOCXIND+0x100, /* 40-41 */ JUST8+0x100, DISP8S+0x100, /* 42-43 */ MVPMVN+0x200, DLOC+0x100, /* 44-45 */ @@ -112,15 +77,15 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* 48-49 */ ACCUM+0x000, IMPLY+0x000, /* 4a-4b */ ABS+0x200, ABS+0x200, /* 4c-4d */ - ABS+0x200, LONG+0x300, /* 4e-4f */ + ABS+0x200, ABSLONG+0x300, /* 4e-4f */ DISP8+0x100, DLOCINDY+0x100, /* 50-51 */ DLOCIND+0x100, DISP8SINDY+0x100, /* 52-53 */ MVPMVN+0x200, DLOCX+0x100, /* 54-55 */ DLOCX+0x100, DLOCBRAKY+0x100, /* 56-57 */ IMPLY+0x000, ABSY+0x200, /* 58-59 */ IMPLY+0x000, IMPLY+0x000, /* 5a-5b */ - LONG+0x300, ABSX+0x200, /* 5c-5d */ - ABSX+0x200, LONGX+0x300, /* 5e-5f */ + ABSLONG+0x300, ABSX+0x200, /* 5c-5d */ + ABSX+0x200, ABSLONGX+0x300, /* 5e-5f */ IMPLY+0x000, DLOCXIND+0x100, /* 60-61 */ DISP16+0x200, DISP8S+0x100, /* 62-63 */ DLOC+0x100, DLOC+0x100, /* 64-65 */ @@ -128,7 +93,7 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* 68-69 */ ACCUM+0x000, IMPLY+0x000, /* 6a-6b */ ABSIND+0x200, ABS+0x200, /* 6c-6d */ - ABS+0x200, LONG+0x300, /* 6e-6f */ + ABS+0x200, ABSLONG+0x300, /* 6e-6f */ DISP8+0x100, DLOCINDY+0x100, /* 70-71 */ DLOCIND+0x100, DISP8SINDY+0x100, /* 72-73 */ DLOCX+0x100, DLOCX+0x100, /* 74-75 */ @@ -136,7 +101,7 @@ const word32 disas_types[256] = { IMPLY+0x000, ABSY+0x200, /* 78-79 */ IMPLY+0x000, IMPLY+0x000, /* 7a-7b */ ABSXIND+0x200, ABSX+0x200, /* 7c-7d */ - ABSX+0x200, LONGX+0x300, /* 7e-7f */ + ABSX+0x200, ABSLONGX+0x300, /* 7e-7f */ DISP8+0x100, DLOCXIND+0x100, /* 80-81 */ DISP16+0x200, DISP8S+0x100, /* 82-83 */ DLOC+0x100, DLOC+0x100, /* 84-85 */ @@ -144,7 +109,7 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* 88-89 */ IMPLY+0x000, IMPLY+0x000, /* 8a-8b */ ABS+0x200, ABS+0x200, /* 8c-8d */ - ABS+0x200, LONG+0x300, /* 8e-8f */ + ABS+0x200, ABSLONG+0x300, /* 8e-8f */ DISP8+0x100, DLOCINDY+0x100, /* 90-91 */ DLOCIND+0x100, DISP8SINDY+0x100, /* 92-93 */ DLOCX+0x100, DLOCX+0x100, /* 94-95 */ @@ -152,7 +117,7 @@ const word32 disas_types[256] = { IMPLY+0x000, ABSY+0x200, /* 98-99 */ IMPLY+0x000, IMPLY+0x000, /* 9a-9b */ ABS+0x200, ABSX+0x200, /* 9c-9d */ - ABSX+0x200, LONGX+0x300, /* 9e-9f */ + ABSX+0x200, ABSLONGX+0x300, /* 9e-9f */ IMMED+0x500, DLOCXIND+0x100, /* a0-a1 */ IMMED+0x500, DISP8S+0x100, /* a2-a3 */ DLOC+0x100, DLOC+0x100, /* a4-a5 */ @@ -160,7 +125,7 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* a8-a9 */ IMPLY+0x000, IMPLY+0x000, /* aa-ab */ ABS+0x200, ABS+0x200, /* ac-ad */ - ABS+0x200, LONG+0x300, /* ae-af */ + ABS+0x200, ABSLONG+0x300, /* ae-af */ DISP8+0x100, DLOCINDY+0x100, /* b0-b1 */ DLOCIND+0x100, DISP8SINDY+0x100, /* b2-b3 */ DLOCX+0x100, DLOCX+0x100, /* b4-b5 */ @@ -168,7 +133,7 @@ const word32 disas_types[256] = { IMPLY+0x000, ABSY+0x200, /* b8-b9 */ IMPLY+0x000, IMPLY+0x000, /* ba-bb */ ABSX+0x200, ABSX+0x200, /* bc-bd */ - ABSY+0x200, LONGX+0x300, /* be-bf */ + ABSY+0x200, ABSLONGX+0x300, /* be-bf */ IMMED+0x500, DLOCXIND+0x100, /* c0-c1 */ REPVAL+0x100, DISP8S+0x100, /* c2-c3 */ DLOC+0x100, DLOC+0x100, /* c4-c5 */ @@ -176,7 +141,7 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* c8-c9 */ IMPLY+0x000, IMPLY+0x000, /* ca-cb */ ABS+0x200, ABS+0x200, /* cc-cd */ - ABS+0x200, LONG+0x300, /* ce-cf */ + ABS+0x200, ABSLONG+0x300, /* ce-cf */ DISP8+0x100, DLOCINDY+0x100, /* d0-d1 */ DLOCIND+0x100, DISP8SINDY+0x100, /* d2-d3 */ DLOC+0x100, DLOCX+0x100, /* d4-d5 */ @@ -184,7 +149,7 @@ const word32 disas_types[256] = { IMPLY+0x000, ABSY+0x200, /* d8-d9 */ IMPLY+0x000, IMPLY+0x000, /* da-db */ ABSIND+0x200, ABSX+0x200, /* dc-dd */ - ABSX+0x200, LONGX+0x300, /* de-df */ + ABSX+0x200, ABSLONGX+0x300, /* de-df */ IMMED+0x500, DLOCXIND+0x100, /* e0-e1 */ SEPVAL+0x100, DISP8S+0x100, /* e2-e3 */ DLOC+0x100, DLOC+0x100, /* e4-e5 */ @@ -192,7 +157,7 @@ const word32 disas_types[256] = { IMPLY+0x000, IMMED+0x400, /* e8-e9 */ IMPLY+0x000, IMPLY+0x000, /* ea-eb */ ABS+0x200, ABS+0x200, /* ec-ed */ - ABS+0x200, LONG+0x300, /* ee-ef */ + ABS+0x200, ABSLONG+0x300, /* ee-ef */ DISP8+0x100, DLOCINDY+0x100, /* f0-f1 */ DLOCIND+0x100, DISP8SINDY+0x100, /* f2-f3 */ IMMED+0x200, DLOCX+0x100, /* f4-f5 */ @@ -200,5 +165,5 @@ const word32 disas_types[256] = { IMPLY+0x000, ABSY+0x200, /* f8-f9 */ IMPLY+0x000, IMPLY+0x000, /* fa-fb */ ABSXIND+0x200, ABSX+0x200, /* fc-fd */ - ABSX+0x200, LONGX+0x300, /* fe-ff */ + ABSX+0x200, ABSLONGX+0x300, /* fe-ff */ }; diff --git a/src/disasm.h b/src/disasm.h new file mode 100644 index 0000000..3c437fd --- /dev/null +++ b/src/disasm.h @@ -0,0 +1,41 @@ +/* + 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) +*/ + +enum { + ABS = 1, + ABSX, + ABSY, + ABSIND, + ABSXIND, + IMPLY, + ACCUM, + IMMED, + JUST8, + DLOC, + DLOCX, + DLOCY, + ABSLONG, + ABSLONGX, + DLOCIND, + DLOCINDY, + DLOCXIND, + DLOCBRAK, + DLOCBRAKY, + DISP8, + DISP8S, + DISP8SINDY, + DISP16, + MVPMVN, + REPVAL, + SEPVAL +}; + + +extern const char * const disasm_opcodes[256]; + + +extern const unsigned disasm_types[256]; \ No newline at end of file diff --git a/src/engine_c.c b/src/engine_c.c index 9372be2..72c2342 100644 --- a/src/engine_c.c +++ b/src/engine_c.c @@ -24,7 +24,6 @@ # define FCYCS_PTR_FCYCLES_ROUND_SLOW #endif -extern int g_dbg_step; extern int halt_sim; extern int g_code_red; extern int g_ignore_halts; @@ -53,9 +52,6 @@ extern byte *g_rom_fc_ff_ptr_allocated; extern byte *g_rom_cards_ptr_allocated; extern byte *g_dummy_memory1_ptr_allocated; -extern int g_num_breakpoints; -extern word32 g_breakpts[]; - extern Pc_log *g_log_pc_ptr; extern Pc_log *g_log_pc_start_ptr; extern Pc_log *g_log_pc_end_ptr; @@ -156,7 +152,7 @@ extern word32 slow_mem_changed[]; stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \ wstat = PTR2WORD(stat) & 0xff; \ ptr = stat - wstat + ((addr) & 0xff); \ - if(wstat & (1 << (31 - BANK_IO_BIT)) || iostrobe == 1) { \ + if(wstat & BANK_IO_TMP || iostrobe == 1) { \ fcycles_tmp1 = fcycles; \ dest = get_memory8_io_stub((addr), stat, \ &fcycles_tmp1, fplus_x_m1); \ @@ -172,7 +168,7 @@ extern word32 slow_mem_changed[]; stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \ wstat = PTR2WORD(stat) & 0xff; \ ptr = stat - wstat + ((addr) & 0xff); \ - if((wstat & (1 << (31 - BANK_IO_BIT))) || (((addr) & 0xff) == 0xff)) { \ + if((wstat & BANK_IO_TMP) || (((addr) & 0xff) == 0xff)) { \ fcycles_tmp1 = fcycles; \ dest = get_memory16_pieces_stub((addr), stat, \ &fcycles_tmp1, fplus_ptr, in_bank); \ @@ -188,7 +184,7 @@ extern word32 slow_mem_changed[]; stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \ wstat = PTR2WORD(stat) & 0xff; \ ptr = stat - wstat + ((addr) & 0xff); \ - if((wstat & (1 << (31 - BANK_IO_BIT))) || (((addr) & 0xfe) == 0xfe)) { \ + if((wstat & BANK_IO_TMP) || (((addr) & 0xfe) == 0xfe)) { \ fcycles_tmp1 = fcycles; \ dest = get_memory24_pieces_stub((addr), stat, \ &fcycles_tmp1, fplus_ptr, in_bank); \ @@ -218,43 +214,77 @@ extern word32 slow_mem_changed[]; GET_MEMORY16(save_addr, dest, 1); \ } +/* + _ macros do not do any MMU checking +*/ -#define PUSH8(arg) \ - SET_MEMORY8(stack, arg); \ +#if 1 +#define MMU_CHECK(addr, val, bytes, in_page, in_bank) \ + if (abort_support && check_mp_breakpoints(addr, val, bytes, in_page, in_bank)) { \ + g_ret1 = RET_MP; \ + g_ret2 = saved_pc; \ + kpc = saved_pc; \ + psr = saved_psr; \ + goto finish; \ + } +#else +#define MMU_CHECK(addr, val, bytes, in_page, in_bank) +#endif +#define PUSH8(arg) \ + MMU_CHECK(stack, arg, 1, 0, 0) \ + _PUSH8(arg) \ + +#define _PUSH8(arg) \ + _SET_MEMORY8(stack, arg); \ stack--; \ if(psr & 0x100) { \ - stack = 0x100 | (stack & 0xff); \ + stack = 0x100 | (stack & 0xff); \ } \ stack = stack & 0xffff; -#define PUSH16(arg) \ +#define PUSH16(arg) \ + tmp2 = stack - 1; \ + if (psr >> 8) tmp2 = (tmp2 & 0xff) | 0x0100; \ + tmp2 &= 0xffff; \ + MMU_CHECK(tmp2, arg, 2, psr >> 8, 1) \ + _PUSH16(arg) + +#define _PUSH16(arg) \ if((stack & 0xfe) == 0) { \ /* stack will cross page! */ \ - PUSH8((arg) >> 8); \ - PUSH8(arg); \ + _PUSH8((arg) >> 8); \ + _PUSH8(arg); \ } else { \ stack -= 2; \ stack = stack & 0xffff; \ - SET_MEMORY16(stack + 1, arg, 1); \ + _SET_MEMORY16(stack + 1, arg, 1); \ } -#define PUSH16_UNSAFE(arg) \ +#define PUSH16_UNSAFE(arg) \ + MMU_CHECK((stack - 1) & 0xffff, arg, 2, 0, 1) \ + _PUSH16_UNSAFE(arg) + +#define _PUSH16_UNSAFE(arg) \ save_addr = (stack - 1) & 0xffff; \ stack -= 2; \ if(psr & 0x100) { \ - stack = 0x100 | (stack & 0xff); \ + stack = 0x100 | (stack & 0xff); \ } \ stack = stack & 0xffff; \ - SET_MEMORY16(save_addr, arg, 1); + _SET_MEMORY16(save_addr, arg, 1); -#define PUSH24_UNSAFE(arg) \ +#define PUSH24_UNSAFE(arg) \ + MMU_CHECK((stack - 2) & 0xffff, arg, 3, 0, 1) \ + _PUSH24_UNSAFE(arg) + +#define _PUSH24_UNSAFE(arg) \ save_addr = (stack - 2) & 0xffff; \ stack -= 3; \ if(psr & 0x100) { \ - stack = 0x100 | (stack & 0xff); \ + stack = 0x100 | (stack & 0xff); \ } \ stack = stack & 0xffff; \ - SET_MEMORY24(save_addr, arg, 1); + _SET_MEMORY24(save_addr, arg, 1); #define PULL8(dest) \ stack++; \ @@ -303,7 +333,11 @@ extern word32 slow_mem_changed[]; } \ } -#define SET_MEMORY8(addr, val) \ +#define SET_MEMORY8(addr, val) \ + MMU_CHECK(addr, val, 1, 0, 0) \ + _SET_MEMORY8(addr, val) + +#define _SET_MEMORY8(addr, val) \ LOG_DATA_MACRO(addr, val, 8); \ CYCLES_PLUS_1; \ stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \ @@ -318,8 +352,12 @@ extern word32 slow_mem_changed[]; *ptr = val; \ } +#define SET_MEMORY16(addr, val, in_bank) \ + MMU_CHECK(addr, val, 2, 0, in_bank) \ + _SET_MEMORY16(addr, val, in_bank) -#define SET_MEMORY16(addr, val, in_bank) \ + +#define _SET_MEMORY16(addr, val, in_bank) \ LOG_DATA_MACRO(addr, val, 16); \ stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \ wstat = PTR2WORD(stat) & 0xff; \ @@ -335,7 +373,12 @@ extern word32 slow_mem_changed[]; ptr[1] = (val) >> 8; \ } -#define SET_MEMORY24(addr, val, in_bank) \ +#define SET_MEMORY24(addr, val, in_bank) \ + MMU_CHECK(addr, val, 3, 0, in_bank) \ + _SET_MEMORY24(addr, val, in_bank) + + +#define _SET_MEMORY24(addr, val, in_bank) \ LOG_DATA_MACRO(addr, val, 24); \ stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \ wstat = PTR2WORD(stat) & 0xff; \ @@ -352,19 +395,99 @@ extern word32 slow_mem_changed[]; ptr[2] = (val) >> 16; \ } -void check_breakpoints(word32 addr) { - int count; + + +extern int g_num_bp_breakpoints; +extern word32 g_bp_breakpoints[]; + +extern int g_num_tp_breakpoints; +extern word32 g_tp_breakpoints[]; + +extern int g_num_mp_breakpoints; +extern word32 g_mp_breakpoints[]; + +extern word32 g_abort_address; +extern word32 g_abort_value; +extern word32 g_abort_bytes; + +int check_bp_breakpoints(word32 addr) { int i; - count = g_num_breakpoints; - for(i = 0; i < count; i++) { - if((g_breakpts[i] & 0xffffff) == addr) { - g_dbg_step = -2; - halt2_printf("Hit breakpoint at %06x\n", addr); + for (i = 0; i < g_num_bp_breakpoints; ++i) { + if (g_bp_breakpoints[i] == addr) { + return 1; } } + /* temp breakpoints */ + for (i = 0; i < g_num_tp_breakpoints; ++i) { + if (g_tp_breakpoints[i] == addr) { + return 1; + } + } + return 0; } + +/* 65816 abort just pushes the orignal pc (-1?) on the stack. + MMU hardware could, of course, store the address [and value?] + +*/ + + +int check_mp_breakpoints(word32 addr, word32 value, unsigned bytes, int in_page, int in_bank) { + byte *stat1; + byte *stat2; + word32 wstat; + word32 mask = 0xffffff; + int i; + + + /* assumptions: + * bytes is 1-3, so no possibility of crossing multiple pages + * g_mp_breakpoints is in ascending order. + */ + + word32 a1 = addr; + word32 a2 = addr + bytes - 1; + + if (in_page) { + mask = 0x00ff; + } else if (in_bank) { + mask = 0xffff; + } else { + mask = 0xffffff; + } + + a2 = (a2 & mask) | (addr & ~mask); + + stat1 = GET_PAGE_INFO_WR(((a1) >> 8) & 0xffff); + stat2 = GET_PAGE_INFO_WR(((a2) >> 8) & 0xffff); + wstat = PTR2WORD(stat1) | PTR2WORD(stat2); + + if (wstat & BANK_BREAK) { + for (i = 0; i < g_num_mp_breakpoints; ++i) { + word32 bp = g_mp_breakpoints[i]; + if (bp >= a1 && bp <= a2) { + abort_it: + g_abort_address = addr; + g_abort_bytes = bytes; + mask = (1 << (bytes << 3))-1; + g_abort_value = value & mask; + return 1; + } + if (a2 < a1) { + /* special logic for page/bank-wrapping... */ + if (bp >= a1 && bp <= (a1 | mask)) goto abort_it; + if (bp >= (a1 & ~mask) && bp <= a2) goto abort_it; + } + } + } + + return 0; +} + + + word32 get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr, double fplus_x_m1) { double fcycles; @@ -372,9 +495,6 @@ word32 get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr, byte *ptr; wstat = PTR2WORD(stat) & 0xff; - if(wstat & BANK_BREAK) { - check_breakpoints(addr); - } fcycles = *fcycs_ptr; if(wstat & BANK_IO2_TMP || iostrobe == 1) { FCYCLES_ROUND; @@ -449,16 +569,14 @@ void set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr, word32 wstat; wstat = PTR2WORD(stat) & 0xff; - if(wstat & (1 << (31 - BANK_BREAK_BIT))) { - check_breakpoints(addr); - } - ptr = stat - wstat + ((addr) & 0xff); \ + + ptr = stat - wstat + ((addr) & 0xff); fcycles = *fcycs_ptr; - if(wstat & (1 << (31 - BANK_IO2_BIT))) { + if(wstat & BANK_IO2_TMP) { FCYCLES_ROUND; *fcycs_ptr = fcycles; set_memory_io((addr), val, fcycs_ptr); - } else if(wstat & (1 << (31 - BANK_SHADOW_BIT))) { + } else if(wstat & BANK_SHADOW) { FCYCS_PTR_FCYCLES_ROUND_SLOW; tmp1 = (addr & 0xffff); setmem_tmp1 = g_slow_memory_ptr[tmp1]; @@ -468,7 +586,7 @@ void set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr, slow_mem_changed[tmp1 >> CHANGE_SHIFT] |= (1 << (31-((tmp1 >> SHIFT_PER_CHANGE) & 0x1f))); } - } else if(wstat & (1 << (31 - BANK_SHADOW2_BIT))) { + } else if(wstat & BANK_SHADOW2) { FCYCS_PTR_FCYCLES_ROUND_SLOW; tmp2 = (addr & 0xffff); tmp1 = 0x10000 + tmp2; @@ -493,12 +611,12 @@ void set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr, word32 addrp1; word32 wstat; fcycles = *fcycs_ptr; - SET_MEMORY8(addr, val); + _SET_MEMORY8(addr, val); addrp1 = addr + 1; if(in_bank) { addrp1 = (addr & 0xff0000) + (addrp1 & 0xffff); } - SET_MEMORY8(addrp1, val >> 8); + _SET_MEMORY8(addrp1, val >> 8); *fcycs_ptr = fcycles; } @@ -516,17 +634,17 @@ void set_memory24_pieces_stub(word32 addr, word32 val, double *fcycs_ptr, fcycles = *fcycs_ptr; fplus_1 = fplus_ptr->plus_1; fplus_x_m1 = fplus_ptr->plus_x_minus_1; - SET_MEMORY8(addr, val); + _SET_MEMORY8(addr, val); addrp1 = addr + 1; if(in_bank) { addrp1 = (addr & 0xff0000) + (addrp1 & 0xffff); } - SET_MEMORY8(addrp1, val >> 8); + _SET_MEMORY8(addrp1, val >> 8); addrp2 = addr + 2; if(in_bank) { addrp2 = (addr & 0xff0000) + (addrp2 & 0xffff); } - SET_MEMORY8(addrp2, val >> 16); + _SET_MEMORY8(addrp2, val >> 16); *fcycs_ptr = fcycles; } @@ -591,7 +709,7 @@ void set_memory_c(word32 addr, word32 val, int cycs) { fcycles = g_cur_dcycs - g_last_vbl_dcycs; fplus_1 = 0; fplus_x_m1 = 0; - SET_MEMORY8(addr, val); + _SET_MEMORY8(addr, val); } void set_memory16_c(word32 addr, word32 val, int cycs) { @@ -606,7 +724,7 @@ void set_memory16_c(word32 addr, word32 val, int cycs) { fplus_1 = 0; fplus_2 = 0; fplus_x_m1 = 0; - SET_MEMORY16(addr, val, 0); + _SET_MEMORY16(addr, val, 0); } void set_memory24_c(word32 addr, word32 val, int cycs) { @@ -760,42 +878,37 @@ void fixed_memory_ptrs_shut() { g_rom_cards_ptr = NULL; } +#if defined(_MSC_VER) + #include +#elif defined(__GNUC__) + + #if defined(__i386__) || defined(__x86_64__) + #include + #elif defined(__powerpc__) || defined(__ppc__) + #define __rdtsc() __builtin_ppc_mftb() + #else + #warning __rdtsc unavailable. + #define __rdtsc() 0 + #endif +#else + #warning __rdtsc unavailable. + #define __rdtsc() 0 +#endif word32 get_itimer() { #if defined(_WIN32) LARGE_INTEGER count; if (QueryPerformanceCounter(&count)) return count.LowPart; - else - return 0; -#elif defined(__i386) && defined(__GNUC__) - /* Here's my bad ia32 asm code to do rdtsc */ - /* Linux source uses: */ - /* asm volatile("rdtsc" : "=a"(ret) : : "edx"); */ - /* asm volatile("rdtsc" : "=%eax"(ret) : : "%edx"); */ - - /* GCC bug report 2001-03/msg00786.html used: */ - /*register word64 dtmp; */ - /*asm volatile ("rdtsc" : "=A" (dtmp)); */ - /*return (word32)dtmp; */ - - register word32 ret; - - asm volatile ("rdtsc;movl %%eax,%0" : "=r" (ret) : : "%eax","%edx"); - - return ret; -#elif defined(__POWERPC__) && defined(__GNUC__) - register word32 ret; - - asm volatile ("mftb %0" : "=r" (ret)); - return ret; -#else - return 0; #endif + + return __rdtsc(); + } void set_halt_act(int val) { - if(val == 1 && g_ignore_halts && !g_user_halt_bad) { + extern int g_dbg_shell; + if(val == 1 && g_ignore_halts && !g_user_halt_bad && !g_dbg_shell) { g_code_red++; } else { halt_sim |= val; @@ -865,18 +978,23 @@ word32 get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fpl return arg; } -#define FETCH_OPCODE \ - addr = kpc; \ + +#define FETCH_OPCODE \ + addr = saved_pc = kpc; \ + saved_psr = psr; \ CYCLES_PLUS_2; \ stat = GET_PAGE_INFO_RD(((addr) >> 8) & 0xffff); \ wstat = PTR2WORD(stat) & 0xff; \ ptr = stat - wstat + ((addr) & 0xff); \ arg_ptr = ptr; \ opcode = *ptr; \ - if((wstat & (1 << (31-BANK_IO_BIT))) || ((addr & 0xff) > 0xfc)) { \ - if(wstat & BANK_BREAK) { \ - check_breakpoints(addr); \ - } \ + if (wstat & BANK_BREAK) { \ + wstat &= ~BANK_BREAK; \ + if (kpc_support && check_bp_breakpoints(addr)) { \ + FINISH(RET_BP, addr); \ + } \ + } \ + if((wstat & BANK_IO_TMP) || ((addr & 0xff) > 0xfc)) { \ if((addr & 0xfffff0) == 0x00c700) { \ if(addr == 0xc700) { \ FINISH(RET_C700, 0); \ @@ -886,7 +1004,7 @@ word32 get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fpl FINISH(RET_C70D, 0); \ } \ } \ - if(wstat & (1 << (31 - BANK_IO2_BIT)) || iostrobe == 1) { \ + if(wstat & BANK_IO2_TMP || iostrobe == 1) { \ FCYCLES_ROUND; \ fcycles_tmp1 = fcycles; \ opcode = get_memory_io((addr), &fcycles_tmp1); \ @@ -935,6 +1053,17 @@ int enter_engine(Engine_reg *engine_ptr) { word32 addr_latch; word32 tmp1, tmp2; + word32 flags = 0; + word32 saved_pc = 0; + word32 saved_psr = 0; + + word32 abort_support = g_num_mp_breakpoints ? 1 : 0; + word32 kpc_support = g_num_bp_breakpoints + g_num_tp_breakpoints ? 1 : 0; + + flags = engine_ptr->flags; + if (flags & FLAG_IGNORE_MP) abort_support = 0; + if (flags & FLAG_IGNORE_BP) kpc_support = 0; + tmp_pc_ptr = 0; diff --git a/src/gsport.sln b/src/gsport.sln deleted file mode 100644 index 9a17a1d..0000000 --- a/src/gsport.sln +++ /dev/null @@ -1,36 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2012 for Windows Desktop -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsport", "gsport.vcxproj", "{0B4E527A-DB50-4B5F-9B08-303ABAF7356A}" - ProjectSection(ProjectDependencies) = postProject - {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B} = {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B} - {E810477A-E004-4308-A58A-21393213EF89} = {E810477A-E004-4308-A58A-21393213EF89} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tfe", "tfe\tfe.vcxproj", "{E810477A-E004-4308-A58A-21393213EF89}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "atbridge", "atbridge\atbridge.vcxproj", "{2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Debug|Win32.ActiveCfg = Debug|Win32 - {0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Debug|Win32.Build.0 = Debug|Win32 - {0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Release|Win32.ActiveCfg = Release|Win32 - {0B4E527A-DB50-4B5F-9B08-303ABAF7356A}.Release|Win32.Build.0 = Release|Win32 - {E810477A-E004-4308-A58A-21393213EF89}.Debug|Win32.ActiveCfg = Debug|Win32 - {E810477A-E004-4308-A58A-21393213EF89}.Debug|Win32.Build.0 = Debug|Win32 - {E810477A-E004-4308-A58A-21393213EF89}.Release|Win32.ActiveCfg = Release|Win32 - {E810477A-E004-4308-A58A-21393213EF89}.Release|Win32.Build.0 = Release|Win32 - {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Debug|Win32.ActiveCfg = Debug|Win32 - {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Debug|Win32.Build.0 = Debug|Win32 - {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Release|Win32.ActiveCfg = Release|Win32 - {2C88133A-7CB8-4C03-AF4D-4ECFC6F8500B}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/gsport.vcxproj b/src/gsport.vcxproj deleted file mode 100644 index 647685c..0000000 --- a/src/gsport.vcxproj +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {0B4E527A-DB50-4B5F-9B08-303ABAF7356A} - Win32Proj - gsport - - - - Application - true - MultiByte - v120 - - - Application - false - true - MultiByte - v120 - - - - - - - - - - - - - true - - - false - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN_SOUND;GSPLUS_LITTLE_ENDIAN;HAVE_TFE;HAVE_ATBRIDGE;TOGGLE_STATUS;%(PreprocessorDefinitions) - CompileAsC - Speed - true - ProgramDatabase - EnableFastChecks - Prompt - true - true - false - - - Console - true - IPHLPAPI.lib;Winmm.lib;Ws2_32.lib;Shlwapi.lib;$(SolutionDir)$(Configuration)\tfe.lib;;$(SolutionDir)$(Configuration)\atbridge.lib;%(AdditionalDependencies) - MachineX86 - - - - - Level3 - NotUsing - Full - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN_SOUND;GSPLUS_LITTLE_ENDIAN;HAVE_ATBRIDGE;HAVE_TFE;TOGGLE_STATUS;%(PreprocessorDefinitions) - Speed - false - CompileAsC - Prompt - StreamingSIMDExtensions2 - AnySuitable - true - true - - - Console - true - true - true - IPHLPAPI.lib;Winmm.lib;Ws2_32.lib;Shlwapi.lib;$(SolutionDir)$(Configuration)\tfe.lib;;$(SolutionDir)$(Configuration)\atbridge.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - perl make_inst c 8 instable.h > 8inst_c.h -perl make_inst c 16 instable.h > 16inst_c.h -perl make_inst s 8 instable.h > 8inst_s.h -perl make_inst s 16 instable.h > 16inst_s.h - 8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h - false - perl make_inst c 8 instable.h > 8inst_c.h -perl make_inst c 16 instable.h > 16inst_c.h -perl make_inst s 8 instable.h > 8inst_s.h -perl make_inst s 16 instable.h > 16inst_s.h - 8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h - false - - - - - - - - - - - - - - - - - - - - - - - perl make_size c size_tab.h > size_c.h -perl make_size s size_tab.h > size_s.h -perl make_size 8 size_tab.h > 8size_s.h -perl make_size 16 size_tab.h > 16size_s.h -perl make_size c size_tab.h > size_c.h - size_c.h size_s.h 8size_s.h 16size_s.h - false - perl make_size c size_tab.h > size_c.h -perl make_size s size_tab.h > size_s.h -perl make_size 8 size_tab.h > 8size_s.h -perl make_size 16 size_tab.h > 16size_s.h -perl make_size c size_tab.h > size_c.h - size_c.h size_s.h 8size_s.h 16size_s.h - false - - - - - - - - - - - - - - - - - - - - - CompileAsCpp - CompileAsCpp - - - - CompileAsCpp - CompileAsCpp - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gsport.vcxproj.filters b/src/gsport.vcxproj.filters deleted file mode 100644 index 59b4026..0000000 --- a/src/gsport.vcxproj.filters +++ /dev/null @@ -1,217 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - - - Resource Files - - - diff --git a/src/headless_driver.c b/src/headless_driver.c index 71b898c..2606248 100644 --- a/src/headless_driver.c +++ b/src/headless_driver.c @@ -8,9 +8,129 @@ #include "defc.h" #include "glog.h" +#include + + +extern int get_byte_at_address(int addr); + +static unsigned char fix_char(unsigned char c) { + // inverse upper case + if (c >= 0x00 && c <= 0x1f) return c + 0x40; + + // inverse special + if (c >= 0x20 && c <= 0x3f) return c; + + // mouse text + if (c >= 0x40 && c <= 0x5f) return ' '; + + // inverse lowercase + if (c >= 0x60 && c <= 0x7f) return c; + + // uppercase normal + if (c >= 0x80 && c <= 0x9f) return c - 0x40; + + + // special characters, uppercase normal, lowercase normal. + if (c >= 0xa0 && c <= 0xff) return c - 0x80; + + return ' '; +} + + +static void siginfo_handler(int signum) { + + static unsigned table[] = { + 0x0400, + 0x0480, + 0x0500, + 0x0580, + 0x0600, + 0x0680, + 0x0700, + 0x0780, + 0x0428, + 0x04A8, + 0x0528, + 0x05A8, + 0x0628, + 0x06A8, + 0x0728, + 0x07A8, + 0x0450, + 0x04D0, + 0x0550, + 0x05D0, + 0x0650, + 0x06D0, + 0x0750, + 0x07D0, + }; + + extern int g_cur_a2_stat; + extern int get_byte_at_address(int addr); + + + if (g_cur_a2_stat & ALL_STAT_SUPER_HIRES) return; // not text... + + int st80 = g_cur_a2_stat & ALL_STAT_VID80 /* ALL_STAT_ST80 */; + + //if (!(g_cur_a2_stat & ALL_STAT_TEXT)) return; // text is not enabled. + + char buffer[80+1]; + + for (int row = 0; row < 24; ++row) { + unsigned address = table[row]; + int column = 0; + + memset(buffer, ' ', sizeof(buffer)); + + for(int j = 0; j < 40; ++j, ++address) { + + unsigned char c; + + if (st80) { + c = get_byte_at_address(0xe10000 + address); + c = fix_char(c); + buffer[column++] = c; + } + + c = get_byte_at_address(0xe00000 + address); + c = fix_char(c); + buffer[column++] = c; + + } + if (st80) { + buffer[80] = '\n'; + write(1, buffer, 81); + } else { + buffer[40] = '\n'; + write(1, buffer, 41); + } + } + write(1, "\n\n", 2); +} + int main(int argc, char **argv) { + + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + + sa.sa_flags = SA_RESTART; + sa.sa_handler = siginfo_handler; + + #if defined(SIGINFO) + /* control-T by default */ + + sigaction(SIGINFO, &sa, NULL); + //signal(SIGINFO, siginfo_handler); + #endif + + //signal(SIGUSR1, siginfo_handler); + sigaction(SIGUSR1, &sa, NULL); + + return gsplusmain(argc, argv); } diff --git a/src/host_common.c b/src/host_common.c index 6cab5ab..6b594e6 100644 --- a/src/host_common.c +++ b/src/host_common.c @@ -1,14 +1,9 @@ #define _BSD_SOURCE -#include -#include -#include #include -#include #include #include #include -#include #include "defc.h" #include "gsos.h" @@ -18,6 +13,12 @@ #include #endif +#ifdef _MSC_VER +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + + #include "host_common.h" @@ -149,59 +150,6 @@ void host_text_to_merlin(byte *buffer, size_t size) { } -/* - * error remapping. - * NOTE - GS/OS errors are a superset of P8 errors - */ - -static word32 enoent(const char *path) { - /* - some op on path return ENOENT. check if it's - fileNotFound or pathNotFound - */ - char *p = (char *)path; - for(;;) { - struct stat st; - p = dirname(p); - if (p == NULL) break; - if (p[0] == '.' && p[1] == 0) break; - if (p[0] == '/' && p[1] == 0) break; - if (stat(p, &st) < 0) return pathNotFound; - } - return fileNotFound; -} - -word32 host_map_errno(int xerrno) { - switch(xerrno) { - case 0: return 0; - case EBADF: - return invalidAccess; -#ifdef EDQUOT - case EDQUOT: -#endif - case EFBIG: - return volumeFull; - case ENOENT: - return fileNotFound; - case ENOTDIR: - return pathNotFound; - case ENOMEM: - return outOfMem; - case EEXIST: - return dupPathname; - case ENOTEMPTY: - return invalidAccess; - - default: - return drvrIOError; - } -} - -word32 host_map_errno_path(int xerrno, const char *path) { - if (xerrno == ENOENT) return enoent(path); - return host_map_errno(xerrno); -} - const char *host_error_name(word16 error) { static char *errors[] = { "", diff --git a/src/host_mli.c b/src/host_mli.c index 48bec74..fb4c8c0 100644 --- a/src/host_mli.c +++ b/src/host_mli.c @@ -26,6 +26,11 @@ #include "host_common.h" +#ifdef _MSC_VER +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + #define LEVEL 0xBFD8 // current file level #define DEVNUM 0xBF30 // last slot / drive diff --git a/src/instable.h b/src/instable.h index 5ff6a5e..21b3c48 100644 --- a/src/instable.h +++ b/src/instable.h @@ -71,27 +71,43 @@ brk_testing_SYM DEC_KPC2; CYCLES_PLUS_2 b dispatch_done - depi RET_BREAK,3,4,ret0 + depi RET_BRK,3,4,ret0 #else GET_1BYTE_ARG; - if(g_testing) { - CYCLES_PLUS_2; - FINISH(RET_BREAK, arg); + + if (flags & FLAG_WANT_BRK) { + if (~flags & FLAG_IGNORE_BRK) { + CYCLES_PLUS_2; + FINISH(RET_BRK, arg); + } } - g_num_brk++; INC_KPC_2; + g_num_brk++; + + psr = psr & (~0x82); + psr |= (neg << 7); + psr |= ((!zero) << 1); + tmp1 = psr & 0xff; if(psr & 0x100) { - PUSH16(kpc & 0xffff); - PUSH8(psr & 0xff); + MMU_CHECK( + ((stack - 2) & 0xff) | 0x0100, + (kpc << 8) | tmp1, 3, 1, 1 + ) + _PUSH16(kpc & 0xffff); + _PUSH8(tmp1); GET_MEMORY16(0xfffe, kpc, 0); dbank = 0; } else { - PUSH8(kpc >> 16); - PUSH16(kpc); - PUSH8(psr & 0xff); + MMU_CHECK( + (stack - 3) & 0xffff, + (kpc << 8) | tmp1, 4, 0, 1 + ) + _PUSH8(kpc >> 16); + _PUSH16(kpc); + _PUSH8(tmp1); GET_MEMORY16(0xffe6, kpc, 0); - halt_printf("Halting for native break!\n"); + //halt_printf("Halting for native break!\n"); } kpc = kpc & 0xffff; psr |= 0x4; @@ -153,18 +169,42 @@ cop_native_SYM #else - g_num_cop++; + GET_1BYTE_ARG; + + if (flags & FLAG_WANT_COP) { + if (~flags & FLAG_IGNORE_BRK) { + CYCLES_PLUS_2; + FINISH(RET_COP, arg); + } + } INC_KPC_2; + g_num_cop++; + + psr = psr & (~0x82); + psr |= (neg << 7); + psr |= ((!zero) << 1); + tmp1 = psr & 0xff; + if(psr & 0x100) { - halt_printf("Halting for emul COP at %04x\n", kpc); - PUSH16(kpc & 0xffff); - PUSH8(psr & 0xff); + //halt_printf("Halting for emul COP at %04x\n", kpc); + MMU_CHECK( + ((stack - 2) & 0xff) | 0x0100, + (kpc << 8) | tmp1, 3, 1, 1 + ) + + _PUSH16(kpc & 0xffff); + _PUSH8(tmp1); GET_MEMORY16(0xfff4, kpc, 0); dbank = 0; } else { - PUSH8(kpc >> 16); - PUSH16(kpc & 0xffff); - PUSH8(psr & 0xff); + MMU_CHECK( + (stack - 3) & 0xffff, + (kpc << 8) | tmp1, 4, 0, 1 + ) + + _PUSH8(kpc >> 16); + _PUSH16(kpc & 0xffff); + _PUSH8(tmp1); GET_MEMORY16(0xffe4, kpc, 0); } kpc = kpc & 0xffff; diff --git a/src/moremem.c b/src/moremem.c index 47a7cbc..d2dda2f 100644 --- a/src/moremem.c +++ b/src/moremem.c @@ -6,9 +6,10 @@ */ #include "defc.h" +#include -#ifdef HAVE_TFE -#include "tfe/protos_tfe.h" +#ifdef HAVE_RAWNET +#include "rawnet/cs8900.h" #endif extern char const g_gsplus_version_str[]; @@ -24,8 +25,16 @@ extern unsigned char iostrobe; extern word32 slow_mem_changed[]; -extern int g_num_breakpoints; -extern word32 g_breakpts[]; + +extern int g_num_mp_breakpoints; +extern word32 g_mp_breakpoints[]; + +extern int g_num_bp_breakpoints; +extern word32 g_bp_breakpoints[]; + +extern int g_num_tp_breakpoints; +extern word32 g_tp_breakpoints[]; + extern Page_info page_info_rd_wr[]; @@ -34,6 +43,8 @@ extern int g_rom_version; extern int g_user_page2_shadow; extern int g_parallel; +extern int g_ethernet_enabled; + char c; /* from iwm.c */ int g_num_shadow_all_banks = 0; @@ -240,11 +251,48 @@ void moremem_init() { void fixup_brks() { word32 page; - word32 tmp, tmp2; Pg_info val; - int is_wr_only; - int i, num; + int i; + /* need to clear break bit from all pages first? */ + for (page = 0; page < 0xffff; ++page) { + val = GET_PAGE_INFO_RD(page); + val = (Pg_info)((ptrdiff_t)val &~ BANK_BREAK); + SET_PAGE_INFO_RD(page, val); + } + for (page = 0; page < 0xffff; ++page) { + val = GET_PAGE_INFO_WR(page); + val = (Pg_info)((ptrdiff_t)val &~ BANK_BREAK); + SET_PAGE_INFO_WR(page, val); + } + + + /* bp are read-only. mp are read/write */ + for (i = 0; i < g_num_bp_breakpoints; ++i) { + page = (g_bp_breakpoints[i] >> 8) & 0xffff; + val = GET_PAGE_INFO_RD(page); + val = (Pg_info)((ptrdiff_t)val | BANK_BREAK); + SET_PAGE_INFO_RD(page, val); + /* why IO_TMP? */ + } + + for (i = 0; i < g_num_tp_breakpoints; ++i) { + page = (g_tp_breakpoints[i] >> 8) & 0xffff; + val = GET_PAGE_INFO_RD(page); + val = (Pg_info)((ptrdiff_t)val | BANK_BREAK); + SET_PAGE_INFO_RD(page, val); + /* why IO_TMP? */ + } + + for (i = 0; i < g_num_mp_breakpoints; ++i) { + page = (g_mp_breakpoints[i] >> 8) & 0xffff; + val = GET_PAGE_INFO_WR(page); + val = (Pg_info)((ptrdiff_t)val | BANK_BREAK); + SET_PAGE_INFO_WR(page, val); + /* why IO_TMP? */ + } + +#if 0 num = g_num_breakpoints; for(i = 0; i < num; i++) { page = (g_breakpts[i] >> 8) & 0xffff; @@ -260,6 +308,8 @@ void fixup_brks() { tmp2 = tmp | BANK_IO_TMP | BANK_BREAK; SET_PAGE_INFO_WR(page, val - tmp + tmp2); } +#endif + } void fixup_hires_on() { @@ -1591,7 +1641,7 @@ int io_read(word32 loc, double *cyc_ptr) { //case 0xb8: // return 0; // break; -#ifdef HAVE_TFE +#ifdef HAVE_RAWNET /*Uthernet read access on slot 3*/ case 0xb0: case 0xb1: @@ -1609,8 +1659,8 @@ int io_read(word32 loc, double *cyc_ptr) { case 0xbd: case 0xbe: case 0xbf: - if (tfe_enabled) { - return tfe_read((word16)loc & 0xf); + if (g_ethernet_enabled) { + return cs8900_read((word16)loc & 0xf); } else {return 0;} @@ -2326,7 +2376,7 @@ void io_write(word32 loc, int val, double *cyc_ptr) { //case 0xb8: case 0xb9: case 0xba: case 0xbb: //case 0xbc: case 0xbd: case 0xbe: case 0xbf: // UNIMPL_WRITE; -#ifdef HAVE_TFE +#ifdef HAVE_RAWNET /*Uthernet write access on slot 3*/ case 0xb0: case 0xb1: @@ -2344,9 +2394,9 @@ void io_write(word32 loc, int val, double *cyc_ptr) { case 0xbd: case 0xbe: case 0xbf: - if (tfe_enabled) + if (g_ethernet_enabled) { - tfe_store((word16)loc & 0xf, (byte)val); + cs8900_store((word16)loc & 0xf, (byte)val); return; } else diff --git a/src/options.c b/src/options.c index 30cd632..a8bdf0d 100644 --- a/src/options.c +++ b/src/options.c @@ -8,10 +8,15 @@ #include #include #include +#include #include "options.h" #include "glog.h" #include "defc.h" +#ifdef _MSC_VER +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + // config is parsed in config.c :: config_parse_config_gsplus_file() // cli is parsed here. would be nice to reuse some code @@ -62,6 +67,8 @@ extern int g_audio_enable; // defined in sound.c // Start in fullscreen mode extern int g_fullscreen; // defined in adb.c, because weird driver writing for x +extern int g_dbg_shell; + // Specify the joystick - SDL2 extern int g_joystick_number; // defined in joystick_driver.c extern int g_joystick_x_axis; // defined in joystick_driver.c @@ -314,15 +321,6 @@ void parse_cli_options(int argc, char **argv) { glogf("%s Setting scanline simulator darkness to %d%%", parse_log_prefix, tmp1); g_scanline_simulator = tmp1; i++; - } else if(!strcmp("-enet", argv[i])) { - if((i+1) >= argc) { - glogf("%s Error, option '-enet' missing argument", parse_log_prefix); - exit(1); - } - tmp1 = strtol(argv[i+1], 0, 0); - glogf("%s Using %d as ethernet enable val", parse_log_prefix, tmp1); - g_ethernet = tmp1; - i++; } else if(!strcmp("-x", argv[i])) { if((i+1) >= argc) { glogf("%s Error, option '-x' missing argument", parse_log_prefix); @@ -386,6 +384,8 @@ void parse_cli_options(int argc, char **argv) { g_dbg_enable_port = strtol(argv[i+1], 0, 0); glogf("%s Using %d for debug port", parse_log_prefix, g_dbg_enable_port); i++; + } else if (!strcmp("-g", argv[i])) { + g_dbg_shell = 1; } else { if ((i == (argc - 1)) && (strncmp("-", argv[i], 1) != 0)) { final_arg = argv[i]; @@ -421,7 +421,6 @@ void help_exit() { printf(" -skip value Set skip_amt to value\n"); printf(" -audio value Set audio enable to value\n"); printf(" -arate value Set preferred audio rate to value\n"); - printf(" -enet value Set ethernet to value\n"); printf(" -config value Set config file to value\n"); printf(" -debugport value Set debugport to value\n"); printf(" -ssdir value Set screenshot save directory to value\n"); diff --git a/src/protos.h b/src/protos.h index 23932ff..de2a0c0 100644 --- a/src/protos.h +++ b/src/protos.h @@ -172,9 +172,9 @@ void do_debug_intfc(void); word32 dis_get_memory_ptr(word32 addr); void show_one_toolset(FILE *toolfile, int toolnum, word32 addr); void show_toolset_tables(word32 a2bank, word32 addr); -void set_bp(word32 addr); -void show_bp(void); -void delete_bp(word32 addr); +int set_bp(int type, word32 addr); +void show_bp(int type); +int delete_bp(int type, word32 addr); void do_blank(void); void do_go(void); void do_go_debug(void); // socket debug ver @@ -385,7 +385,7 @@ double remove_event_scc(int type); void show_all_events(void); void show_pmhz(void); void setup_zip_speeds(void); -void run_prog(void); +int run_prog(void); void add_irq(word32 irq_mask); void remove_irq(word32 irq_mask); void take_irq(int is_it_brk); 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..7b1ec93 --- /dev/null +++ b/src/rawnet/rawnetarch_vmnet_helper.c @@ -0,0 +1,486 @@ +/* + * 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; + posix_spawn_file_actions_t actions; + posix_spawnattr_t attr; + 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); + + 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); + + 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/readline.c b/src/readline.c new file mode 100644 index 0000000..8476ea2 --- /dev/null +++ b/src/readline.c @@ -0,0 +1,265 @@ +#include +#include +#include +#include + + +#define HISTORY_SIZE 64 + +/* remove trailing whitespace and terminators */ +static void cleanup_buffer(char *buffer, int size) { + + while (size > 0) { + unsigned c = buffer[size-1]; + if (c == ' ' || c == '\r' || c == '\n') { + --size; + continue; + } + break; + } + buffer[size] = 0; +} + +#if defined(USE_LIBEDIT) + +#include + + + /* BSD libedit support */ +EditLine *el = NULL; +History *hist = NULL; +HistEvent ev; + +static const char *el_prompt = NULL; +static char *prompt_fn(EditLine *el) { + return el_prompt ? (char *)el_prompt : ""; +} + +char *x_readline(const char *prompt) { + static char buffer[1024]; + int count = 0; + const char *cp; + + if (!el) { + hist = history_init(); + history(hist, &ev, H_SETSIZE, HISTORY_SIZE); + history(hist, &ev, H_SETUNIQUE, 1); + + el = el_init("GS+", stdin, stdout, stderr); + el_set(el, EL_EDITOR, "emacs"); + el_set(el, EL_BIND, "-e", NULL, NULL, NULL); + el_set(el, EL_HIST, history, hist); + el_set(el, EL_PROMPT, prompt_fn); + el_set(el, EL_SIGNAL, 1); + el_source(el, NULL); + } + + el_prompt = prompt; + cp = el_gets(el, &count); + el_prompt = NULL; + if (count <= 0) { + if (prompt) fputc('\n', stdout); + return NULL; + } + if (count > sizeof(buffer) - 1) return ""; + + + memcpy(buffer, cp, count); + cleanup_buffer(buffer, count); + + if (*buffer) + history(hist, &ev, H_ENTER, buffer); + + return buffer; +} + +void x_readline_end(void) { + if (el) { + el_end(el); + el = NULL; + } + if (hist) { + history_end(hist); + hist = NULL; + } +} + +#elif defined(USE_READLINE) + /* GNU Readline support */ + +#include +#include + +static int readline_init = 0; +/* suppress tab completion, which defaults to filenames */ +static char **rl_acf(const char* text, int start, int end) { + return NULL; +} +char *x_readline(const char *prompt) { + static char buffer[1024]; + + char *cp; + int count; + + if (!readline_init) { + rl_readline_name = "GS+"; + rl_attempted_completion_function = rl_acf; + + using_history(); + stifle_history(HISTORY_SIZE); + + readline_init = 1; + } + + cp = readline(prompt); + if (!cp) { + if (prompt) fputc('\n', stdout); + return NULL; + } + count = strlen(cp); + if (count > sizeof(buffer) - 1) { + free(cp); + return ""; + } + memcpy(buffer, cp, count); + cleanup_buffer(buffer, count); + free(cp); + + /* append to history, but only if unique from prev. entry */ + if (*buffer) { + HIST_ENTRY *h = history_get(history_length); + if (h == NULL || strcmp(buffer, h->line)) + add_history(buffer); + } + return buffer; +} + +void x_readline_end(void) { +} +#elif defined(_WIN32) + +#include + +static int readline_init = 0; + +#ifndef HISTORY_NO_DUP_FLAG +#define HISTORY_NO_DUP_FLAG 0x01 +#endif + +char *x_readline(const char *prompt) { + static char buffer[1024]; + DWORD count = 0; + BOOL ok; + + + HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + + /* MS CRT uses -2 to indicate there is no stdin/stdout/stderr fileno */ + +/* + if (h == INVALID_HANDLE_VALUE) { + //* cygwin? * / + fputs("GetStdHandle\n", stderr); + fflush(stderr); + return NULL; + + char *cp; + fputs(prompt, stdout); + fflush(stdout); + return fgets(buffer, sizeof(buffer), stdin); + } +*/ + + if (!readline_init) { + + //struct stat st; + + + CONSOLE_HISTORY_INFO chi; + DWORD mode; + + memset(&chi, 0, sizeof(chi)); + chi.cbSize = sizeof(CONSOLE_HISTORY_INFO); + chi.HistoryBufferSize = HISTORY_SIZE; + chi.NumberOfHistoryBuffers = 1; /* ???? */ + chi.dwFlags = HISTORY_NO_DUP_FLAG; + ok = SetConsoleHistoryInfo(&chi); + + if (!ok) { + fprintf(stderr, "SetConsoleHistoryInfo: %lx\n", GetLastError()); + fflush(stderr); + } + + + mode = ENABLE_ECHO_INPUT | ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_QUICK_EDIT_MODE; + ok = SetConsoleMode(hIn, mode); + + if (!ok) { + fprintf(stderr, "SetConsoleMode: %lx (h = %p)\n", GetLastError(), hIn); + fflush(stderr); + } + + readline_init = 1; + } + + fflush(stderr); + fflush(stdout); + + ok = WriteConsole(hOut, prompt, strlen(prompt), NULL, NULL); + if (!ok) { + /* msys/cygwin? */ + + // fprintf(stderr, "WriteConsole: %lx (h = %p)\n", GetLastError(), hOut); + fflush(stderr); + if (prompt) fputs(prompt, stdout); + fflush(stdout); + char *cp = fgets(buffer, sizeof(buffer), stdin); + if (!cp) { + if (prompt) fputc('\n', stdout); + return NULL; + } + cleanup_buffer(buffer, strlen(buffer)); + return buffer; + } + ok = ReadConsole(hIn, buffer, sizeof(buffer), &count, NULL); + if (!ok) { + if (prompt) fputc('\n', stdout); + // fflush(stdout); + // fprintf(stderr, "Error: %lx (h = %p)\n", GetLastError(), hIn); + // fprintf(stderr, "Type: %08x\n", GetFileType(hIn)); + // fflush(stderr); + return NULL; + } + cleanup_buffer(buffer, count); + return buffer; +} + + +#else + +#include + +char *x_readline(const char *prompt) { + static char buffer[1024]; + + if (prompt) fputs(prompt, stdout); + fflush(stdout); + + for(;;) { + int ok = read(STDIN_FILENO, buffer, sizeof(buffer)-1); + if (ok < 0 && ok == EINTR) continue; + if (ok <= 0) { + if (prompt) fputc('\n', stdout); + return NULL; + } + cleanup_buffer(buffer, ok); + + return buffer; + } +} + +void x_readline_end(void) { + +} +#endif diff --git a/src/scc.c b/src/scc.c index 4d4ea3b..b116ae8 100644 --- a/src/scc.c +++ b/src/scc.c @@ -6,6 +6,7 @@ */ #include "defc.h" +#include "scc.h" #include "scc_llap.h" #ifdef UNDER_CE @@ -25,7 +26,6 @@ extern int g_appletalk_turbo; /* my scc port 0 == channel A = slot 1 = c039/c03b */ /* port 1 == channel B = slot 2 = c038/c03a */ -#include "scc.h" #define SCC_R14_DPLL_SOURCE_BRG 0x100 #define SCC_R14_FM_MODE 0x200 diff --git a/src/scc.h b/src/scc.h index 50939ea..31c96e2 100644 --- a/src/scc.h +++ b/src/scc.h @@ -5,14 +5,13 @@ See LICENSE.txt for license (GPL v2) */ -#include - #ifdef _WIN32 # include #else # include # include # include +typedef int SOCKET; #endif #if defined(HPUX) || defined(__linux__) || defined(SOLARIS) || defined(MAC) || defined(__MACH__) || defined(_WIN32) @@ -28,10 +27,6 @@ #define SCC_MODEM_MAX_CMD_STR 128 -#ifndef SOCKET -# define SOCKET word32 /* for non-windows */ -#endif - STRUCT(Scc) { int port; int state /* 0 == disconnected, 1 == real serial port, 2 == socket, 3 == LocalTalk */; diff --git a/src/scc_imagewriter.c b/src/scc_imagewriter.c index 7ebca0e..e03854a 100644 --- a/src/scc_imagewriter.c +++ b/src/scc_imagewriter.c @@ -8,8 +8,9 @@ /* This is an interface between the SCC emulation and the Virtual Imagewriter. */ #include "defc.h" -#include "scc.h" #include "imagewriter.h" +#include "scc.h" + extern Scc scc_stat[2]; extern word32 g_vbl_count; diff --git a/src/scc_macdriver.c b/src/scc_macdriver.c index 15eab92..d7f7b14 100644 --- a/src/scc_macdriver.c +++ b/src/scc_macdriver.c @@ -7,17 +7,16 @@ /* This file contains the Mac serial calls */ +#ifdef MAC + #include "defc.h" #include "scc.h" -#ifndef _WIN32 -# include -#endif +#include extern Scc scc_stat[2]; extern word32 g_c025_val; -#ifdef MAC int scc_serial_mac_init(int port) { char str_buf[1024]; Scc *scc_ptr; diff --git a/src/scc_socket_driver.c b/src/scc_socket_driver.c index bf43bfd..4fc3398 100644 --- a/src/scc_socket_driver.c +++ b/src/scc_socket_driver.c @@ -11,20 +11,21 @@ #include "scc.h" #include #include +#include + #ifndef UNDER_CE //OG #include #endif -#ifdef __CYGWIN__ + +#ifdef _WIN32 #include +#define socklen_t int #endif + extern Scc scc_stat[2]; extern int g_serial_modem[]; -#if !(defined _MSC_VER || defined __CYGWIN__) -extern int h_errno; -#else -#define socklen_t int -#endif + int g_wsastartup_called = 0; typedef unsigned short USHORT; @@ -108,19 +109,17 @@ void scc_socket_maybe_open_incoming(int port, double dcycs) { sockfd = socket(AF_INET, SOCK_STREAM, 0); printf("sockfd ret: %d\n", sockfd); if(sockfd == -1) { - printf("socket ret: %d, errno: %d\n", sockfd, errno); + perror("socket"); scc_socket_close(port, 0, dcycs); scc_ptr->socket_state = -1; return; } - /* printf("socket ret: %d\n", sockfd); */ on = 1; ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if(ret < 0) { - printf("setsockopt REUSEADDR ret: %d, err:%d\n", - ret, errno); + perror("setsockopt REUSEADDR"); scc_socket_close(port, 0, dcycs); scc_ptr->socket_state = -1; return; @@ -138,7 +137,7 @@ void scc_socket_maybe_open_incoming(int port, double dcycs) { break; } /* else ret to bind was < 0 */ - printf("bind ret: %d, errno: %d\n", ret, errno); + perror("bind"); inc++; scc_socket_close_handle(sockfd); printf("Trying next port: %d\n", 6501 + port + inc); @@ -180,7 +179,7 @@ void scc_socket_open_outgoing(int port, double dcycs) { sockfd = socket(AF_INET, SOCK_STREAM, 0); printf("sockfd ret: %d\n", sockfd); if(sockfd == -1) { - printf("socket ret: %d, errno: %d\n", sockfd, errno); + perror("socket"); scc_socket_close(port, 1, dcycs); return; } @@ -190,8 +189,7 @@ void scc_socket_open_outgoing(int port, double dcycs) { ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if(ret < 0) { - printf("setsockopt REUSEADDR ret: %d, err:%d\n", - ret, errno); + perror("setsockopt REUSEADDR"); scc_socket_close(port, 1, dcycs); return; } @@ -218,9 +216,9 @@ void scc_socket_open_outgoing(int port, double dcycs) { hostentptr = gethostbyname((const char*)&scc_ptr->modem_cmd_str[0]); // OG Added Cast if(hostentptr == 0) { #if defined(_WIN32) - fatal_printf("Lookup host %s failed\n", &scc_ptr->modem_cmd_str[0]); + fatal_printf("gethostbyname %s failed\n", &scc_ptr->modem_cmd_str[0]); #else - fatal_printf("Lookup host %s failed, herrno: %d\n", &scc_ptr->modem_cmd_str[0], h_errno); + fatal_printf("gethostbyname %s failed: %s\n", &scc_ptr->modem_cmd_str[0], hstrerror(h_errno)); #endif scc_socket_close_handle(sockfd); scc_socket_close(port, 1, dcycs); @@ -234,7 +232,7 @@ void scc_socket_open_outgoing(int port, double dcycs) { ret = connect(sockfd, (struct sockaddr *)&sa_in, sizeof(sa_in)); if(ret < 0) { - printf("connect ret: %d, errno: %d\n", ret, errno); + perror("connect"); scc_socket_close_handle(sockfd); scc_socket_close(port, 1, dcycs); return; @@ -276,14 +274,14 @@ void scc_socket_make_nonblock(int port, double dcycs) { #else flags = fcntl(sockfd, F_GETFL, 0); if(flags == -1) { - printf("fcntl GETFL ret: %d, errno: %d\n", flags, errno); + perror("fcntl GETFL"); scc_socket_close(port, 1, dcycs); scc_ptr->socket_state = -1; return; } ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); if(ret == -1) { - printf("fcntl SETFL ret: %d, errno: %d\n", ret, errno); + perror("fcntl SETFL"); scc_socket_close(port, 1, dcycs); scc_ptr->socket_state = -1; return; @@ -374,12 +372,12 @@ void scc_accept_socket(int port, double dcycs) { /* For Linux, we need to set O_NONBLOCK on the rdwrfd */ flags = fcntl(rdwrfd, F_GETFL, 0); if(flags == -1) { - printf("fcntl GETFL ret: %d, errno: %d\n", flags,errno); + perror("fcntl GETFL"); return; } ret = fcntl(rdwrfd, F_SETFL, flags | O_NONBLOCK); if(ret == -1) { - printf("fcntl SETFL ret: %d, errno: %d\n", ret, errno); + perror("fcntl SETFL"); return; } #endif diff --git a/src/scc_windriver.c b/src/scc_windriver.c index 8fecd17..bc2d664 100644 --- a/src/scc_windriver.c +++ b/src/scc_windriver.c @@ -7,13 +7,13 @@ /* This file contains the Win32 COM1/COM2 calls */ +#ifdef _WIN32 + #include "defc.h" #include "scc.h" -#ifdef __CYGWIN__ #include #include -#endif #ifdef UNDER_CE #define vsnprintf _vsnprintf @@ -22,7 +22,6 @@ extern Scc scc_stat[2]; extern word32 g_c025_val; -#ifdef _WIN32 int scc_serial_win_init(int port) { COMMTIMEOUTS commtimeouts; TCHAR str_buf[8]; diff --git a/src/sim65816.c b/src/sim65816.c index 56e2a2e..13dfe4c 100644 --- a/src/sim65816.c +++ b/src/sim65816.c @@ -21,18 +21,31 @@ extern char g_config_gsplus_screenshot_dir[]; #define vsnprintf _vsnprintf #endif -#ifdef HAVE_TFE - #include "tfe/tfesupp.h" - #include "tfe/protos_tfe.h" +#ifdef HAVE_RAWNET + #include "rawnet/rawnet.h" + #include "rawnet/cs8900.h" #endif -#if defined (_WIN32) && !defined(WIN_SDL)|| defined(__CYGWIN__) && !defined(WIN_SDL) +#if defined(_WIN32) && !defined(HAVE_SDL) #define WIN32_LEAN_AND_MEAN /* Tell windows we want less header gunk */ #define STRICT /* Tell Windows we want compile type checks */ #include /* Need a definition for LPTSTR in CYGWIN */ extern void get_cwd(LPTSTR buffer, int size); #endif +#ifndef GSPLUS_DEBUGGER +int g_dbg_enable_port = 0; + +void debug_server_poll(void) { } +int debug_events_waiting(void) { return 0; } +void debug_handle_event(void) { } +void debug_init(void) { } +void do_go_debug(void) { } + +#endif + + + #define PC_LOG_LEN (8*1024) int g_speed_fast; // OG Expose fast parameter @@ -69,7 +82,6 @@ const char *g_gsplus_default_paths[] = { // probably overkill on the paths #define EV_VID_UPD 7 extern int g_stepping; -extern int g_dbg_step; extern int g_c068_statereg; @@ -142,7 +154,8 @@ int g_iw2_emul = 0; int g_serial_out_masking = 0; int g_serial_modem[2] = { 0, 1 }; int g_ethernet = 0; -int g_ethernet_interface = 0; +char* g_ethernet_interface = ""; +int g_ethernet_enabled = 0; int g_parallel = 0; int g_parallel_out_masking = 0; int g_printer = 0; @@ -306,6 +319,7 @@ void sim65816_initglobals() { g_mem_size_total = 256*1024; /* Total contiguous RAM from 0 */ } +#if 0 void show_pc_log() { FILE *pcfile; Pc_log *log_pc_ptr; @@ -399,7 +413,7 @@ void show_pc_log() { fclose(pcfile); } - +#endif #define TOOLBOX_LOG_LEN 64 @@ -469,30 +483,6 @@ void show_toolbox_log() { } } -#if 0 -/* get_memory_c is not used, get_memory_asm is, but this does what the */ -/* assembly language would do */ -word32 get_memory_c(word32 loc, int diff_cycles) { - byte *addr; - word32 result; - int index; - -#ifdef CHECK_BREAKPOINTS - check_breakpoints_c(loc); -#endif - - index = loc >> 8; - result = page_info[index].rd; - if(result & BANK_IO_BIT) { - return get_memory_io(loc, diff_cycles); - } - - addr = (byte *)((result & 0xffffff00) + (loc & 0xff)); - - return *addr; -} -#endif - word32 get_memory_io(word32 loc, double *cyc_ptr) { int tmp; @@ -541,71 +531,6 @@ word32 get_memory_io(word32 loc, double *cyc_ptr) { return 0; } -#if 0 -word32 get_memory16_pieces(word32 loc, int diff_cycles) { - return(get_memory_c(loc, diff_cycles) + - (get_memory_c(loc+1, diff_cycles) << 8)); -} - -word32 get_memory24(word32 loc, int diff_cycles) { - return(get_memory_c(loc, diff_cycles) + - (get_memory_c(loc+1, diff_cycles) << 8) + - (get_memory_c(loc+2, diff_cycles) << 16)); -} -#endif - -#if 0 -void set_memory(word32 loc, int val, int diff_cycles) { - byte *ptr; - word32 new_addr; - word32 tmp; - word32 or_val; - int or_pos; - int old_slow_val; - -#ifdef CHECK_BREAKPOINTS - check_breakpoints_c(loc); -#endif - - tmp = GET_PAGE_INFO_WR((loc>>8) & 0xffff); - if(tmp & BANK_IO) { - set_memory_io(loc, val, diff_cycles); - return; - } - - if((loc & 0xfef000) == 0xe0c000) { - printf("set_memory_special: non-io for addr %08x, %02x, %d\n", - loc, val, diff_cycles); - halt_printf("tmp: %08x\n", tmp); - } - - ptr = (byte *)(tmp & (~0xff)); - - new_addr = loc & 0xffff; - old_slow_val = val; - - if(tmp & BANK_SHADOW) { - old_slow_val = g_slow_memory_ptr[new_addr]; - } else if(tmp & BANK_SHADOW2) { - new_addr += 0x10000; - old_slow_val = g_slow_memory_ptr[new_addr]; - } - - if(old_slow_val != val) { - g_slow_memory_ptr[new_addr] = val; - or_pos = (new_addr >> SHIFT_PER_CHANGE) & 0x1f; - or_val = DEP1(1, or_pos, 0); - if((new_addr >> CHANGE_SHIFT) >= SLOW_MEM_CH_SIZE) { - printf("new_addr: %08x\n", new_addr); - exit(12); - } - slow_mem_changed[(new_addr & 0xffff) >> CHANGE_SHIFT] |= or_val; - } - - ptr[loc & 0xff] = val; - -} -#endif void set_memory_io(word32 loc, int val, double *cyc_ptr) { word32 tmp; @@ -653,25 +578,6 @@ void set_memory_io(word32 loc, int val, double *cyc_ptr) { } -#if 0 -void check_breakpoints_c(word32 loc) { - int index; - int count; - int i; - - index = (loc & (MAX_BP_INDEX-1)); - count = breakpoints[index].count; - if(count) { - for(i = 0; i < count; i++) { - if(loc == breakpoints[index].addrs[i]) { - halt_printf("Write hit breakpoint %d!\n", i); - } - } - } -} -#endif - - void show_regs_act(Engine_reg *eptr) { int tmp_acc, tmp_x, tmp_y, tmp_psw; int kpc; @@ -760,7 +666,6 @@ void do_reset() { engine.kpc = get_memory16_c(0x00fffc, 0); g_stepping = 0; - g_dbg_step = 0; if (g_irq_pending) halt_printf("*** irq remainings...\n"); @@ -797,6 +702,7 @@ void check_engine_asm_defines() { CHECK(eptr, eptr->direct, ENGINE_REG_DIRECT, val1, val2); CHECK(eptr, eptr->psr, ENGINE_REG_PSR, val1, val2); CHECK(eptr, eptr->kpc, ENGINE_REG_KPC, val1, val2); + CHECK(eptr, eptr->flags, ENGINE_FLAGS, val1, val2); pcptr = &pclog; CHECK(pcptr, pcptr->dbank_kpc, LOG_PC_DBANK_KPC, val1, val2); @@ -884,8 +790,6 @@ void banner() { int gsplusmain(int argc, char **argv) { int diff; - int skip_amt; - int i; char *final_arg = 0; @@ -944,31 +848,23 @@ int gsplusmain(int argc, char **argv) { } printer_init(g_printer_dpi,85,110,g_printer_output,g_printer_multipage != 0); //If ethernet is enabled in config.gsport, let's initialize it -#ifdef HAVE_TFE - if (g_ethernet == 1) +#ifdef HAVE_RAWNET + g_ethernet_enabled = 0; + /* todo - pass device name via cmd line? */ + if (g_ethernet) { - int i = 0; - char *ppname = NULL; - char *ppdes = NULL; - if (tfe_enumadapter_open()) - { - //Loop through the available adapters until we reach the interface number specified in config.gsport - while(tfe_enumadapter(&ppname,&ppdes)) - { - if (i == g_ethernet_interface) break; - i++; - } - tfe_enumadapter_close(); - printf("Using host ethernet interface: %s\nUthernet support is ON.\n",ppdes); + if (!g_ethernet_interface || !*g_ethernet_interface) { + g_ethernet_interface = rawnet_get_standard_interface(); } - else - { - printf("No ethernet host adapters found. Do you have PCap installed/enabled?\nUthernet support is OFF.\n"); + + if (g_ethernet_interface && *g_ethernet_interface) { + if (cs8900_init() >= 0 && cs8900_activate(g_ethernet_interface) >= 0) { + g_ethernet_enabled = 1; + } else { + glogf("Unable to start ethernet (%s).\n", g_ethernet_interface); + } } - set_tfe_interface(ppname); //Connect the emulated ethernet device with the selected host adapter - lib_free(ppname); - lib_free(ppdes); - tfe_init(); + } #endif @@ -992,7 +888,6 @@ int gsplusmain(int argc, char **argv) { do_reset(); g_stepping = 0; - g_dbg_step = 0; // OG Notify emulator has been initialized and ready to accept external events g_initialized = 1; @@ -1003,8 +898,6 @@ int gsplusmain(int argc, char **argv) { do_go_debug(); } else { do_go(); - /* If we get here, we hit a breakpoint, call debug intfc */ - do_debug_intfc(); } // OG Notify emulator is being closed, and cannot accept events anymore @@ -1020,6 +913,13 @@ int gsplusmain(int argc, char **argv) { load_roms_shut_memory(); clear_fatal_logs(); +#if HAVE_RAWNET + if (g_ethernet_enabled) { + cs8900_deactivate(); + cs8900_shutdown(); + } +#endif + // OG Not needed anymore : the emulator will quit gently //my_exit(0); end_screen(); @@ -1095,7 +995,7 @@ void gsport_expand_path(char *out_ptr, const char *in_ptr, int maxlen) { if(!strncmp("0", name_buf, 128)) { /* Replace ${0} with g_argv0_path */ tmp_ptr = &(g_argv0_path[0]); -#if defined (_WIN32) && !defined(WIN_SDL)|| defined(__CYGWIN__) && !defined(WIN_SDL) +#if defined(_WIN32) && !defined(HAVE_SDL) } else if(!strncmp("PWD", name_buf, 128)) { /* Replace ${PWD} with cwd in Windows */ get_cwd(out_ptr,128); @@ -1464,7 +1364,7 @@ void setup_zip_speeds() { } } -void run_prog() { +int run_prog() { Fplus *fplus_ptr; Event *this_event; Event *db1; @@ -1576,7 +1476,7 @@ void run_prog() { engine.fcycles = prerun_fcycles; fcycles_stop = (g_event_start.next->dcycs - g_last_vbl_dcycs) + 0.001; - if(g_stepping || g_dbg_step < 0) { + if(g_stepping || engine.flags) { fcycles_stop = prerun_fcycles; } g_fcycles_stop = fcycles_stop; @@ -1612,13 +1512,14 @@ void run_prog() { if(ret != 0) { g_engine_action++; handle_action(ret); + ret >>= 28; } - if(halt_sim == HALT_EVENT) { + if(halt_sim & HALT_EVENT) { g_engine_halt_event++; /* if we needed to stop to check for interrupts, */ /* clear halt */ - halt_sim = 0; + halt_sim &= ~HALT_EVENT; } #if 0 @@ -1635,10 +1536,10 @@ void run_prog() { this_event = g_event_start.next; while(dcycs >= this_event->dcycs) { - if(halt_sim != 0 && halt_sim != HALT_EVENT) { + if(halt_sim & ~HALT_EVENT) { break; } - if(g_stepping || g_dbg_step != 0) { + if(g_stepping) { printf("HIT STEPPING BREAK!\n"); break; } @@ -1705,19 +1606,36 @@ void run_prog() { } #endif - if(halt_sim != 0 && halt_sim != HALT_EVENT) { + + if (ret == RET_MP) break; + if (ret == RET_BP) break; + if (ret == RET_BRK) break; + if (ret == RET_COP) break; + engine.flags &= ~(FLAG_IGNORE_BP | FLAG_IGNORE_MP | FLAG_IGNORE_BRK); + if(g_stepping) { + ret = 0; break; } - if(g_stepping || g_dbg_step != 0) { + if (halt_sim & ~HALT_EVENT) { + if(halt_sim & 0x07) { + /* halt_printf() */ + halt_sim &= ~0x07; + ret = RET_HALT; + } break; } + } +#if 0 if(!g_testing) { printf("leaving run_prog, halt_sim:%d\n", halt_sim); } +#endif x_auto_repeat_on(0); + + return ret; } void add_irq(word32 irq_mask) { @@ -2321,6 +2239,7 @@ void init_reg() { engine.direct = 0; engine.psr = 0x134; engine.fplus_ptr = 0; + engine.flags = 0; } @@ -2330,9 +2249,6 @@ void handle_action(word32 ret) { type = EXTRU(ret,3,4); switch(type) { - case RET_BREAK: - do_break(ret & 0xff); - break; case RET_COP: do_cop(ret & 0xff); break; @@ -2350,14 +2266,6 @@ void handle_action(word32 ret) { case RET_C70D: do_c70d(ret); break; -#if 0 - case RET_ADD_DEC_8: - do_add_dec_8(ret); - break; - case RET_ADD_DEC_16: - do_add_dec_16(ret); - break; -#endif case RET_IRQ: irq_printf("Special fast IRQ response. irq_pending: %x\n", g_irq_pending); @@ -2368,6 +2276,12 @@ void handle_action(word32 ret) { case RET_STP: do_stp(); break; + case RET_BP: + case RET_MP: + case RET_BRK: + case RET_HALT: + /* handled elsewhere */ + break; default: halt_printf("Unknown special action: %08x!\n", ret); } diff --git a/src/sound.c b/src/sound.c index 2b113a2..a66ff68 100644 --- a/src/sound.c +++ b/src/sound.c @@ -32,8 +32,7 @@ int g_queued_nonsamps = 0; int g_num_osc_interrupting = 0; int g_sound_play_depth = 0; -/* Workaround - gcc in cygwin wasn't defining _WIN32, substituted WIN_SOUND instead */ -#if defined(HPUX) || defined(__linux__) || defined(WIN_SOUND) || defined(MAC) || defined(HAVE_SDL) +#if defined(HPUX) || defined(__linux__) || defined(_WIN32) || defined(MAC) || defined(HAVE_SDL) int g_audio_enable = -1; #else # if defined(OSS) @@ -243,8 +242,7 @@ void sound_init() { void sound_init_general() { -/* Workaround - gcc in cygwin wasn't defining _WIN32 */ -#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(HAVE_SDL) +#if !defined(_WIN32) && !defined(MAC) && !defined(HAVE_SDL) int pid; int shmid; int tmp; @@ -255,8 +253,7 @@ void sound_init_general() { int size; int ret; -/* Workaround - gcc in cygwin wasn't defining _WIN32 */ -#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(HAVE_SDL) +#if !defined(_WIN32) && !defined(MAC) && !defined(HAVE_SDL) if(!g_use_shmem) { if(g_audio_enable < 0) { printf("Defaulting audio off for slow X display\n"); @@ -273,8 +270,7 @@ void sound_init_general() { } size = SOUND_SHM_SAMP_SIZE * SAMPLE_CHAN_SIZE; -/* Workaround - gcc in cygwin wasn't defining _WIN32 */ -#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(HAVE_SDL) +#if !defined(_WIN32) && !defined(MAC) && !defined(HAVE_SDL) shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); if(shmid < 0) { printf("sound_init: shmget ret: %d, errno: %d\n", shmid, errno); @@ -303,8 +299,8 @@ void sound_init_general() { g_sound_shm_addr = shmaddr; fflush(stdout); -/* Workaround - gcc in cygwin wasn't defining _WIN32 */ -#if !defined(MAC) && !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(HAVE_SDL) + +#if !defined(MAC) && !defined(_WIN32) && !defined(HAVE_SDL) /* prepare pipe so parent can signal child each other */ /* pipe[0] = read side, pipe[1] = write end */ ret = pipe(&g_pipe_fd[0]); @@ -356,9 +352,9 @@ void sound_init_general() { #else # if defined (HAVE_SDL) sdlsnd_init(shmaddr); -# elif defined (WIN_SOUND) +# elif defined (_WIN32) win32snd_init(shmaddr); -# elif defined (MAC) && !defined(HAVE_SDL) +# elif defined (MAC) macsnd_init(shmaddr); # endif #endif @@ -419,13 +415,14 @@ void sound_shutdown() { // OG stop sound and free memory on sound_shutdown sound_reset(g_cur_dcycs); -#ifdef WIN_SOUND /* Workaround - gcc in cygwin wasn't defining _WIN32 */ - win32snd_shutdown(); -#elif defined(HAVE_SDL) + +#if defined(HAVE_SDL) if((g_audio_enable != 0)) { //sdlsnd_shutdown(); sound_shutdown_sdl(); } +#elif defined(_WIN32) + win32snd_shutdown(); #else if((g_audio_enable != 0) && g_pipe_fd[1] != 0) { close(g_pipe_fd[1]); @@ -607,11 +604,11 @@ void send_sound(int real_samps, int size) { } DOC_LOG("send_sound", -1, g_last_sound_play_dsamp, (real_samps << 30) + size); -// Workaround - gcc in cygwin wasn't defining _WIN32 -#if defined(WIN_SOUND) || defined(MAC) && !defined(HAVE_SDL) - child_sound_playit(tmp); -#elif defined(HAVE_SDL) + +#if defined(HAVE_SDL) sound_write_sdl( real_samps, size); +#elif defined(_WIN32) || defined(MAC) + child_sound_playit(tmp); #else /* Although this looks like a big/little-endian issue, since the */ /* child is also reading an int, it just works with no byte swap */ diff --git a/src/sound_driver.c b/src/sound_driver.c index 322af25..b60a531 100644 --- a/src/sound_driver.c +++ b/src/sound_driver.c @@ -21,7 +21,7 @@ long sound_init_device_sdl(); # include #endif -#ifndef WIN_SOUND /* Workaround - gcc in cygwin wasn't defining _WIN32 */ +#ifndef _WIN32 # include # include #endif @@ -77,9 +77,9 @@ void reliable_buf_write(word32 *shm_addr, int pos, int size) { #if defined(HAVE_SDL) //ret = sdl_send_audio(ptr, size); -#elif defined(WIN_SOUND) +#elif defined(_WIN32) ret = win32_send_audio(ptr, size); -#elif defined(MAC) && !defined(HAVE_SDL) +#elif defined(MAC) ret = mac_send_audio(ptr, size); #else ret = write(g_audio_socket, ptr, size); @@ -129,10 +129,10 @@ void child_sound_loop(int read_fd, int write_fd, word32 *shm_addr) { child_sound_init_linux(); #elif HPUX child_sound_init_hpdev(); -#elif WIN_SOUND +#elif defined(_WIN32) child_sound_init_win32(); return; -#elif defined(MAC) && !defined(HAVE_SDL) +#elif defined(MAC) child_sound_init_mac(); return; #endif diff --git a/src/tfe/CMakeLists.txt b/src/tfe/CMakeLists.txt index 80df2c3..ea0c249 100644 --- a/src/tfe/CMakeLists.txt +++ b/src/tfe/CMakeLists.txt @@ -4,3 +4,7 @@ add_library(tfe tfe.c tfearch.c tfesupp.c) target_compile_definitions(tfe PUBLIC HAVE_TFE) +if(WIN32) + target_include_directories(tfe PRIVATE ../rawnet/include) + target_link_libraries(tfe ws2_32) # winsock2 +endif() \ No newline at end of file diff --git a/src/tfe/tfe.vcxproj b/src/tfe/tfe.vcxproj deleted file mode 100644 index 55aa273..0000000 --- a/src/tfe/tfe.vcxproj +++ /dev/null @@ -1,108 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {E810477A-E004-4308-A58A-21393213EF89} - Win32Proj - tfe - - - - StaticLibrary - true - MultiByte - v120 - - - StaticLibrary - false - true - MultiByte - v120 - - - - - - - - - - - - - true - - - false - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;TFE_EXPORTS;%(PreprocessorDefinitions) - Speed - false - ProgramDatabase - Default - CompileAsC - true - true - false - - - Windows - true - - - - - Level3 - NotUsing - Full - true - true - WIN32;NDEBUG;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;TFE_EXPORTS;%(PreprocessorDefinitions) - Speed - CompileAsC - false - StreamingSIMDExtensions - AnySuitable - true - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tfe/tfe.vcxproj.filters b/src/tfe/tfe.vcxproj.filters deleted file mode 100644 index 78f75f4..0000000 --- a/src/tfe/tfe.vcxproj.filters +++ /dev/null @@ -1,54 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - diff --git a/src/to_pro.c b/src/to_pro.c index c74f70b..3beb9e3 100755 --- a/src/to_pro.c +++ b/src/to_pro.c @@ -16,6 +16,11 @@ #include #endif +#ifdef _MSC_VER +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + #define DEF_DISK_SIZE (800*1024) #define MAX_FILE_NAMES 51 diff --git a/src/unix_host_common.c b/src/unix_host_common.c index c5075d9..30523c0 100644 --- a/src/unix_host_common.c +++ b/src/unix_host_common.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #if defined(__APPLE__) #include @@ -510,3 +512,58 @@ unsigned host_storage_type(const char *path, word16 *error) { *error = badStoreType; return 0; } + + +/* + * error remapping. + * NOTE - GS/OS errors are a superset of P8 errors + */ + +static word32 enoent(const char *path) { + /* + some op on path return ENOENT. check if it's + fileNotFound or pathNotFound + */ + char *p = (char *)path; + for(;;) { + struct stat st; + p = dirname(p); + if (p == NULL) break; + if (p[0] == '.' && p[1] == 0) break; + if (p[0] == '/' && p[1] == 0) break; + if (stat(p, &st) < 0) return pathNotFound; + } + return fileNotFound; +} + +word32 host_map_errno(int xerrno) { + switch(xerrno) { + case 0: return 0; + case EBADF: + return invalidAccess; +#ifdef EDQUOT + case EDQUOT: +#endif + case EFBIG: + return volumeFull; + case ENOENT: + return fileNotFound; + case ENOTDIR: + return pathNotFound; + case ENOMEM: + return outOfMem; + case EEXIST: + return dupPathname; + case ENOTEMPTY: + return invalidAccess; + + default: + return drvrIOError; + } +} + +word32 host_map_errno_path(int xerrno, const char *path) { + if (xerrno == ENOENT) return enoent(path); + return host_map_errno(xerrno); +} + diff --git a/src/vars_c b/src/vars_c deleted file mode 100644 index cd0743e..0000000 --- a/src/vars_c +++ /dev/null @@ -1,20 +0,0 @@ - -TARGET = gsportx -OBJECTS = $(OBJECTS1) xdriver.o -CC = gcc -CCOPTS = -O -OPTS = -DNDEBUG -SUFFIX = -NAME = gsportx -LDFLAGS = -LDOPTS = -z -LD = $(CC) -EXTRA_LIBS = -lXext -lX11 -lcl -lc -EXTRA_SPECIALS = Alib.h - -AS = cc -Ae -PERL = perl - -XOPTS = -DHPUX -I/usr/include/X11R5 -XLIBS = -L/usr/lib/X11R5 -L/opt/audio/lib - 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 - diff --git a/src/vars_kegs32 b/src/vars_kegs32 deleted file mode 100644 index b435b20..0000000 --- a/src/vars_kegs32 +++ /dev/null @@ -1,10 +0,0 @@ - -TARGET = gsport.exe -OBJECTS = $(OBJECTS1) win32snd_driver.o windriver.o gsport32.o -CCOPTS = -O2 -DGSPLUS_LITTLE_ENDIAN -SUFFIX = ".exe" -NAME = gsport - -XOPTS = -Wall -fomit-frame-pointer -march=pentium -XLIBS = - diff --git a/src/vars_linuxppc b/src/vars_linuxppc deleted file mode 100644 index 4bf50c2..0000000 --- a/src/vars_linuxppc +++ /dev/null @@ -1,20 +0,0 @@ - -TARGET = gsportx -OBJECTS = $(OBJECTS1) xdriver.o -CC = cc -CCOPTS = -O -OPTS = -DNDEBUG -SUFFIX = -NAME = gsportx -LDFLAGS = -LDOPTS = -LD = $(CC) -EXTRA_LIBS = -lXext -lX11 -lc -EXTRA_SPECIALS = - -AS = cc -PERL = perl - -XOPTS = -I/usr/X11R6/include -XLIBS = -L/usr/X11R6/lib - diff --git a/src/vars_mac b/src/vars_mac deleted file mode 100644 index 3ecf9dd..0000000 --- a/src/vars_mac +++ /dev/null @@ -1,18 +0,0 @@ -# -# There is some very useful information on compilation on the Mac, where we need -# to take a lot of things into account (bitness, OS level, endianness), here: -# http://www.kyngchaos.com/macosx/notes/universal64 -# -CC = /usr/bin/g++-4.0 -ARCH = -arch i386 -arch ppc -SDK = -isysroot /Developer/SDKs/MacOSX10.4u.sdk -isysroot /Developer/SDKs/MacOSX10.5.sdk -TARGET = gsportmac -OBJECTS = $(OBJECTS1) scc_macdriver.o macsnd_driver.o macdriver_generic.o macdriver_console.o -CCOPTS = -O2 -DMAC $(ARCH) $(SDK) -CPPOPTS = $(ARCH) $(SDK) -SUFFIX = -NAME = gsportmac - -XOPTS = -Wall -fpascal-strings -mdynamic-no-pic -XLIBS = -LDOPTS = -I. -prebind -framework Carbon -framework Quicktime diff --git a/src/vars_osx_sdl2 b/src/vars_osx_sdl2 deleted file mode 100644 index c33fca7..0000000 --- a/src/vars_osx_sdl2 +++ /dev/null @@ -1,21 +0,0 @@ -TARGET = gsplus -NAME = gsplus -PERL = perl -CC = clang -LD = clang++ -AS = cc - -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o fix_mac_menu.o -ARCHS = ppc, i386, ppc64, x86_64 - -# OPTIONS FOR COMPILING C SOURCE -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_ICON -DHAVE_SDL `sdl2-config --cflags` -# OPTIONS FOR COMPILING C++ SOURCE -CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL `freetype-config --cflags` `sdl2-config --cflags` - -EXTRA_LIBS = -lSDL2_image -OPTS = -DGSPLUS_LITTLE_ENDIAN -SUFFIX = -LDFLAGS = `sdl2-config --static-libs` `freetype-config --libs` -framework Cocoa -LDOPTS = -EXTRA_SPECIALS = diff --git a/src/vars_osx_x11 b/src/vars_osx_x11 deleted file mode 100644 index 937925c..0000000 --- a/src/vars_osx_x11 +++ /dev/null @@ -1,20 +0,0 @@ -TARGET = gsplusx -NAME = gsportx -PERL = perl -CC = clang -LD = g++ -AS = cc - - -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) xdriver.o -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_SDL -DTOGGLE_STATUS -I/usr/local/include/SDL2 -I/usr/local/include/freetype2 -L/usr/X11/lib -CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -I/usr/local/include/freetype2 -I/usr/local/include/SDL2 -OPTS = -DGSPLUS_LITTLE_ENDIAN -SUFFIX = -LDFLAGS = -LDOPTS = -EXTRA_LIBS = -lX11 -lfreetype -lSDL2 -lpcap -lXext -EXTRA_SPECIALS = - - -XOPTS = -I/usr/X11/include diff --git a/src/vars_pi b/src/vars_pi deleted file mode 100644 index f35f807..0000000 --- a/src/vars_pi +++ /dev/null @@ -1,17 +0,0 @@ -TARGET = gsportx -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) xdriver.o -CC = gcc -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=armv6 -OPTS = -DGSPLUS_LITTLE_ENDIAN -DHAVE_TFE -DTOGGLE_STATUS -DHAVE_ATBRIDGE -SUFFIX = -NAME = gsportx -LDFLAGS = -LDOPTS = -LD = g++ -EXTRA_LIBS = -lXext -EXTRA_SPECIALS = - -AS = cc -PERL = perl - -XOPTS = -I/usr/X11R6/include diff --git a/src/vars_rpilinux_fb b/src/vars_rpilinux_fb deleted file mode 100644 index 442bebc..0000000 --- a/src/vars_rpilinux_fb +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = gsplusfb -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) fbdriver.o -CC = gcc -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=armv6 -OPTS = -DGSPLUS_LITTLE_ENDIAN -DHAVE_TFE -DHAVE_ATBRIDGE -SUFFIX = -NAME = gsportfb -LDFLAGS = -LDOPTS = -LD = g++ -EXTRA_LIBS = -ldl -EXTRA_SPECIALS = - -AS = cc -PERL = perl - -XOPTS = -I/usr/X11R6/include - diff --git a/src/vars_rpilinux_sdl2 b/src/vars_rpilinux_sdl2 deleted file mode 100644 index 1fa1fe0..0000000 --- a/src/vars_rpilinux_sdl2 +++ /dev/null @@ -1,16 +0,0 @@ -TARGET = gsplus -NAME = gsplus -PERL = perl -CC = gcc -LD = g++ -#LD = gcc -AS = cc - -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=armv6 -OPTS = -DGSPLUS_LITTLE_ENDIAN -DHAVE_TFE -DHAVE_ATBRIDGE -DHAVE_SDL -I/usr/include/SDL2 -I/usr/include/freetype2 - -EXTRA_LIBS = -ldl -lfreetype -lSDL2 -lSDL2_image - -XOPTS = -I/usr/X11R6/include - diff --git a/src/vars_solaris b/src/vars_solaris deleted file mode 100644 index b9e3761..0000000 --- a/src/vars_solaris +++ /dev/null @@ -1,20 +0,0 @@ - -TARGET = gsportx -OBJECTS = $(OBJECTS1) xdriver.o -CC = cc -CCOPTS = -O -OPTS = -DNDEBUG -DSOLARIS -SUFFIX = -NAME = gsportx -LDFLAGS = -LDOPTS = -LD = $(CC) -EXTRA_LIBS = -lXext -lX11 -lsocket -lnsl -EXTRA_SPECIALS = - -AS = cc -PERL = perl - -XOPTS = -I/usr/X/include -XLIBS = -L/usr/X/lib - diff --git a/src/vars_win32 b/src/vars_win32 deleted file mode 100644 index 2b535f0..0000000 --- a/src/vars_win32 +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = gsplus32.exe - -FSTOBJ = host_common.o win32_host_common.o host_mli.o win32_host_fst.o - -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) scc_windriver.o win32snd_driver.o win_console.o win_generic.o gsplus32.o -CCOPTS = -O2 -DGSPLUS_LITTLE_ENDIAN -DHAVE_TFE -DWIN_SOUND -DTOGGLE_STATUS -DWIN32 -D_WIN32 -D__USE_W32_SOCKETS -D_WINSOCK2API_ -std=gnu99 -DHAVE_ATBRIDGE -CPPOPTS = -O2 -DGSPLUS_LITTLE_ENDIAN -DHAVE_TFE -DTOGGLE_STATUS -DWIN32 -D_WIN32 -D__USE_W32_SOCKETS -D_WINSOCK2API_ -DHAVE_ATBRIDGE - -SUFFIX = ".exe" -NAME = gsplus32 -EXTRA_LIBS = -Larch/win32 -lcomdlg32 -lShlwapi -lIPHlpApi - -XOPTS = -Wall -fomit-frame-pointer -march=i686 -XLIBS = diff --git a/src/vars_win32_sdl b/src/vars_win32_sdl deleted file mode 100644 index 7205507..0000000 --- a/src/vars_win32_sdl +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = gsplus.exe -NAME = gsplus - -FSTOBJ = win32_host_fst.o - -OBJECTS = sdl2_driver.o $(OBJECTS1) $(FSTOBJ) sdl2snd_driver.o - -CCOPTS = -O2 -DGSPLUS_LITTLE_ENDIAN -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I/usr/include/SDL2 -L/cygdrive/c/mingw/lib -I/cygdrive/c/mingw/include/SDL2/ -CPPOPTS = -O2 -DGSPLUS_LITTLE_ENDIAN -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I/usr/include/freetype2 -L/cygdrive/c/mingw/lib -I/cygdrive/c/mingw/include/SDL2/ - -SUFFIX = ".exe" -EXTRA_LIBS = -Larch/win32 -lSDL2main -lSDL2 -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -lcygwin -EXTRA_LIBS = -L/usr/local/lib -lcygwin -lSDL2main -lSDL2 -mwindows -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -L/usr/lib -lpthread -lSDL2_image -L/cygdrive/c/mingw/lib -I/cygdrive/c/mingw/include/SDL2/ - - - -XOPTS = -Wall -fomit-frame-pointer -march=i686 -XLIBS = diff --git a/src/vars_win32_sdl2 b/src/vars_win32_sdl2 deleted file mode 100644 index 575d083..0000000 --- a/src/vars_win32_sdl2 +++ /dev/null @@ -1,21 +0,0 @@ -TARGET = gsplus.exe -NAME = gsplus - -MINGW_HOME = /cygdrive/c/mingw/i686-w64-mingw32 - -FSTOBJ = host_common.o win32_host_common.o host_mli.o win32_host_fst.o - -OBJECTS = sdl2_driver.o $(OBJECTS1) $(FSTOBJ) sdl2snd_driver.o scc_windriver.o - -CCOPTS = -O3 -DGSPLUS_LITTLE_ENDIAN -DWIN32 -D_WIN32 -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I$(MINGW_HOME)/include/SDL2 -DWINSDL_BORDERHACK -D__USE_W32_SOCKETS -D_WINSOCK2API_ -CPPOPTS = -O3 -DGSPLUS_LITTLE_ENDIAN -DWIN32 -D_WIN32 -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I/usr/include/freetype2 -I$(MINGW_HOME)/include/SDL2 -D__USE_W32_SOCKETS -D_WINSOCK2API_ - -SUFFIX = ".exe" -# working in cygwin -EXTRA_LIBS = -lcygwin -lSDL2main -lSDL2 -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -lpthread -lSDL2_image -L$(MINGW_HOME)/lib/ -EXTRA_LIBS = -lcygwin -lSDL2main -lSDL2 -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -lpthread -lSDL2_image -L$(MINGW_HOME)/lib/ -Larch/win32 -lshell32 - - - -#XOPTS = -Wall -fomit-frame-pointer -march=i686 -XLIBS = diff --git a/src/vars_x86linux_sdl b/src/vars_x86linux_sdl deleted file mode 100644 index 36b404f..0000000 --- a/src/vars_x86linux_sdl +++ /dev/null @@ -1,24 +0,0 @@ -TARGET = gsplus -NAME = gsplus -PERL = perl -CC = gcc -LD = g++ -AS = cc - -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o - -# C Compiler Options -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_SDL -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS -I/usr/include/SDL2 -I/usr/include/freetype2 -# C++ Compiler Options -CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -DHAVE_ATBRIDGE -I/usr/include/freetype2 -I/usr/include/SDL2 - -EXTRA_LIBS = -lfreetype -lSDL2 -lSDL2_image -ldl -OPTS = -DGSPLUS_LITTLE_ENDIAN -SUFFIX = -LDFLAGS = -LDOPTS = - -EXTRA_SPECIALS = - - -XOPTS = -I/usr/X11R6/include diff --git a/src/vars_x86linux_sdl2 b/src/vars_x86linux_sdl2 deleted file mode 100644 index ba34915..0000000 --- a/src/vars_x86linux_sdl2 +++ /dev/null @@ -1,21 +0,0 @@ -TARGET = gsplus -NAME = gsplus -PERL = perl -CC = gcc -LD = gcc -AS = cc - -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o - -# C Compiler Options -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_SDL -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS -I/usr/include/SDL2 -I/usr/include/freetype2 -# C++ Compiler Options -CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -DHAVE_ATBRIDGE -I/usr/include/freetype2 -I/usr/include/SDL2 - - -EXTRA_LIBS = -lfreetype -lSDL2 -lSDL2_image -ldl -lm -lstdc++ -OPTS = -DGSPLUS_LITTLE_ENDIAN -SUFFIX = -LDFLAGS = -LDOPTS = -I. -EXTRA_SPECIALS = diff --git a/src/vars_x86linux_x11 b/src/vars_x86linux_x11 deleted file mode 100644 index 766c6c2..0000000 --- a/src/vars_x86linux_x11 +++ /dev/null @@ -1,21 +0,0 @@ -TARGET = gsplusx -NAME = gsplusx -PERL = perl -CC = gcc -LD = g++ -AS = cc - -OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) xdriver.o -#-march=i686 is causing "error: CPU you selected does not support x86-64 instruction set" on ubuntu -#CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=i686 -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS -CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS -OPTS = -DGSPLUS_LITTLE_ENDIAN -SUFFIX = -LDFLAGS = -LDOPTS = -# added -ldl for ubuntu -EXTRA_LIBS = -lXext -ldl -EXTRA_SPECIALS = - - -XOPTS = -I/usr/X11R6/include diff --git a/src/vars_x86solaris b/src/vars_x86solaris deleted file mode 100644 index 274519e..0000000 --- a/src/vars_x86solaris +++ /dev/null @@ -1,20 +0,0 @@ - -TARGET = gsportx -OBJECTS = $(OBJECTS1) $(FSTOBJ) xdriver.o -CC = gcc -CCOPTS = -O -OPTS = -DNDEBUG -DSOLARIS -DGSPLUS_LITTLE_ENDIAN -DSOLARISSOUND -SUFFIX = -NAME = gsportx -LDFLAGS = -LDOPTS = -LD = $(CC) -EXTRA_LIBS = -lXext -lX11 -lsocket -lnsl -EXTRA_SPECIALS = - -AS = cc -PERL = perl - -XOPTS = -I/usr/X/include -XLIBS = -L/usr/X/lib - diff --git a/src/win32.rc b/src/win32.rc index 271edf5..c608827 100644 --- a/src/win32.rc +++ b/src/win32.rc @@ -65,8 +65,8 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDC_GSPORT32 ICON DISCARDABLE "gsp_icon.ico" -GSPORT32_ICON ICON DISCARDABLE "gsp_icon.ico" +IDC_GSPORT32 ICON DISCARDABLE "assets/gsp_icon.ico" +GSPORT32_ICON ICON DISCARDABLE "assets/gsp_icon.ico" ///////////////////////////////////////////////////////////////////////////// // diff --git a/src/win32_host_common.c b/src/win32_host_common.c index 1b3e016..7e22cc5 100644 --- a/src/win32_host_common.c +++ b/src/win32_host_common.c @@ -11,6 +11,11 @@ #include "host_common.h" +#ifdef _MSC_VER +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + void afp_init(struct AFP_Info *info, word16 file_type, word32 aux_type) { @@ -66,7 +71,7 @@ void afp_synchronize(struct AFP_Info *info, int preference) { -static DWORD root_file_id[3] = {}; +static DWORD root_file_id[3] = { 0 }; unsigned host_startup(void) { @@ -97,10 +102,8 @@ unsigned host_startup(void) { if (!(fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { fprintf(stderr, "%s is not a directory\n", host_root); - CloseHandle(h); return invalidFSTop; } - CloseHandle(h); return 0; } @@ -231,8 +234,8 @@ FILETIME host_get_date_time(word32 ptr) { TzSpecificLocalTimeToSystemTime(NULL, &tmLocal, &tmUTC); - if (!SystemTimeToFileTime(&tmUTC, &utc)) utc =(FILETIME){0, 0}; - + if (!SystemTimeToFileTime(&tmUTC, &utc)) memset(&utc, 0, sizeof(utc)); + return utc; } @@ -249,6 +252,7 @@ FILETIME host_get_date_time_rec(word32 ptr) { SYSTEMTIME tmUTC; memset(&tmLocal, 0, sizeof(tmLocal)); memset(&tmUTC, 0, sizeof(tmUTC)); + memset(&utc, 0, sizeof(utc)); tmLocal.wSecond = buffer[0]; tmLocal.wMinute = buffer[1]; @@ -258,7 +262,7 @@ FILETIME host_get_date_time_rec(word32 ptr) { tmLocal.wMonth = buffer[5] + 1; TzSpecificLocalTimeToSystemTime(NULL, &tmLocal, &tmUTC); - if (!SystemTimeToFileTime(&tmUTC, &utc)) utc =(FILETIME){0, 0}; + if (!SystemTimeToFileTime(&tmUTC, &utc)) memset(&utc, 0, sizeof(utc)); return utc; } diff --git a/src/win32_host_fst.c b/src/win32_host_fst.c index 05f3360..8922a65 100644 --- a/src/win32_host_fst.c +++ b/src/win32_host_fst.c @@ -20,6 +20,12 @@ #include "host_common.h" +#ifdef _MSC_VER +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + + extern Engine_reg engine; @@ -62,7 +68,7 @@ static struct directory *read_directory(const char *path, word16 *error); #define COOKIE_BASE 0x8000 -static word32 cookies[32] = {}; +static word32 cookies[32] = { 0 }; static int alloc_cookie() { for (int i = 0; i < 32; ++i) { @@ -746,7 +752,7 @@ static struct directory *read_directory(const char *path, word16 *error) { size = sizeof(struct directory) + capacity * sizeof(char *); struct directory * tmp = realloc(dd, size); if (!tmp) { - *error = host_map_errno(errno); + *error = outOfMem; free_directory(dd); FindClose(h); return NULL; @@ -1207,11 +1213,11 @@ static word16 win_seek(HANDLE h, word16 base, word32 displacement, LARGE_INTEGER break; case markMinus: m = FILE_CURRENT; - d.QuadPart = -displacement; + d.QuadPart = -(LONGLONG)displacement; break; case eofMinus: m = FILE_END; - d.QuadPart = -displacement; + d.QuadPart = -(LONGLONG)displacement; break; default: diff --git a/src/win_console.c b/src/win_console.c index 983e6a6..e7fc274 100644 --- a/src/win_console.c +++ b/src/win_console.c @@ -15,6 +15,11 @@ #include "defc.h" #include "protos_windriver.h" +#include +#include +#include +#include +#include extern void gsportinit(HWND _hwnd); extern void gsportshut(); @@ -104,9 +109,198 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin return main(0,0); } -int main(int argc, char **argv) { +/* cygwin may have old headers ... */ +#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT +#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200 +#endif + +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif + +#ifndef DISABLE_NEWLINE_AUTO_RETURN +#define DISABLE_NEWLINE_AUTO_RETURN 0x0008 +#endif + + +#ifdef __CYGWIN__ + +static ssize_t handle_read(void *r, void *cookie, char *buffer, size_t size) { + + BOOL ok; + DWORD n; + ok = ReadConsole((HANDLE)cookie, buffer, size, &n, NULL); + if (!ok) { errno = EIO; return -1; } + return n; +} + +static ssize_t handle_write(void *r, void *cookie, const char *buffer, size_t size) { + + static char *crbuffer = NULL; + static int crbuffer_size = 0; + + BOOL ok; + DWORD n; + int crcount = 0; + int i, j; + + for (i = 0; i < size; ++i) { + if (buffer[i] == '\n') ++crcount; + } + + if (crcount) { + if (crbuffer_size < crcount + size) { + crbuffer = realloc(crbuffer, size + crcount); + if (!crbuffer) return -1; + crbuffer_size = crcount + size; + } + + for (i = 0, j = 0; i < size; ++i) { + char c = buffer[i]; + if (c == '\n') crbuffer[j++] = '\r'; + crbuffer[j++] = c; + } + } + + + ok = WriteConsole((HANDLE)cookie, crcount ? crbuffer : buffer, size + crcount, &n, NULL); + if (!ok) { errno = EIO; return -1; } + return size; +} + +#endif + +static void set_file_handle(FILE *fp, HANDLE h) { + + #ifdef __CYGWIN__ + fp->_file = -1; + fp->_cookie = (void *)h; + fp->_read = handle_read; + fp->_write = handle_write; + fp->_seek = NULL; + fp->_close = NULL; + #else + int fd = _open_osfhandle((intptr_t)h, _O_TEXT); + fp->_file = fd; + #endif +} + +int g_win32_cygwin; +void win_init_console(void) { + /* + powershell/cmd + fd 0/1/2 closed + GetStdHandle return 0 + stdin = -2, stdout = -2, stderr = -2 + + msys/cygwin + fd 0/1/2 open + GetStdHandle return value (type = 3/pipe) + stdin = 0, stdout = 1, stderr = 2 + */ + + //struct stat st; + //int ok; + int fd; + HANDLE h; + DWORD mode; + +#if 0 + FILE *dbg = fopen("debug.txt", "a+"); + h = GetStdHandle(STD_INPUT_HANDLE); + fprintf(dbg, "STD_INPUT_HANDLE: %p\n", h); + fprintf(dbg, "GetFileType: %08x\n", GetFileType(h)); + fprintf(dbg, "%d %d %d\n", stdin->_file, stdout->_file, stderr->_file); + fclose(dbg); +#endif + + g_win32_cygwin = 0; + + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); + setvbuf(stderr, NULL, _IOLBF, BUFSIZ); + +#if 0 + if (fstat(0, &st) == 0) { + g_win32_cygwin = 1; + return; + } +#endif + + SetStdHandle(STD_INPUT_HANDLE, 0); + SetStdHandle(STD_OUTPUT_HANDLE, 0); + SetStdHandle(STD_ERROR_HANDLE, 0); + #if 0 + stdin->_file = 0; + stdout->_file = 1; + stderr->_file = 2; + #endif + + + AllocConsole(); + SetConsoleTitle("GS+"); + + + h = GetStdHandle(STD_INPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + + mode = 0; + GetConsoleMode(h, &mode); + mode |= ENABLE_VIRTUAL_TERMINAL_INPUT; + SetConsoleMode(h, mode); + + set_file_handle(stdin, h); + } + + h = GetStdHandle(STD_OUTPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + + mode = 0; + GetConsoleMode(h, &mode); + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; + SetConsoleMode(h, mode); + + //SetConsoleTextAttribute(h, BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + set_file_handle(stdout, h); + } + + + h = GetStdHandle(STD_ERROR_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + + mode = 0; + GetConsoleMode(h, &mode); + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; + SetConsoleMode(h, mode); + + set_file_handle(stderr, h); + } + + +#if 0 + dbg = fopen("debug.txt", "a+"); + h = GetStdHandle(STD_INPUT_HANDLE); + fprintf(dbg, "STD_INPUT_HANDLE: %p\n", h); + fprintf(dbg, "GetFileType: %08x\n", GetFileType(h)); + fprintf(dbg, "%d %d %d\n", stdin->_file, stdout->_file, stderr->_file); + fclose(dbg); +#endif +} + + +static void exit_sleep(void) { + /* todo -- "press return to continue" */ + if (!g_win32_cygwin) + sleep(10); +} + +int main(int argc, char **argv) { // Hide the console initially to reduce window flashing. We'll show the console later if needed. - x_show_console(0); + + //atexit(exit_sleep); + win_init_console(); + + //x_show_console(0); + // Register the window class. WNDCLASS wndclass; @@ -144,13 +338,16 @@ int main(int argc, char **argv) { printf("...rect is: %ld, %ld, %ld, %ld\n", rect.left, rect.top, rect.right, rect.bottom); +#if 0 // Enable non-blocking, character-at-a-time console I/O. // win_nonblock_read_stdin() expects this behavior. DWORD mode; GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); mode &= ~ENABLE_LINE_INPUT; SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode); +#endif + hook = SetWindowsHookEx(WH_KEYBOARD_LL, win_ll_keyboard, NULL, 0); hook = SetWindowsHookEx(WH_KEYBOARD_LL, win_ll_keyboard, NULL, 0); @@ -160,6 +357,7 @@ int main(int argc, char **argv) { UnhookWindowsHookEx(hook); UnregisterClass(wndclass.lpszClassName,GetModuleHandle(NULL)); + gsportshut(); return ret; } diff --git a/src/win_generic.c b/src/win_generic.c index ee2a0c0..8ec9280 100644 --- a/src/win_generic.c +++ b/src/win_generic.c @@ -15,6 +15,8 @@ #include "defc.h" #include "protos.h" #include "protos_windriver.h" +#include "adb_keycodes.h" + #include "win_keymap.h" extern int Verbose; @@ -234,7 +236,7 @@ void win_event_key(HWND hwnd, UINT raw_vk, BOOL down, int repeat, UINT flags) capslock_down = GetKeyState(VK_CAPITAL) & 0x01; if(capslock_down != g_win_capslock_down) { g_win_capslock_down = capslock_down; - adb_physical_key_update(0x39, !capslock_down); + adb_physical_key_update(kVK_CapsLock, !capslock_down); } return; // Do no more processing! @@ -420,13 +422,12 @@ void show_xcolor_array() { // OG Add function to clear all get_images loaded (dev dependent) void x_release_kimage(Kimage *kimage_ptr) { - if ((int)kimage_ptr->dev_handle != -1) + if (kimage_ptr->dev_handle) { DeleteObject(kimage_ptr->dev_handle); - kimage_ptr->dev_handle = (void*)-1; + kimage_ptr->dev_handle = NULL; } - else - if (kimage_ptr->data_ptr) + else if (kimage_ptr->data_ptr) { free(kimage_ptr->data_ptr); kimage_ptr->data_ptr = NULL; @@ -480,11 +481,11 @@ void x_get_kimage(Kimage *kimage_ptr) { kimage_ptr->data_ptr = ptr; - kimage_ptr->dev_handle = (void *)-1; + kimage_ptr->dev_handle = NULL; } - printf("kim: %p, dev:%p data: %p, size: %08x\n", kimage_ptr, - kimage_ptr->dev_handle, kimage_ptr->data_ptr, size); + //printf("kim: %p, dev:%p data: %p, size: %08x\n", kimage_ptr, + // kimage_ptr->dev_handle, kimage_ptr->data_ptr, size); return; }