commit b70b6fb43a25dcc0fa0673f360cae86caca3eb42 Author: Horst Schirmeier Date: Thu Mar 8 19:43:02 2012 +0000 another directory rename: failstar -> fail "failstar" sounds like a name for a cruise liner from the 80s. As "*" isn't a desirable part of directory names, just name the whole thing "fail/", the core parts being stored in "fail/core/". Additionally fixing two build system dependency issues: - missing jobserver -> protomessages dependency - broken bochs -> fail dependency (add_custom_target DEPENDS only allows plain file dependencies ... cmake for the win) git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@956 8c4709b5-6ec9-48aa-a5cd-a96041d1645a diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..81f96c69 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +*.o +*.a +*.d +*.acc +*.pb.h +*.pb.cc +*.gcda +*~ +Makefile +build + +bochs/autom4te.cache/ +bochs/bochs +bochs/build/linux/bochs-dlx +bochs/build/macosx/Info.plist +bochs/build/win32/nsis/bochs.nsi +bochs/bxcommit +bochs/bximage +bochs/bxversion.h +bochs/bxversion.rc +bochs/config.h +bochs/config.log +bochs/config.status +bochs/libtool +bochs/ltdlconf.h + +!bochs/plex86/kernel/freebsd/Makefile diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..967dc791 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,68 @@ +cmake_minimum_required(VERSION 2.6) + +PROJECT(Fail*) + +set(PROJECT_VERSION "0.0.1" CACHE STRING "Fail* version number") + +#### Put all resulting library files in /lib #### +SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) + +#### Put all resulting executables in /bin #### +SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) +# At the moment this is the campaign controller executable. +## (The autoconf'd Bochs instance is placed in the auto-configured path, +## as we still just call Bochs' Makefile's make install) + + +#### Setup search path for custom cmake scipts #### +SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +#### Compiler configuration, see cmake/compilerconfig.cmake +include(compilerconfig) + +#### #OPTION to configure Bochs/OVP #### +OPTION( BUILD_OVP "Build OVP Variant?" OFF) # Defaults to BOCHS ON +OPTION( BUILD_BOCHS "Build Bochs Variant?" ON) + +#### Configuration file emitting BUILD_OVP/BOCHS defines #### +configure_file(${CMAKE_SOURCE_DIR}/core/variant_config.h.cmake ${CMAKE_SOURCE_DIR}/core/variant_config.h) + +if(BUILD_OVP) + message(STATUS "[${PROJECT_NAME}] Building OVP variant...") + SET(VARIANT ovp) +else(BUILD_OVP) + message(STATUS "[${PROJECT_NAME}] Building Bochs variant...") + ## add necessary additional header search paths. + add_definitions(-I${CMAKE_SOURCE_DIR}/bochs/instrument/stubs/ -I${CMAKE_SOURCE_DIR}/bochs/) + SET(VARIANT bochs) +endif(BUILD_OVP) + +## Additional Compiler flags ## +set(CMAKE_C_FLAGS "-g -Wall") +set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") +## Tell the linker where to find the libfail.a +link_directories("${LIBRARY_OUTPUT_PATH}") + +## Add CMakeLists from subdirectories (at the moment only core) +add_subdirectory(core) + +if(BUILD_OVP) + add_subdirectory(ovp) +else(BUILD_OVP) +endif(BUILD_OVP) + +## Just for testing: +## Invoking bochs build via external project +# Setup configure call for bochs (-> make ebochs) +# Prefix dir for make install etc +#set(BOCHS_PREFIX_DIR "${CMAKE_BINARY_DIR}/bochs") +#configure_file(${CMAKE_SOURCE_DIR}/cmake/config_failbochs.sh.in ${CMAKE_BINARY_DIR}/config_bochs.sh) +# +#include(ExternalProject) +#externalproject_add( +# ebochs +# SOURCE_DIR ${CMAKE_SOURCE_DIR}/bochs +# CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/config_bochs.sh +# BUILD_IN_SOURCE 1 +# PREFIX ${BOCHS_PREFIX_DIR} +#) diff --git a/bochs/.bochsrc b/bochs/.bochsrc new file mode 100644 index 00000000..81a11d0e --- /dev/null +++ b/bochs/.bochsrc @@ -0,0 +1,989 @@ +# You may now use double quotes around pathnames, in case +# your pathname includes spaces. + +#======================================================================= +# CONFIG_INTERFACE +# +# The configuration interface is a series of menus or dialog boxes that +# allows you to change all the settings that control Bochs's behavior. +# Depending on the platform there are up to 3 choices of configuration +# interface: a text mode version called "textconfig" and two graphical versions +# called "win32config" and "wx". The text mode version uses stdin/stdout and +# is always compiled in, unless Bochs is compiled for wx only. The choice +# "win32config" is only available on win32 and it is the default there. +# The choice "wx" is only available when you use "--with-wx" on the configure +# command. If you do not write a config_interface line, Bochs will +# choose a default for you. +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +#======================================================================= +#config_interface: textconfig +#config_interface: win32config +#config_interface: wx + +#======================================================================= +# DISPLAY_LIBRARY +# +# The display library is the code that displays the Bochs VGA screen. Bochs +# has a selection of about 10 different display library implementations for +# different platforms. If you run configure with multiple --with-* options, +# the display_library command lets you choose which one you want to run with. +# If you do not write a display_library line, Bochs will choose a default for +# you. +# +# The choices are: +# x use X windows interface, cross platform +# win32 use native win32 libraries +# carbon use Carbon library (for MacOS X) +# beos use native BeOS libraries +# macintosh use MacOS pre-10 +# amigaos use native AmigaOS libraries +# sdl use SDL library, cross platform +# svga use SVGALIB library for Linux, allows graphics without X11 +# term text only, uses curses/ncurses library, cross platform +# rfb provides an interface to AT&T's VNC viewer, cross platform +# wx use wxWidgets library, cross platform +# nogui no display at all +# +# NOTE: if you use the "wx" configuration interface, you must also use +# the "wx" display library. +# +# Specific options: +# Some display libraries now support specific option to control their +# behaviour. See the examples below for currently supported options. +#======================================================================= +#display_library: amigaos +#display_library: beos +#display_library: carbon +#display_library: macintosh +#display_library: nogui +#display_library: rfb, options="timeout=60" # time to wait for client +#display_library: sdl, options="fullscreen" # startup in fullscreen mode +#display_library: term +#display_library: win32, options="gui_debug" # use Win32 debugger gui +#display_library: wx +#display_library: x, options="hideIPS" # disable IPS output in status bar +#display_library: x, options="gui_debug" # use GTK debugger gui + +#======================================================================= +# ROMIMAGE: +# The ROM BIOS controls what the PC does when it first powers on. +# Normally, you can use a precompiled BIOS in the source or binary +# distribution called BIOS-bochs-latest. The ROM BIOS is usually loaded +# starting at address 0xf0000, and it is exactly 64k long. Another option +# is 128k BIOS which is loaded at address 0xe0000. +# You can also use the environment variable $BXSHARE to specify the +# location of the BIOS. +# The usage of external large BIOS images (up to 512k) at memory top is +# now supported, but we still recommend to use the BIOS distributed with +# Bochs. The start address optional, since it can be calculated from image size. +#======================================================================= +romimage: file=$BXSHARE/BIOS-bochs-latest +#romimage: file=bios/seabios-0.5.1.bin +#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top + +#======================================================================= +# CPU: +# This defines cpu-related parameters inside Bochs: +# +# COUNT: +# Set the number of processors:cores per processor:threads per core +# when Bochs is compiled for SMP emulation. +# Bochs currently supports up to 8 threads running simultaniosly. +# If Bochs is compiled without SMP support, it won't accept values +# different from 1. +# +# QUANTUM: +# Maximum amount of instructions allowed to execute by processor before +# returning control to another cpu. This option exists only in Bochs +# binary compiled with SMP support. +# +# RESET_ON_TRIPLE_FAULT: +# Reset the CPU when triple fault occur (highly recommended) rather than +# PANIC. Remember that if you trying to continue after triple fault the +# simulation will be completely bogus ! +# +# MSRS: +# Define path to user CPU Model Specific Registers (MSRs) specification. +# See example in msrs.def. +# +# IGNORE_BAD_MSRS: +# Ignore MSR references that Bochs does not understand; print a warning +# message instead of generating #GP exception. This option is enabled +# by default but will not be avaiable if configurable MSRs are enabled. +# +# IPS: +# Emulated Instructions Per Second. This is the number of IPS that bochs +# is capable of running on your machine. You can recompile Bochs with +# --enable-show-ips option enabled, to find your host's capability. +# Measured IPS value will then be logged into your log file or shown +# in the status bar (if supported by the gui). +# +# IPS is used to calibrate many time-dependent events within the bochs +# simulation. For example, changing IPS affects the frequency of VGA +# updates, the duration of time before a key starts to autorepeat, and +# the measurement of BogoMips and other benchmarks. +# +# Examples: +# +# Bochs Machine/Compiler Mips +# ____________________________________________________________________ +# 2.3.7 3.2Ghz Intel Core 2 Q9770 with WinXP/g++ 3.4 50 to 55 Mips +# 2.3.7 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 38 to 43 Mips +# 2.2.6 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 21 to 25 Mips +# 2.2.6 2.1Ghz Athlon XP with Linux 2.6/g++ 3.4 12 to 15 Mips +# 2.0.1 1.6Ghz Intel P4 with Win2000/g++ 3.3 5 to 7 Mips +#======================================================================= +cpu: count=1, ips=50000000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def" + +#======================================================================= +# CPUID: +# +# This defines features and functionality supported by Bochs emulated CPU: +# +# MMX: +# Select MMX instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5. +# +# SEP: +# Select SYSENTER/SYSEXIT instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# SSE: +# Select SSE instruction set support. +# Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2 could be selected. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XAPIC: +# Select XAPIC extensions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# AES: +# Select AES instruction set support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# MOVBE: +# Select MOVBE Intel(R) Atom instruction support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# XSAVE: +# Select XSAVE extensions support. +# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6. +# +# 1G_PAGES: +# Enable 1G page size support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# PCID: +# Enable Process-Context Identifiers (PCID) support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# FSGSBASE: +# Enable GS/GS BASE access instructions support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# +# MWAIT: +# Select MONITOR/MWAIT instructions support. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# MWAIT_IS_NOP: +# When this option is enabled MWAIT will not put the CPU into a sleep state. +# This option exists only if Bochs compiled with --enable-monitor-mwait. +# +# VENDOR_STRING: +# Set the CPUID vendor string returned by CPUID(0x0). This should be a +# twelve-character ASCII string. +# +# BRAND_STRING: +# Set the CPUID vendor string returned by CPUID(0x80000002 .. 0x80000004). +# This should be at most a forty-eight-character ASCII string. +# +# STEPPING: +# Set stepping information returned by CPUID. Default stepping value is 3. +# +# CPUID_LIMIT_WINNT: +# Determine whether to limit maximum CPUID function to 3. This mode is +# required to workaround WinNT installation and boot issues. +#======================================================================= +cpuid: mmx=1, sep=1, sse=sse4_2, xapic=1, aes=1, movbe=1, xsave=1 +cpuid: stepping=5 +cpuid: cpuid_limit_winnt=0 + +#======================================================================= +# MEMORY +# Set the amount of physical memory you want to emulate. +# +# GUEST: +# Set amount of guest physical memory to emulate. The default is 32MB, +# the maximum amount limited only by physical address space limitations. +# +# HOST: +# Set amount of host memory you want to allocate for guest RAM emulation. +# It is possible to allocate less memory than you want to emulate in guest +# system. This will fake guest to see the non-existing memory. Once guest +# system touches new memory block it will be dynamically taken from the +# memory pool. You will be warned (by FATAL PANIC) in case guest already +# used all allocated host memory and wants more. +# +#======================================================================= +memory: guest=512, host=256 + +#======================================================================= +# OPTROMIMAGE[1-4]: +# You may now load up to 4 optional ROM images. Be sure to use a +# read-only area, typically between C8000 and EFFFF. These optional +# ROM images should not overwrite the rombios (located at +# F0000-FFFFF) and the videobios (located at C0000-C7FFF). +# Those ROM images will be initialized by the bios if they contain +# the right signature (0x55AA) and a valid checksum. +# It can also be a convenient way to upload some arbitrary code/data +# in the simulation, that can be retrieved by the boot loader +#======================================================================= +#optromimage1: file=optionalrom.bin, address=0xd0000 +#optromimage2: file=optionalrom.bin, address=0xd1000 +#optromimage3: file=optionalrom.bin, address=0xd2000 +#optromimage4: file=optionalrom.bin, address=0xd3000 + +#optramimage1: file=/path/file1.img, address=0x0010000 +#optramimage2: file=/path/file2.img, address=0x0020000 +#optramimage3: file=/path/file3.img, address=0x0030000 +#optramimage4: file=/path/file4.img, address=0x0040000 + +#======================================================================= +# VGAROMIMAGE +# You now need to load a VGA ROM BIOS into C0000. +#======================================================================= +#vgaromimage: file=bios/VGABIOS-elpin-2.40 +vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest +#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus + +#======================================================================= +# VGA: +# Here you can specify the display extension to be used. With the value +# 'none' you can use standard VGA with no extension. Other supported +# values are 'vbe' for Bochs VBE and 'cirrus' for Cirrus SVGA support. +#======================================================================= +#vga: extension=cirrus +vga: extension=vbe + +#======================================================================= +# FLOPPYA: +# Point this to pathname of floppy image file or device +# This should be of a bootable floppy(image/device) if you're +# booting from 'a' (or 'floppy'). +# +# You can set the initial status of the media to 'ejected' or 'inserted'. +# floppya: 2_88=path, status=ejected (2.88M 3.5" media) +# floppya: 1_44=path, status=inserted (1.44M 3.5" media) +# floppya: 1_2=path, status=ejected (1.2M 5.25" media) +# floppya: 720k=path, status=inserted (720K 3.5" media) +# floppya: 360k=path, status=inserted (360K 5.25" media) +# floppya: 320k=path, status=inserted (320K 5.25" media) +# floppya: 180k=path, status=inserted (180K 5.25" media) +# floppya: 160k=path, status=inserted (160K 5.25" media) +# floppya: image=path, status=inserted (guess media type from image size) +# floppya: 1_44=vvfat:path, status=inserted (use directory as VFAT media) +# floppya: type=1_44 (1.44M 3.5" floppy drive, no media) +# +# The path should be the name of a disk image file. On Unix, you can use a raw +# device name such as /dev/fd0 on Linux. On win32 platforms, use drive letters +# such as a: or b: as the path. The parameter 'image' works with image files +# only. In that case the size must match one of the supported types. +# The parameter 'type' can be used to enable the floppy drive without media +# and status specified. Usually the drive type is set up based on the media type. +# The optional parameter 'write_protected' can be used to control the media +# write protect switch. By default it is turned off. +#======================================================================= +floppya: 1_44=/dev/fd0, status=inserted +#floppya: image=../1.44, status=inserted +#floppya: 1_44=/dev/fd0H1440, status=inserted +#floppya: 1_2=../1_2, status=inserted +#floppya: 1_44=a:, status=inserted +#floppya: 1_44=a.img, status=inserted, write_protected=1 +#floppya: 1_44=/dev/rfd0a, status=inserted + +#======================================================================= +# FLOPPYB: +# See FLOPPYA above for syntax +#======================================================================= +#floppyb: 1_44=b:, status=inserted +#floppyb: 1_44=b.img, status=inserted + +#======================================================================= +# ATA0, ATA1, ATA2, ATA3 +# ATA controller for hard disks and cdroms +# +# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number +# +# These options enables up to 4 ata channels. For each channel +# the two base io addresses and the irq must be specified. +# +# ata0 and ata1 are enabled by default with the values shown below +# +# Examples: +# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 +# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x360, irq=9 +#======================================================================= +ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 +ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9 + +#======================================================================= +# ATA[0-3]-MASTER, ATA[0-3]-SLAVE +# +# This defines the type and characteristics of all attached ata devices: +# type= type of attached device [disk|cdrom] +# mode= only valid for disks [flat|concat|external|dll|sparse|vmware3] +# mode= only valid for disks [undoable|growing|volatile|vvfat] +# path= path of the image / directory +# cylinders= only valid for disks +# heads= only valid for disks +# spt= only valid for disks +# status= only valid for cdroms [inserted|ejected] +# biosdetect= type of biosdetection [none|auto], only for disks on ata0 [cmos] +# translation=type of translation of the bios, only for disks [none|lba|large|rechs|auto] +# model= string returned by identify device command +# journal= optional filename of the redolog for undoable, volatile and vvfat disks +# +# Point this at a hard disk image file, cdrom iso file, or physical cdrom +# device. To create a hard disk image, try running bximage. It will help you +# choose the size and then suggest a line that works with it. +# +# In UNIX it may be possible to use a raw device as a Bochs hard disk, +# but WE DON'T RECOMMEND IT. In Windows there is no easy way. +# +# In windows, the drive letter + colon notation should be used for cdroms. +# Depending on versions of windows and drivers, you may only be able to +# access the "first" cdrom in the system. On MacOSX, use path="drive" +# to access the physical drive. +# +# The path is mandatory for hard disks. Disk geometry autodetection works with +# images created by bximage if CHS is set to 0/0/0 (cylinders are calculated +# using heads=16 and spt=63). For other hard disk images and modes the +# cylinders, heads, and spt are mandatory. In all cases the disk size reported +# from the image must be exactly C*H*S*512. +# +# Default values are: +# mode=flat, biosdetect=auto, translation=auto, model="Generic 1234" +# +# The biosdetect option has currently no effect on the bios +# +# Examples: +# ata0-master: type=disk, mode=flat, path=10M.sample, cylinders=306, heads=4, spt=17 +# ata0-slave: type=disk, mode=flat, path=20M.sample, cylinders=615, heads=4, spt=17 +# ata1-master: type=disk, mode=flat, path=30M.sample, cylinders=615, heads=6, spt=17 +# ata1-slave: type=disk, mode=flat, path=46M.sample, cylinders=940, heads=6, spt=17 +# ata2-master: type=disk, mode=flat, path=62M.sample, cylinders=940, heads=8, spt=17 +# ata2-slave: type=disk, mode=flat, path=112M.sample, cylinders=900, heads=15, spt=17 +# ata3-master: type=disk, mode=flat, path=483M.sample, cylinders=1024, heads=15, spt=63 +# ata3-slave: type=cdrom, path=iso.sample, status=inserted +#======================================================================= +ata0-master: type=disk, mode=flat, path="30M.sample" +#ata0-master: type=disk, mode=flat, path="30M.sample", cylinders=615, heads=6, spt=17 +#ata0-master: type=disk, mode=flat, path="c.img", cylinders=0 # autodetect +#ata0-slave: type=disk, mode=vvfat, path=/bochs/images/vvfat, journal=vvfat.redolog +#ata0-slave: type=cdrom, path=D:, status=inserted +#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted +#ata0-slave: type=cdrom, path="drive", status=inserted +#ata0-slave: type=cdrom, path=/dev/rcd0d, status=inserted + +#======================================================================= +# BOOT: +# This defines the boot sequence. Now you can specify up to 3 boot drives, +# which can be 'floppy', 'disk', 'cdrom' or 'network' (boot ROM). +# Legacy 'a' and 'c' are also supported. +# Examples: +# boot: floppy +# boot: cdrom, disk +# boot: network, disk +# boot: cdrom, floppy, disk +#======================================================================= +#boot: floppy +boot: disk + +#======================================================================= +# CLOCK: +# This defines the parameters of the clock inside Bochs: +# +# SYNC: +# This defines the method how to synchronize the Bochs internal time +# with realtime. With the value 'none' the Bochs time relies on the IPS +# value and no host time synchronization is used. The 'slowdown' method +# sacrifices performance to preserve reproducibility while allowing host +# time correlation. The 'realtime' method sacrifices reproducibility to +# preserve performance and host-time correlation. +# It is possible to enable both synchronization methods. +# +# TIME0: +# Specifies the start (boot) time of the virtual machine. Use a time +# value as returned by the time(2) system call. If no time0 value is +# set or if time0 equal to 1 (special case) or if time0 equal 'local', +# the simulation will be started at the current local host time. +# If time0 equal to 2 (special case) or if time0 equal 'utc', +# the simulation will be started at the current utc time. +# +# Syntax: +# clock: sync=[none|slowdown|realtime|both], time0=[timeValue|local|utc] +# +# Example: +# clock: sync=none, time0=local # Now (localtime) +# clock: sync=slowdown, time0=315529200 # Tue Jan 1 00:00:00 1980 +# clock: sync=none, time0=631148400 # Mon Jan 1 00:00:00 1990 +# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999 +# clock: sync=realtime, time0=946681200 # Sat Jan 1 00:00:00 2000 +# clock: sync=none, time0=1 # Now (localtime) +# clock: sync=none, time0=utc # Now (utc/gmt) +# +# Default value are sync=none, time0=local +#======================================================================= +#clock: sync=none, time0=local + + +#======================================================================= +# FLOPPY_BOOTSIG_CHECK: disabled=[0|1] +# Enables or disables the 0xaa55 signature check on boot floppies +# Defaults to disabled=0 +# Examples: +# floppy_bootsig_check: disabled=0 +# floppy_bootsig_check: disabled=1 +#======================================================================= +floppy_bootsig_check: disabled=0 + +#======================================================================= +# LOG: +# Give the path of the log file you'd like Bochs debug and misc. verbiage +# to be written to. If you don't use this option or set the filename to +# '-' the output is written to the console. If you really don't want it, +# make it "/dev/null" (Unix) or "nul" (win32). :^( +# +# Examples: +# log: ./bochs.out +# log: /dev/tty +#======================================================================= +#log: /dev/null +log: bochsout.txt + +#======================================================================= +# LOGPREFIX: +# This handles the format of the string prepended to each log line. +# You may use those special tokens : +# %t : 11 decimal digits timer tick +# %i : 8 hexadecimal digits of cpu current eip (ignored in SMP configuration) +# %e : 1 character event type ('i'nfo, 'd'ebug, 'p'anic, 'e'rror) +# %d : 5 characters string of the device, between brackets +# +# Default : %t%e%d +# Examples: +# logprefix: %t-%e-@%i-%d +# logprefix: %i%e%d +#======================================================================= +#logprefix: %t%e%d + +#======================================================================= +# LOG CONTROLS +# +# Bochs now has four severity levels for event logging. +# panic: cannot proceed. If you choose to continue after a panic, +# don't be surprised if you get strange behavior or crashes. +# error: something went wrong, but it is probably safe to continue the +# simulation. +# info: interesting or useful messages. +# debug: messages useful only when debugging the code. This may +# spit out thousands per second. +# +# For events of each level, you can choose to crash, report, or ignore. +# TODO: allow choice based on the facility: e.g. crash on panics from +# everything except the cdrom, and only report those. +# +# If you are experiencing many panics, it can be helpful to change +# the panic action to report instead of fatal. However, be aware +# that anything executed after a panic is uncharted territory and can +# cause bochs to become unstable. The panic is a "graceful exit," so +# if you disable it you may get a spectacular disaster instead. +#======================================================================= +panic: action=ask +error: action=report +info: action=report +debug: action=ignore +#pass: action=fatal + +#======================================================================= +# DEBUGGER_LOG: +# Give the path of the log file you'd like Bochs to log debugger output. +# If you really don't want it, make it /dev/null or '-'. :^( +# +# Examples: +# debugger_log: ./debugger.out +#======================================================================= +#debugger_log: /dev/null +#debugger_log: debugger.out +debugger_log: - + +#======================================================================= +# COM1, COM2, COM3, COM4: +# This defines a serial port (UART type 16550A). In the 'term' you can specify +# a device to use as com1. This can be a real serial line, or a pty. To use +# a pty (under X/Unix), create two windows (xterms, usually). One of them will +# run bochs, and the other will act as com1. Find out the tty the com1 +# window using the `tty' command, and use that as the `dev' parameter. +# Then do `sleep 1000000' in the com1 window to keep the shell from +# messing with things, and run bochs in the other window. Serial I/O to +# com1 (port 0x3f8) will all go to the other window. +# In socket* and pipe* (win32 only) modes Bochs becomes either socket/named pipe +# client or server. In client mode it connects to an already running server (if +# connection fails Bochs treats com port as not connected). In server mode it +# opens socket/named pipe and waits until a client application connects to it +# before starting simulation. This mode is useful for remote debugging (e.g. +# with gdb's "target remote host:port" command or windbg's command line option +# -k com:pipe,port=\\.\pipe\pipename). Note: 'socket' is a shorthand for +# 'socket-client' and 'pipe' for 'pipe-client'. Socket modes use simple TCP +# communication, pipe modes use duplex byte mode pipes. +# Other serial modes are 'null' (no input/output), 'file' (output to a file +# specified as the 'dev' parameter), 'raw' (use the real serial port - under +# construction for win32), 'mouse' (standard serial mouse - requires +# mouse option setting 'type=serial', 'type=serial_wheel' or 'type=serial_msys'). +# +# Examples: +# com1: enabled=1, mode=null +# com1: enabled=1, mode=mouse +# com2: enabled=1, mode=file, dev=serial.out +# com3: enabled=1, mode=raw, dev=com1 +# com3: enabled=1, mode=socket-client, dev=localhost:8888 +# com3: enabled=1, mode=socket-server, dev=localhost:8888 +# com4: enabled=1, mode=pipe-client, dev=\\.\pipe\mypipe +# com4: enabled=1, mode=pipe-server, dev=\\.\pipe\mypipe +#======================================================================= +#com1: enabled=1, mode=term, dev=/dev/ttyp9 + + +#======================================================================= +# PARPORT1, PARPORT2: +# This defines a parallel (printer) port. When turned on and an output file is +# defined the emulated printer port sends characters printed by the guest OS +# into the output file. On some platforms a device filename can be used to +# send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on +# win32 platforms). +# +# Examples: +# parport1: enabled=1, file="parport.out" +# parport2: enabled=1, file="/dev/lp0" +# parport1: enabled=0 +#======================================================================= +parport1: enabled=1, file="parport.out" + +#======================================================================= +# SB16: +# This defines the SB16 sound emulation. It can have several of the +# following properties. +# All properties are in the format sb16: property=value +# midi: The filename is where the midi data is sent. This can be a +# device or just a file if you want to record the midi data. +# midimode: +# 0=no data +# 1=output to device (system dependent. midi denotes the device driver) +# 2=SMF file output, including headers +# 3=output the midi data stream to the file (no midi headers and no +# delta times, just command and data bytes) +# wave: This is the device/file where wave output is stored +# wavemode: +# 0=no data +# 1=output to device (system dependent. wave denotes the device driver) +# 2=VOC file output, incl. headers +# 3=output the raw wave stream to the file +# log: The file to write the sb16 emulator messages to. +# loglevel: +# 0=no log +# 1=resource changes, midi program and bank changes +# 2=severe errors +# 3=all errors +# 4=all errors plus all port accesses +# 5=all errors and port accesses plus a lot of extra info +# dmatimer: +# microseconds per second for a DMA cycle. Make it smaller to fix +# non-continuous sound. 750000 is usually a good value. This needs a +# reasonably correct setting for the IPS parameter of the CPU option. +# +# Examples for output devices: +# sb16: midimode=1, midi="", wavemode=1, wave="" # win32 +# sb16: midimode=1, midi=alsa:128:0, wavemode=1, wave=alsa # Linux with ALSA +#======================================================================= +#sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=sb16.log, dmatimer=600000 + +#======================================================================= +# VGA_UPDATE_INTERVAL: +# Video memory is scanned for updates and screen updated every so many +# virtual seconds. The default is 50000, about 20Hz. Keep in mind that +# you must tweak the 'cpu: ips=N' directive to be as close to the number +# of emulated instructions-per-second your workstation can do, for this +# to be accurate. +# +# Examples: +# vga_update_interval: 250000 +#======================================================================= +vga_update_interval: 300000 + +# using for Winstone '98 tests +#vga_update_interval: 100000 + +#======================================================================= +# KEYBOARD_SERIAL_DELAY: +# Approximate time in microseconds that it takes one character to +# be transfered from the keyboard to controller over the serial path. +# Examples: +# keyboard_serial_delay: 200 +#======================================================================= +keyboard_serial_delay: 250 + +#======================================================================= +# KEYBOARD_PASTE_DELAY: +# Approximate time in microseconds between attempts to paste +# characters to the keyboard controller. This leaves time for the +# guest os to deal with the flow of characters. The ideal setting +# depends on how your operating system processes characters. The +# default of 100000 usec (.1 seconds) was chosen because it works +# consistently in Windows. +# +# If your OS is losing characters during a paste, increase the paste +# delay until it stops losing characters. +# +# Examples: +# keyboard_paste_delay: 100000 +#======================================================================= +keyboard_paste_delay: 100000 + +#======================================================================= +# MOUSE: +# This defines parameters for the emulated mouse type, the initial status +# of the mouse capture and the runtime method to toggle it. +# +# TYPE: +# With the mouse type option you can select the type of mouse to emulate. +# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse +# on PS/2), 'serial', 'serial_wheel' and 'serial_msys' (one com port requires +# setting 'mode=mouse'). To connect a mouse to an USB port, see the 'usb_uhci' +# or 'usb_ohci' option (requires PCI and USB support). +# +# ENABLED: +# The Bochs gui creates mouse "events" unless the 'enabled' option is +# set to 0. The hardware emulation itself is not disabled by this. +# Unless you have a particular reason for enabling the mouse by default, +# it is recommended that you leave it off. You can also toggle the mouse +# usage at runtime (RFB, SDL, Win32, wxWidgets and X11 - see below). +# +# TOGGLE: +# The default method to toggle the mouse capture at runtime is to press the +# CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows +# to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU) +# or 'f12' (replaces win32 'legacyF12' option). +# +# Examples: +# mouse: enabled=1 +# mouse: type=imps2, enabled=1 +# mouse: type=serial, enabled=1 +# mouse: enabled=0, toggle=ctrl+f10 +#======================================================================= +mouse: enabled=0 + +#======================================================================= +# private_colormap: Request that the GUI create and use it's own +# non-shared colormap. This colormap will be used +# when in the bochs window. If not enabled, a +# shared colormap scheme may be used. Not implemented +# on all GUI's. +# +# Examples: +# private_colormap: enabled=1 +# private_colormap: enabled=0 +#======================================================================= +private_colormap: enabled=0 + +#======================================================================= +# fullscreen: ONLY IMPLEMENTED ON AMIGA +# Request that Bochs occupy the entire screen instead of a +# window. +# +# Examples: +# fullscreen: enabled=0 +# fullscreen: enabled=1 +#======================================================================= +#fullscreen: enabled=0 +#screenmode: name="sample" + +#======================================================================= +# ne2k: NE2000 compatible ethernet adapter +# +# Examples: +# ne2k: ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT +# +# ioaddr, irq: You probably won't need to change ioaddr and irq, unless there +# are IRQ conflicts. These arguments are ignored when assign the ne2k to a +# PCI slot. +# +# mac: The MAC address MUST NOT match the address of any machine on the net. +# Also, the first byte must be an even number (bit 0 set means a multicast +# address), and you cannot use ff:ff:ff:ff:ff:ff because that's the broadcast +# address. For the ethertap module, you must use fe:fd:00:00:00:01. There may +# be other restrictions too. To be safe, just use the b0:c4... address. +# +# ethdev: The ethdev value is the name of the network interface on your host +# platform. On UNIX machines, you can get the name by running ifconfig. On +# Windows machines, you must run niclist to get the name of the ethdev. +# Niclist source code is in misc/niclist.c and it is included in Windows +# binary releases. +# +# script: The script value is optional, and is the name of a script that +# is executed after bochs initialize the network interface. You can use +# this script to configure this network interface, or enable masquerading. +# This is mainly useful for the tun/tap devices that only exist during +# Bochs execution. The network interface name is supplied to the script +# as first parameter +# +# If you don't want to make connections to any physical networks, +# you can use the following 'ethmod's to simulate a virtual network. +# null: All packets are discarded, but logged to a few files. +# arpback: ARP is simulated. Disabled by default. +# vde: Virtual Distributed Ethernet +# vnet: ARP, ICMP-echo(ping), DHCP and read/write TFTP are simulated. +# The virtual host uses 192.168.10.1. +# DHCP assigns 192.168.10.2 to the guest. +# TFTP uses the ethdev value for the root directory and doesn't +# overwrite files. +# +#======================================================================= +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=fbsd, ethdev=xl0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=win32, ethdev=MYCARD +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0 +# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tuntap, ethdev=/dev/net/tun0, script=./tunconfig +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=null, ethdev=eth0 +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vde, ethdev="/tmp/vde.ctl" +# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vnet, ethdev="c:/temp" + +#======================================================================= +# pnic: Bochs/Etherboot pseudo-NIC +# +# Example: +# pnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT +# +# The pseudo-NIC accepts the same syntax (for mac, ethmod, ethdev, script) and +# supports the same networking modules as the NE2000 adapter. In addition to +# this, it must be assigned to a PCI slot. +#======================================================================= +#pnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet + +#======================================================================= +# KEYBOARD_MAPPING: +# This enables a remap of a physical localized keyboard to a +# virtualized us keyboard, as the PC architecture expects. +# If enabled, the keymap file must be specified. +# +# Examples: +# keyboard_mapping: enabled=1, map=gui/keymaps/x11-pc-de.map +#======================================================================= +keyboard_mapping: enabled=0, map= + +#======================================================================= +# KEYBOARD_TYPE: +# Type of keyboard return by a "identify keyboard" command to the +# keyboard controler. It must be one of "xt", "at" or "mf". +# Defaults to "mf". It should be ok for almost everybody. A known +# exception is french macs, that do have a "at"-like keyboard. +# +# Examples: +# keyboard_type: mf +#======================================================================= +#keyboard_type: mf + +#======================================================================= +# USER_SHORTCUT: +# This defines the keyboard shortcut to be sent when you press the "user" +# button in the headerbar. The shortcut string is a combination of maximum +# 3 key names (listed below) separated with a '-' character. +# Valid key names: +# "alt", "bksl", "bksp", "ctrl", "del", "down", "end", "enter", "esc", +# "f1", ... "f12", "home", "ins", "left", "menu", "minus", "pgdwn", "pgup", +# "plus", "right", "shift", "space", "tab", "up", "win", "print" and "power". +# +# Example: +# user_shortcut: keys=ctrl-alt-del +#======================================================================= +#user_shortcut: keys=ctrl-alt-del + +#======================================================================= +# I440FXSUPPORT: +# This option controls the presence of the i440FX PCI chipset. You can +# also specify the devices connected to PCI slots. Up to 5 slots are +# available now. These devices are currently supported: ne2k, pcivga, +# pcidev, pcipnic and usb_ohci. If Bochs is compiled with Cirrus SVGA +# support you'll have the additional choice 'cirrus'. +# +# Example: +# i440fxsupport: enabled=1, slot1=pcivga, slot2=ne2k +#======================================================================= +i440fxsupport: enabled=1 + +#======================================================================= +# USB_UHCI: +# This option controls the presence of the USB root hub which is a part +# of the i440FX PCI chipset. With the portX parameter you can connect devices +# to the hub (currently supported: 'mouse', 'tablet', 'keypad', 'disk', 'cdrom' +# 'hub' and 'printer'). +# +# The optionsX parameter can be used to assign specific options to the device +# connected to the corresponding USB port. Currently this feature is only used +# to set the speed reported by device and by the 'disk' device to specify +# an alternative redolog file of some image modes. +# +# If you connect the mouse or tablet to one of the ports, Bochs forwards the +# mouse movement data to the USB device instead of the selected mouse type. +# When connecting the keypad to one of the ports, Bochs forwards the input of +# the numeric keypad to the USB device instead of the PS/2 keyboard. +# +# To connect a 'flat' mode image as an USB hardisk you can use the 'disk' device +# with the path to the image separated with a colon. To use other disk image modes +# similar to ATA disks the syntax 'disk:mode:filename' must be used (see below). +# +# To emulate an USB cdrom you can use the 'cdrom' device name and the path to +# an ISO image or raw device name also separated with a colon. An option to +# insert/eject media is available in the runtime configuration. +# +# The device name 'hub' connects an external hub with max. 8 ports (default: 4) +# to the root hub. To specify the number of ports you have to add the value +# separated with a colon. Connecting devices to the external hub ports is only +# available in the runtime configuration. +# +# The device 'printer' emulates the HP Deskjet 920C printer. The PCL data is +# sent to a file specified in bochsrc.txt. The current code appends the PCL +# code to the file if the file already existed. It would probably be nice to +# overwrite the file instead, asking user first. +#======================================================================= +#usb_uhci: enabled=1 +#usb_uhci: enabled=1, port1=mouse, port2=disk:usbstick.img +#usb_uhci: enabled=1, port1=hub:7, port2=disk:growing:usbdisk.img +#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options1=journal:redo.log +#usb_uhci: enabled=1, port1=printer:printdata.bin, port2=cdrom:image.iso + +#======================================================================= +# USB_OHCI: +# This option controls the presence of the USB OHCI host controller with a +# 2-port hub. The portX option accepts the same device types with the same +# syntax as the UHCI controller (see above). The OHCI HC must be assigned to +# a PCI slot. +#======================================================================= +#usb_ohci: enabled=1 +#usb_ohci: enabled=1, port1=printer:usbprinter.bin + +#======================================================================= +# CMOSIMAGE: +# This defines image file that can be loaded into the CMOS RAM at startup. +# The rtc_init parameter controls whether initialize the RTC with values stored +# in the image. By default the time0 argument given to the clock option is used. +# With 'rtc_init=image' the image is the source for the initial time. +# +# Example: +# cmosimage: file=cmos.img, rtc_init=image +#======================================================================= +#cmosimage: file=cmos.img, rtc_init=time0 + +#======================================================================= +# MAGIC_BREAK: +# This enables the "magic breakpoint" feature when using the debugger. +# The useless cpu instruction XCHG BX, BX causes Bochs to enter the +# debugger mode. This might be useful for software development. +# +# Example: +# magic_break: enabled=1 +#======================================================================= +#magic_break: enabled=1 + +#======================================================================= +# PORT_E9_HACK: +# The 0xE9 port doesn't exists in normal ISA architecture. However, we +# define a convention here, to display on the console of the system running +# Bochs anything that is written to it. The idea is to provide debug output +# very early when writing BIOS or OS code for example, without having to +# bother with setting up a serial port or etc. Reading from port 0xE9 will +# will return 0xe9 to let you know if the feature is available. +# Leave this 0 unless you have a reason to use it. +# +# Example: +# port_e9_hack: enabled=1 +#======================================================================= +#port_e9_hack: enabled=1 + +#======================================================================= +# DEBUG_SYMBOLS: +# This loads symbols from the specified file for use in Bochs' internal +# debugger. Symbols are loaded into global context. This is equivalent to +# issuing ldsym debugger command at start up. +# +# Example: +# debug_symbols: file="kernel.sym" +# debug_symbols: file="kernel.sym", offset=0x80000000 +#======================================================================= +#debug_symbols: file="kernel.sym" + +#======================================================================= +# other stuff +#======================================================================= +#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log +#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img +#text_snapshot_check: enabled=1 +#print_timestamps: enabled=1 + +#------------------------- +# PCI host device mapping +#------------------------- +#pcidev: vendor=0x1234, device=0x5678 + +#======================================================================= +# GDBSTUB: +# Enable GDB stub. See user documentation for details. +# Default value is enabled=0. +#======================================================================= +#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0 + +#======================================================================= +# PLUGIN_CTRL: +# Controls the presence of optional plugins without a separate option. +# By default all existing plugins are enabled. These plugins are currently +# supported: 'acpi', 'biosdev', 'extfpuirq', 'gameport', 'iodebug', +# 'pci_ide', 'speaker' and 'unmapped'. +#======================================================================= +#plugin_ctrl: biosdev=0, speaker=0 + +#======================================================================= +# USER_PLUGIN: +# Load user-defined plugin. This option is available only if Bochs is +# compiled with plugin support. Maximum 8 different plugins are supported. +# See the example in the Bochs sources how to write a plugin device. +#======================================================================= +#user_plugin: name=testdev + +#======================================================================= +# for Macintosh, use the style of pathnames in the following +# examples. +# +# vgaromimage: :bios:VGABIOS-elpin-2.40 +# romimage: file=:bios:BIOS-bochs-latest, address=0xf0000 +# floppya: 1_44=[fd:], status=inserted +#======================================================================= + +#======================================================================= +# MEGS +# Set the number of Megabytes of physical memory you want to emulate. +# The default is 32MB, most OS's won't need more than that. +# The maximum amount of memory supported is 2048Mb. +# The 'MEGS' option is deprecated. Use 'MEMORY' option instead. +#======================================================================= +#megs: 256 +#megs: 128 +#megs: 64 +#megs: 32 +#megs: 16 +#megs: 8 diff --git a/bochs/.conf.amigaos b/bochs/.conf.amigaos new file mode 100755 index 00000000..7abbc6dc --- /dev/null +++ b/bochs/.conf.amigaos @@ -0,0 +1,6 @@ +#!/bin/sh +# +# These options should work on Amiga/MorphOS +# + +./configure --with-amigaos --disable-shared ${CONFIGURE_ARGS} diff --git a/bochs/.conf.beos b/bochs/.conf.beos new file mode 100755 index 00000000..821bce99 --- /dev/null +++ b/bochs/.conf.beos @@ -0,0 +1,21 @@ +#!/bin/sh + +# +# These options are suggested by Bernd Korz, who maintains the BeOS +# port. He says that SDL works better than the native BeOS gui. +# + +CC=gcc +CXX=$CC +CFLAGS="-Wall -O9 -mpentium -fomit-frame-pointer -pipe" +CXXFLAGS=$CFLAGS + +export CC +export CXX +export CFLAGS +export CXXFLAGS + +./configure --with-sdl \ + --enable-ne2000 \ + --enable-all-optimizations \ + --enable-pci diff --git a/bochs/.conf.everything b/bochs/.conf.everything new file mode 100644 index 00000000..26179abd --- /dev/null +++ b/bochs/.conf.everything @@ -0,0 +1,36 @@ +# This script tries to turn on nearly every configure option. +# It is useful for finding compile problems, but it may turn on +# more things than you actually want. + +./configure \ + --enable-smp \ + --enable-x2apic \ + --enable-x86-64 \ + --enable-all-optimizations \ + --enable-long-phy-address \ + --enable-configurable-msrs \ + --enable-debugger \ + --enable-disasm \ + --enable-debugger-gui \ + --enable-fpu \ + --enable-misaligned-sse \ + --enable-alignment-check \ + --enable-3dnow \ + --enable-monitor-mwait \ + --enable-vmx \ + --enable-x86-debugger \ + --enable-a20-pin \ + --enable-instrumentation=instrument/example1 \ + --enable-vbe \ + --enable-ne2000 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb \ + --enable-usb-ohci \ + --enable-cdrom \ + --enable-sb16 \ + --enable-iodebug \ + --enable-gdb-stub \ + --enable-show-ips \ + --with-all-libs diff --git a/bochs/.conf.linux b/bochs/.conf.linux new file mode 100755 index 00000000..b67c620c --- /dev/null +++ b/bochs/.conf.linux @@ -0,0 +1,64 @@ +#!/bin/sh +# +# .conf.linux +# + +#which_config=normal +which_config=plugins + +CC="gcc" +CXX="c++" +CFLAGS="-Wall -O3 -fomit-frame-pointer -pipe" # for speed +#CFLAGS="-Wall -g -pipe" # for development +CXXFLAGS="$CFLAGS" + +export CC +export CXX +export CFLAGS +export CXXFLAGS + + +case $which_config in + + normal) + + ####################################################################### + # configuration 1 for release binary RPMs + # Include a few standard options, speed optimizations, X11 only. + ####################################################################### + ./configure --enable-sb16 \ + --enable-ne2000 \ + --enable-all-optimizations \ + --enable-cpu-level=6 \ + --enable-x86-64 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb \ + --enable-usb-ohci \ + --enable-show-ips \ + ${CONFIGURE_ARGS} + ;; + + plugins) + ####################################################################### + # configuration 2 for release binary RPMs + # Include plugins, every possible gui. + ####################################################################### + ./configure --enable-sb16 \ + --enable-ne2000 \ + --enable-all-optimizations \ + --enable-cpu-level=6 \ + --enable-x86-64 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb \ + --enable-usb-ohci \ + --enable-plugins \ + --enable-show-ips \ + --with-all-libs \ + ${CONFIGURE_ARGS} + ;; + +esac diff --git a/bochs/.conf.macos b/bochs/.conf.macos new file mode 100755 index 00000000..7efa36b3 --- /dev/null +++ b/bochs/.conf.macos @@ -0,0 +1,34 @@ +#!/bin/sh + +# This script will run configure for a Macintosh/CodeWarrior Pro +# environment. I actually run this on my Linux machine, but +# the generated files are for a Mac. + +set echo + +# These really just make ./configure happy on your Unix machine. +# They are not the options used on your Mac. +CC="gcc" +CFLAGS="" +CXX="$CC" +CXXFLAGS="$CFLAGS" + +export CC +export CXX +export CFLAGS +export CXXFLAGS + +./configure --target=ppc-macos \ + --enable-sb16 \ + --enable-all-optimizations \ + --enable-cpu-level=6 \ + --enable-x86-64 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb \ + --enable-plugins \ + --with-macos \ + ${CONFIGURE_ARGS} + +unset echo diff --git a/bochs/.conf.macosx b/bochs/.conf.macosx new file mode 100644 index 00000000..5157eb74 --- /dev/null +++ b/bochs/.conf.macosx @@ -0,0 +1,33 @@ +#!/bin/sh + +# this sets up the compile for MacOS X +# +# To support plugins on macosx, you must have "dlcompat" installed. You can +# get dlcompat by installing the fink package "dlcompat-devel". On the SF +# compile farm, dlcompat is in /sw/include and /sw/lib, so we have added +# those paths to the environment variables. + +set echo +CFLAGS="-pipe -O3 -I/sw/include -fomit-frame-pointer -finline-functions -falign-loops=16 -falign-jumps=16 -falign-functions=16 -falign-labels=16 -falign-loops-max-skip=15 -falign-jumps-max-skip=15 -fprefetch-loop-arrays $CFLAGS" +CPATH="/sw/include" +CPPFLAGS="" +CXXFLAGS="$CFLAGS" +LDFLAGS="-L/sw/lib" + +export CFLAGS +export CPATH +export CPPFLAGS +export CXXFLAGS +export LDFLAGS + +./configure --enable-sb16 \ + --enable-ne2000 \ + --enable-all-optimizations \ + --enable-cpu-level=6 \ + --enable-x86-64 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb \ + --enable-plugins \ + ${CONFIGURE_ARGS} diff --git a/bochs/.conf.nothing b/bochs/.conf.nothing new file mode 100755 index 00000000..052414e9 --- /dev/null +++ b/bochs/.conf.nothing @@ -0,0 +1,18 @@ +#!/bin/sh +# +# These are the steps I typically use to configure and compile Bochs +# on a Win32 system with cygwin (v.20.1) +# + +CC="gcc" +CXX="g++" +CFLAGS="-O3 -Wall -Wno-format" +CXXFLAGS="$CFLAGS" + +export CC +export CXX +export CFLAGS +export CXXFLAGS + +./configure --enable-cpu-level=3 \ + --disable-fpu diff --git a/bochs/.conf.sparc b/bochs/.conf.sparc new file mode 100755 index 00000000..fa4c8d09 --- /dev/null +++ b/bochs/.conf.sparc @@ -0,0 +1,31 @@ +#!/bin/sh + +# +# These are the steps I typically use to configure and compile Bochs. +# + +# superSPARC w/ Solaris 2.x +set echo +CC="gcc" +CXX="g++" +#CFLAGS="-Wall -O2 -mv8 -msupersparc -mno-epilogue" +CFLAGS="-Wall -O2 -mv8 -msupersparc" +#CFLAGS="-Wall -O2 -g" +CXXFLAGS="$CFLAGS" + + +export CC +export CXX +export CFLAGS +export CXXFLAGS + +./configure --enable-ne2000 \ + --enable-all-optimizations \ + --enable-cpu-level=6 \ + --enable-x86-64 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb + +unset echo diff --git a/bochs/.conf.win32-cygwin b/bochs/.conf.win32-cygwin new file mode 100755 index 00000000..15f52906 --- /dev/null +++ b/bochs/.conf.win32-cygwin @@ -0,0 +1,28 @@ +#!/bin/sh +# +# These are the steps I typically use to configure and compile Bochs +# on a Win32 system with cygwin (v.20.1) +# + +CC="gcc" +CXX="g++" +CFLAGS="-O3 -Wall -Wno-format" +CXXFLAGS="$CFLAGS" + +export CC +export CXX +export CFLAGS +export CXXFLAGS + +./configure --enable-sb16 \ + --enable-ne2000 \ + --enable-all-optimizations \ + --enable-cpu-level=6 \ + --enable-x86-64 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb \ + --enable-usb-ohci \ + --enable-show-ips \ + --with-win32 --with-rfb --with-nogui diff --git a/bochs/.conf.win32-vcpp b/bochs/.conf.win32-vcpp new file mode 100755 index 00000000..a476ad4c --- /dev/null +++ b/bochs/.conf.win32-vcpp @@ -0,0 +1,29 @@ +#!/bin/sh + +set echo + +./configure --target=pentium-windows \ + --enable-sb16 \ + --enable-ne2000 \ + --enable-all-optimizations \ + --enable-cpu-level=6 \ + --enable-x86-64 \ + --enable-pci \ + --enable-acpi \ + --enable-clgd54xx \ + --enable-usb \ + --enable-usb-ohci \ + --enable-show-ips \ + --disable-readline \ + --without-x \ + --with-win32 --with-rfb --with-nogui + +unset echo + +# Fix up all makefiles so that nmake can handle them. +for i in `find . -name Makefile`; do + echo Removing curly brackets in $i for NMAKE. + mv $i $i.tmp + sed -e 's/{/(/g' -e 's/}/)/g' < $i.tmp > $i + rm -f $i.tmp +done diff --git a/bochs/CHANGES b/bochs/CHANGES new file mode 100644 index 00000000..216dbaf1 --- /dev/null +++ b/bochs/CHANGES @@ -0,0 +1,3374 @@ +Changes in 2.4.6 (February 22, 2011): + +Brief summary : +- Support more host OS to run on: + - Include win64 native binary in the release. + - Fixed failures on big endian hosts. +- BIOS: Support for up to 2M ROM BIOS images. +- GUI: select mouse capture toggle method in .bochsrc. +- Ported most of Qemu's 'virtual VFAT' block driver + (except runtime write support, but plus FAT32 suppport) +- Added write protect option for floppy drives. +- Bugfixes / improved internal debugger + instrumentation. + +Detailed change log : + +- CPU and internal debugger + - Implemented Process Context ID (PCID) feature + - Implemented FS/GS BASE access instructions support + (according to document from http://software.intel.com/en-us/avx/) + - Rewritten from scratch SMC detection algorithm + - Implemented fine-grained SMC detection (on 128 byte granularity) + - Bugfixes for CPU emulation correctness and stability + - Fixed failures on Big Endian hosts ! + - Print detailed page walk information and attributes in + internal debugger 'page' command + - Updated/Fixed instrumentation callbacks + +- Configure and compile + - Bochs now can be compiled as native Windows x86-64 application + (tested with Mingw gcc 4.5.1 and Microsoft Visual Studio Express 2010) + - Added ability to configure CPUID stepping through .bochsrc. + The default stepping value is 3. + - Added ability to disable MONITOR/MWAIT support through .bochsrc + CPUID option. The option is available only if compiled with + --enable-monitor-mwait configure option. + - Determine and select max physical address size automatically at + configure time: + - 32-bit physical address for 386/486 guests + - 36-bit physical address for PSE-36 enabled Pentium guest + - 40-bit physical address for PAE enabled P6 or later guests + - Update config.guess/config.sub scripts to May 2010 revisions. + - Update Visual Studio 2008 project files in build/win32/vs2008ex-workspace.zip + - Added Bochs compilation timestamp after Bochs version string. + +- GUI and display libraries (Volker) + - Added new .bochsrc option to select mouse capture toggle method. + In addition to the default Bochs method using the CTRL key and the + middle mouse button there are now the choices: + - CTRL+F10 (like DOSBox) + - CTRL+ALT (like QEMU) + - F12 (replaces win32 'legacyF12' option) + - display library 'x' now uses the desktop size for the maximum guest resolution + +- ROM BIOS + - Support for up to 2M ROM BIOS images + +- I/O Devices + - 3 new 'pseudo device' plugins created by plugin separation (see below) + - Fixes for emulated DHCP in eth_vnet (patch from @SF tracker) + - Added support for VGA graphics mode with 400 lines (partial fix for SF bug #2948724) + - NE2K: Fixed "send buffer" command issue on big endian hosts + - USB + - converted common USB code plus devices to the new 'usb_common' plugin + Now the USB device classes no longer exist twice if both HC plugins are loaded. + - added 'pseudo device' in common USB code for the device creation. This makes + the HCs independent from the device specific code. + - USB MSD: added support for disk image modes (like ATA disks) + - USB printer: output file creation failure now causes a disconnect + - re-implemented "options" parameter for additional options of connected + devices (currently only used to set the speed reported by device and to + specify an alternative redolog file of USB MSD disk image modes) + - hard drive + - new disk image mode 'vvfat' + - ported the read-only part of Qemu's 'virtual VFAT' block driver + - additions: configurable disk geometry, FAT32 support, read MBR and/or + boot sector from file, volatile write support using hdimage redolog_t + class, optional commit support on Bochs exit, save/restore file + attributes, 1.44 MB floppy support, set file modification date/time + - converted the complete hdimage stuff to the new 'hdimage' plugin + - new hdimage method get_capabilities() that can return special flags + - vmware3, vmware4 and vvfat classes now return HDIMAGE_HAS_GEOMETRY flag + - other disk image modes by default return HDIMAGE_AUTO_GEOMETRY if + cylinder value is set to 0 + - multiple sector read/write support for some image modes + - new log prefix "IMG" for hdimage messages + - floppy + - added write protect option for floppy drives (based on @SF patch by Ben Lunt) + - vvfat support + - bugfix: close images on exit + - SB16 + - converted the sound output module stuff to the new 'soundmod' plugin + +- SF patches applied + [3164945] hack to compile under WIN64 by Darek Mihocka and Stanislav + [3164073] Fine grain SMC invalidation by Stanislav + [1539417] write protect for floppy drives by Ben Lunt + [2862322] fixes for emulated DHCP in eth_vnet + +- these S.F. bugs were closed/fixed + [2588085] Mouse capture + [3140332] typo in mf3/ps2 mapping of BX_KEY_CTRL_R + [3111577] No "back" option in log settings + [3108422] Timing window in NE2K emulation + [3084390] Bochs won't load floppy plugin right on startup + [3043174] Docbook use of '_' build failure + [3085140] Ia_arpl_Ew_Rw definition of error + [3078995] ROL/ROR/SHL/SHR modeling wrong when dest reg is 32 bit + [2864794] BX_INSTR_OPCODE in "cpu_loop" causes crash in x86_64 host + [2884071] [AIX host] prefetch: EIP [00010000] > CS.limit [0000ffff] + [3053542] 64 bit mode: far-jmp instruction is error + [3011112] error compile vs2008/2010 with X2APIC + [3002017] compile error with vs 2010 + [3009767] guest RFLAGS.IF blocks externel interrupt in VMX guest mode + [2964655] VMX not enabled in MSR IA32_FEATURE_CONTROL + [3005865] IDT show bug + [3001637] CMOS MAP register meaning error + [2994370] Cannot build with 3DNow support + +- these S.F. feature requests were closed/implemented + [1510142] Native Windows XP x64 Edition binary + [1062553] select mouse (de)activation in bochsrc + [2930633] legacy mouse capture key : not specific enough + [2930679] Let user change mouse capture control key + [2803538] Show flags for pages when using "info tab" + +------------------------------------------------------------------------- +Changes in 2.4.5 (April 25, 2010): + +Brief summary : +- Major configure/cpu rework allowing to enable/disable CPU options at runtime + through .bochsrc (Stanislav) +- Bugfixes for CPU emulation correctness and stability +- Implemented X2APIC extensions (Stanislav) +- Implemented Intel VMXx2 extensions (Stanislav) + - Extended VMX capability MSRs, APIC Virtualization, + X2APIC Virtualization, Extended Page Tables (EPT), + VPID, Unrestricted Guests, new VMX controls. +- Implemented PCLMULQDQ AES instruction +- Extended Bochs internal debugger functionality +- USB HP DeskJet 920C printer device emulation (Ben Lunt) + +Detailed change log : + +- Configure rework + - Deprecate --enable-popcnt configure option. POPCNT instruction will be + enabled automatically iff SSE4_2 is supported (like in hardware). + + - Make --ignore-bad-msrs runtime option in .bochsrc. Old --ignore-bad-msrs + configure option is deprecated and should not be used anymore. + + - Enable changing part of CPU functionality at runtime through .bochsrc. + - Now you could enable/disable any of SSEx/AES/MOVBE/SYSENTER_SYSEXIT/XSAVE + instruction sets using new CPUID option in .bochsrc. + - When x86-64 support is compiled in, you could enable/disable long mode + 1G pages support without recompile using new CPUID option in .bochsrc. + Configure options: + --enable-mmx, --enable-sse, --enable-movbe, --enable-xsave, + --enable-sep, --enable-aes, --enable-1g-pages + are deprecated and should not be used anymore. + + - Local APIC configure option --enable-apic is deprecated and should not + be used anymore. The LAPIC option now automatically determined from + other configure options. XAPIC functionality could be enabled using + new CPUID .bochsrc option. + + - Changed default CPU configuration (generated by configure script with + default options) to BX_CPU_LEVEL=6 with SSE2 enabled. + +- CPU + - Implemented PCLMULQDQ AES instruction + - Implemented X2APIC extensions / enable extended topology CPUID leaf (0xb), + in order to enable X2APIC configure with --enable-x2apic + - Implemented Intel VMXx2 extensions: + - Enabled extended VMX capability MSRs + - Implemented VMX controls for loading/storing of MSR_PAT and MSR_EFER + - Enabled/Implemented secondary proc-based vmexec controls: + - Implemented APIC virtualization + - Implemented Extended Page Tables (EPT) mode + - Implemented Descriptor Table Access VMEXIT control + - Implemented RDTSCP VMEXIT control + - Implemented Virtualize X2APIC mode control + - Implemented Virtual Process ID (VPID) + - Implemented WBINVD VMEXIT control + - Implemented Unrestricted Guest mode + In order to enable emulation of VMXx2 extensions configure with + --enable-vmx=2 option (x86-64 must be enabled) + - Bugfixes for CPU emulation correctness + - Fixed Bochs crash when accessing the first byte above emulated memory size + +- Internal Debugger + - Introduced range read/write physical watchpoints + - Allow reloading of segment registers from internal debugger + - Improved verbose physical memory access tracing + +- BIOS + - Fix MTRR configuration (prevented boot of modern Linux kernels) + - Fix interrupt vectors for INT 60h-66h (reserved for user interrupt) by + setting them to zero + - Fix BIOS INT13 function 08 when the number of cylinders on the disk = 1 + +- I/O Devices + - USB HP DeskJet 920C printer device emulation (Ben Lunt) + +- Misc + - Updated Bochs TESTFORM to version 0.5 + +- SF patches applied + [2864402] outstanding x2apic patches by Stanislav + [2960379] Fix build with -Wformat -Werror=format-security by Per Oyvind Karlsen + [2938273] allow instrumentation to change execute by Konrad Grochowski + [2926072] Indirection operators in expressions by Derek Peschel + [2914433] makesym.perl misses symbols by John R. Jackson + [2908481] USB Printer by Ben Lunt + +- these S.F. bugs were closed/fixed + [2861662] dbg_xlate_linear2phy needs to be updated + [2956217] INT13 AH=8 returns wrong values when cylinders=1 + [2981161] Allow DMA transfers to continue when CPU is in HALT state + [2795115] NX fault could be missed + [2964824] bad newline sequence in aspi-win32.h + [913419] configure options and build process needs some work + [2938398] gdbstub compile error with x86_64 enabled + [2734455] shutdown/reset type 05 should reinit the PICs + [1921294] extended memory less than 1M wrong size + [1947249] BX_USE_EBDA_TABLES and MP table placement + [1933859] BX_USE_EBDA_TABLES and memory overlapping + [2923680] "help dregs" is a syntax error + [2919661] CPU may fail to do 16bit near call + [2790768] Memory corruption with SMP > 32, Panic BIOS Keyboard Error + [2902118] interrupts vectors 0x60 to 67 should be NULL ! + [2912502] Instruction Pointer behaving erratically + [2901047] Bochs crashed, closed by guest os + [2905385] Bochs crash + [2901481] Instruction SYSRET and SS(PL) + [2900632] Broken long mode RETF to outer priviledge with null SS + [1429011] Use bx_phyaddr_t for physaddr vars and bx_adress for lin adr + +- these S.F. feature requests were closed/implemented + [2955911] RPM preuninstall scriptlet removes /core + [2947863] don't abort on unrecognised options + [2878861] numerics in the disassembler output + [2900619] make more CPU state changeable + +------------------------------------------------------------------------- +Changes in 2.4.2 (November 12, 2009): + +- CPU and internal debugger + - VMX: Implemented TPR shadow VMEXIT + - Bugfixes for CPU emulation correctness (mostly for VMX support). + - Bugfixes and updates for Bochs internal debugger + - On SMP system stepN command now affects only current processor + +- Memory + - Bugfixes for > 32-bit physical address space. + - Allow to emulate more physical memory than host actually could or would + like to allocate. For more details look for new .bochsrc 'memory' option. + +- Cleanup configure options + - All paging related options now will be automatically determined according + to --enable-cpu-level option. Related configure options + --enable-global-pages, --enable-large-pages, + --enable-pae, --enable-mtrr + are deprecated now. Only 1G paging option still remaining unchanged. + - Deprecate --enable-daz configure option. Denormals-are-zeros MXCSR control + will be enabled automatically iff SSE2 is supported (like in hardware). + - Deprecate --enable-vme configure option, now it will be supported iff + CPU_LEVEL >= 5 (like in hardware). + +- I/O Devices + - Bugfixes for 8254 PIT, VGA, Cirrus-Logic SVGA, USB UCHI + +- SF patches applied + [2817840] Make old_callback static by Mark Marshall + [2874004] fix for VMWRITE instruction by Roberto Paleari + [2873999] fix CS segment type during fast syscall invocation by Roberto Paleari + [2864389] Debugger gui maximize on startup by Thomas Nilsen + [2817868] Rework loops in the memory code by Mark Marshall + [2812948] PIT bug by Derek + +- these S.F. bugs were closed/fixed + [2833504] GUI debugger bug-about GDT display + [2872244] BIOS writes not allowed value to MTRR MSR causing #GP + [2885383] SDL GUI memory leak + [2872290] compilation in AIX5.3 ML10 failes + [2867904] crash with cirrus bx_vga_c::mem_write + [2851495] BIOS PCI returns with INT flag = 0 + [2860333] vista 64 guest STOP 109 (GDT modification) + [2849745] disassembler bug for 3DNow and SSE opcodes + [1066748] Wrong registers values after #RESET, #INIT + [2836893] Regression: Windows XP installer unable to format harddrive + [2812239] VMX: VM-Exit: Incorrect instruction length on software int + [2814130] bx_debug lex/yacc files incorrectly generated + [2813199] MP Tables Missing From BIOS + [2824093] VMX exception bug + [2811909] VMX : CS Access-rights Type.Accessed stays 0 + [2810571] Compile Errors on OSX + [2823749] GCC regression or VM_EXIT RDMSR/WRMSR bug + [2815929] Vista/XP64 unnecessary panic + [2803519] Wrong example in man page bochsrc + +- these S.F. feature requests were closed/implemented + [422766] Large Memory configurations + [1311287] Idea for a better GUI + [455971] USB support + [615363] debugger shortcut for repeat last cmd + +------------------------------------------------------------------------- +Changes in 2.4.1 (June 7, 2009): + +- Fixed bunch of CPUID issues + - Bochs is now able to install and boot 64-bit Windows images! + (special thanks to Mark Ebersole for his patch) +- Several bugfixes in CPU emulation (mostly for x87 instructions) +- Fixed two critical deadlock bugs in the Win32 gui (patches from @SF tracker) +- Fixes related to the 'show ips' feature + - removed conflicting win32-specific alarm() functions ('win32' and 'sdl' gui) + - feature now works in wx on win32 +- Added support for gdb stub on big endian machine (patch by Godmar Back) +- Rewritten obsolete hash_map code in dbg symbols module (patch from @SF) +- BIOS: implemented missing INT 15h/89h (patch by Sebastian Herbszt) + +------------------------------------------------------------------------- +Changes in 2.4 (May 3, 2009): + +Brief summary : + +- Added graphical Bochs debugger frontend for most of the supported platforms. + - Thanks for Chourdakis Michael and Bruce Ewing. +- Many new CPU features in emulation + - Support for > 32 bit physical address space and configurable MSRs + - VMX, 1G pages in long mode, MOVBE instruction +- Bugfixes for CPU emulation correctness, debugger and CPU instrumentation. +- New config interface 'win32config' with start and runtime menu +- USB: added OHCI support, external hub and cdrom +- Added user plugin interface support. + +Detailed change log : + +- CPU and internal debugger + - Support for VMX hardware emulation in Bochs CPU, to enable configure with + --enable-vmx option + Nearly complete VMX implementation, with few exceptions: + - Dual-monitor treatment of SMIs and SMM not implemented yet + - NMI virtualization, APIC virtualization not implemented yet + - VMENTER to not-active state not supported yet + - No advanced features like Extended Page Tables or VPID + - Support for configurable MSR registers emulation, to enable configure with + --enable-configurable-msrs option + Look for configuration example in .bochsrc and msrs.def + - Support new Intel Atom(R) MOVBE instruction, to enable configure with + --enable-movbe option + - Support for 1G pages in long mode, to enable configure with + --enable-1g-pages option + - Support for > 32 bit physical address space in CPU. Up to 36 bit could be + seen in legacy mode (PAE) and up to 40 bit in x86-64 mode. + Still support the same amount of the physical memory in the memory object, + so system with > 4Gb of RAM yet cannot be emulated. + To enable configure with --enable-long-phy-address option. + - Implemented modern BIOSes mode limiting max reported CPUID function + to 3 using .bochsrc CPU option. The mode is required in order to + correctly install and boot WinNT. + - Added ability to configure CPUID vendor/brand strings through .bochsrc + (patch from @SF by Doug Reed). + - Many bugfixes for CPU emulation correctness (both x86 and x86-64). + - Updated CPU instrumentation callbacks. + - Fixed Bochs internal debugger breakpoints/watchpoints handling. + +- Configure and compile + - Added ability to choose Bochs log file name and Bochs debugger log file + name from Bochs command line (using new -log and -dbglog options) + - Removed Peter Tattam's closed source external debugger interface from + the code. + - Removed --enable-guest2host-tlb configure option. The option is always + enabled for any Bochs configuration. + - Removed --enable-icache configure option. The option is always enabled + for any Bochs configuration. Trace cache support still remains optional + and could be configured off. + - Added configure option to compile in GUI frontend for Bochs debugger, + to enable configure with --enable-debugger-gui option. + The GUI debugger frontend is enabled by default with Bochs debugger. + - Removed --enable-port-e9-hack configure option. The feature now could be + configured at runtime through .bochsrc. + - Added configure option to enable/disable A20 pin support. Disabling the + A20 pin support slightly speeds up the emulation. + - reduced dependencies between source files for faster code generation + +- BIOS + - Added S3 (suspend to RAM) ACPI state to BIOS (patch by Gleb Natapov) + - Implemented MTRR support in the bios (patches by Avi Kivity and Alex + Williamsion with additions by Sebastian Herbszt) + - Bug fixes + +- I/O Devices + - Added user plugin support + - remaining devices converted to plugins: pit, ioapic, iodebug + - added 'plugin_ctrl' bochsrc option to control the presence of optional + device plugins without a separate option. By default all plugins are enabled. + - added register mechanism for removable mouse and keyboard devices + - Hard drive / cdrom + - PACKET-DMA feature now supported by all ATAPI commands + - ATAPI command 0x1A added (based on the Qemu implementation) + - sb16 + - Added ALSA sound support on Linux (PCM/MIDI output) + - FM synthesizer now usable with MIDI output (simple piano only) + - Fixed OPL frequency to MIDI note translation + - Fixed MIDI output command + - keyboard + - added keyboard controller commands 0xCA and 0xCB + - USB + - USB code reorganized to support more HC types and devices + - added USB OHCI support written by Ben Lunt + - added external USB hub support (initial code ported from Qemu) + - added USB cdrom support (SCSI layer ported from Qemu) + - added status bar indicators to show data transfer + - VGA + - VBE video memory increased to 16 MB + - implemented changeable VBE LFB base address (PCI only, requires latest + BIOS and VGABIOS images) + - I/O APIC + - implemented I/O APIC device hardware reset + +- Config interface + - new config interface 'win32config' with start and runtime menu is now + the default on Windows ('textconfig' is still available) + - win32 device config dialogs are now created dynamicly from a parameter list + (works like the wx ParamDialog) + - changes in textcofig and the wx ParamDialog for compatibility with the new + win32 dialog behaviour + - Bochs param tree index keys are case independent now + - some other additions / bugfixes in the simulator interface code + +- Misc + - updated LGPL'd VGABIOS to version 0.6c + - Updated Bochs TESTFORM to version 0.4 + +- SF patches applied + [2784858] IO Handler names are not compared properly + [2712569] Legacy bios serial data buffer timeout bug by grybranix + [2655090] 64 bit BSWAP with REX.W broken by M. Eby + [2645919] CR8 bug when reading by M. Eby + [1895665] kvm: bios: add support to memory above the pci hole by Izik Eidus + [2403372] rombios: check for valid cdrom before using it by Sebastian + [2307269] acpi: handle S3 by Sebastian + [2354134] TAP networking on Solaris/Sparc repaired + [2144692] The scsi device can not complete its writing data command by naiyue + [1827082] [PATCH] Configurable CPU vendor by Marcel Sondaar + [2217229] Panic on EBDA overflow in rombios32 by Sebastian + [2210194] Log pci class code by Sebastian + [1984662] red led for disk write and titlebar mod by ggbsf + [2142955] Fix for monitor/mwait by Doug Gibson + [2137774] Patch to fix bug: cdrom: read_block: lseek returned error by Gabor Olah + [2134642] Fix scan_to_scanascii table for F11 and F12 by Ben Guthro & Steve Ofsthun + [2123036] sdl fullscreen fix by ggbsf + [2073039] Remove CMOS accsess from AML code by Gleb Natapov + [2072168] smbios: add L1-L3 cache handle to processor information by Sebastian + [2055416] bochsrc cpu options for cpuid vendor and brand string by Doug Reed + [2035278] rombios: Fix return from BEV via retf by Sebastian + [2035260] rombios: El Torito load segment fix by Sebastian + [2031978] Fix VMware backdoor command 0Ah by Jamie Lokier + [2015277] Remove obsolete comment about DATA_SEG_DEFS_HERE hack by Sebastian + [2011268] Set new default format and unit only if both are supported by Sebastian + [2001919] gdbstub: fix qSupported reply by Sebastian + [2001912] gdbstub: enclose packet data by apostrophes by Sebastian + [1998071] fix missing SIGHUP and SIGQUIT with term ui on mingw by Sebastian + [1998063] fix wrong colors with term ui by Sebastian + [1995064] Compile fix needed for --enable-debugger and gcc 4.3 by Hans de Goede + [1994564] Fix typo in RDMSR BX_MSR_MTRRFIX16K_A0000 by Sebastian + [1994396] Change hard_drive_post #if by Sebastian + [1993235] TESTFORM email address update by Sebastian + [1992322] PATCH: fix compilation of bochs 2.3.7 on bigendian machines by Hans de Goede + [1991280] Shutdown status code 0Ch handler by Sebastian + [1990108] Shutdown status code 0Bh handler by Sebastian + [1988907] Shutdown status code 0Ah handler by Sebastian + [1984467] two typos in a release! (2.3.7) + [1981505] Init PIIX4 PCI to ISA bridge and IDE by Sebastian + +- these S.F. bugs were closed/fixed + [2784148] an integer overflow BUG of Bochs-2.3.7 source code + [2695273] MSVC cpu.dsp failure in 2.3.7.zip + [616114] Snapshot/Copy crash on Win2K + [2628318] 'VGABIOS-latest' bug + [1945055] can't 'make install' lastest bochs on loepard + [2031993] Mac OS X Makefile bug + [1843199] install error on mac osx + [2710931] Problem compiling both instrumentation and debugger + [2617003] ExceptionInfo conflicts with OS X api + [2609432] stepping causes segfault (CVS) + [2605861] compile error with --enable-smp + [1757068] current cvs(Jul19, 07) failed to boot smp + [2426271] cannot get correct symbol entry + [2471982] VGA character height glitches + [1659659] wrong behaviour a20 at boot + [1998027] minwg + --with-term + --with-out-win32 = link failure + [1871936] bochs-2.3.6 make fails on wx.cc + [1684666] info idt for long mode + [2105989] could not read() hard drive image file at byte 269824 + [1173093] Debugger totally not supports x86-64 + [1803018] new win32debug dialog problems + [2141679] windows vcc build broken + [2162824] latest cvs fails to compile + [2164506] latest bochs fails to start + [2129223] MOV reg16, SS not working in real mode due to dead code + [2106514] RIS / startrom.com install ALMOST works + [2123358] SMP (HTT): wbinvd executed by CPU1 crashes CPU0 + [2002758] Arch Linux: >>PANIC<< ATAPI command with zero byte count + [2026501] El Torito incorrect boot segment:offset + [2029758] BEV can return via retf instead of int 18h + [2010173] x command breaks after one error about x/s or x/i + [1830665] harddrv PANIC: ATAPI command with zero byte count + [1985387] fail to make using gcc4 with --enable-debugger + [1990187] testform feedback + [1992138] Misspell in cpu/ia_opcodes.h + +- these S.F. feature requests were closed/implemented + [2175153] Update MSVC project files + [658800] front end program and bios + [1883370] Make cd and floppy images more usable + [422783] change floppy size without restarting + [2552685] param tree names should be case insensitive + [1214659] PC Speaker emu turnoff. Plugin Controll. + [1977045] support 40 bit physical address + [1506385] Intel Core Duo VT features + [1429015] Support for user plugins + [1488136] debugger access to floppy controller + [1363136] Full debugger SMP and 64 bit support + [2068304] Support for ACPI + [431032] debugger "x" command + [423420] profiling ideas (SMF) + [445342] Add FM support? + [928439] alsa + +------------------------------------------------------------------------- +Changes in 2.3.7 (June 3, 2008): + +Brief summary : + ++ More optimizations in CPU code - Bochs 2.3.7 is more than 2x faster + than Bochs 2.3.5 build ! +- Implemented LBA48 support in BIOS +- Added memory access tracing for Bochs internal debugger +- Implemented Intel(R) XSAVE/XRSTOR and AES instruction set extensions +- Many fixes in CPU emulation and internal debugger + - MenuetOS64 floppy images booting perfect again ! +- updated LGPL'd VGABIOS to version 0.6b + +Detailed change log : + +- CPU + - Support of XSAVE/XRSTOR CPU extensions, to enable configure with + --enable-xsave option + - Support of AES CPU extensions, to enable configure with + --enable-aes option + - Fixed Bochs failure on RISC host machines with BxRepeatSpeedups + optimization enabled + - Implemented SYSENTER/SYSEXIT instructions in long mode + - More than 100 bugfixes for CPU emulation correctness (both x86 and x86-64) + - MenuetOS64 floppy images booting perfect again ! + - Updated CPU instrumentation callbacks + +- Bochs Internal Debugger and Disassembler + - Added memory access tracing for Bochs internal debugger, enable + by typing 'trace-mem on' in debugger command line + - Many bug fixes in Bochs internal debugger and disassembler + +- System BIOS (Volker) + - Implemented LBA48 support + - Added generation of SSDT ACPI table that contains definitions + for available processors + - Added RTC device to ACPI DSDT table + - Added implementation of SMBIOS + +- I/O devices (Volker) + - VGA + - Implemented screen disable bit in sequencer register #1 + - Implemented text mode cursor blinking + - Serial + - new serial modes 'pipe-server' and 'pipe-client' for win32 + - new serial mode 'socket-server' + +- Configure and compile + - Fixed configure bug with enabling of POPCNT instruction, POPCNT + instruction should be enabled by default when SSE4.2 is enabled. + - Removed --enable-magic-breakpoint configure option. The option is + automatically enabled if Bochs internal debugger is compiled in. + It is still possible to turn on/off the feature through .bochsrc. + - Allow boot from network option in .bochsrc + - Added Bochs version info for Win32 + +- Display libraries + - implemented text mode character blinking in some guis + - improved 'X' gui runtime dialogs + +- SF patches applied + [1980833] Fix shutdown status code 5h handler by Kevin O'Connor + [1928848] "pipe" mode for serial port (win32 only) by Eugene Toder + [1956843] Set the compatible pci interrupt router back to PIIX by Sebastian + [1956366] Do not announce C2 & C3 cpu power state support by Igor Lvovsky + [1921733] support for LBA48 by Robert Millan + [1938185] Fix link problem with --enable-debugger by Sebastian + [1938182] Makefile.in - use @IODEV_LIB_VAR@ by Sebastian + [1928945] fix for legacy rombios - e820 map and ACPI_DATA_SIZE by Sebastian + [1925578] rombios32.c - fix ram_size in ram_probe for low memory setup by Sebastian + [1908921] rombios32.c - move uuid_probe() call by Sebastian + [1928902] improvements to load-symbols by Eugene Toder + [1925568] PATCH: msvc compilation by Eugene Toder + [1913150] rombios.c - e820 cover full size if memory <= 16 mb by Alexander van Heukelum + [1919804] rombios.c - fix and add #ifdef comments by Sebastian + [1909782] rombios.c - remove segment values from comment by Sebastian + [1908918] SMBIOS - BIOS characteristics fix by Sebastian + [1901027] BIOS boot menu support (take 3) + [1902579] rombios32.c - define pci ids by Sebastian + [1859447] Pass segment:offset to put_str and introduce %S by Sebastian + [1889057] rombios.c - boot failure message by Sebastian + [1891469] rombios.c - print BEV product string by Sebastian + [1889851] Win32 version information FILEVERSION for bochs.exe by Sebastian + [1889042] rombios.c - fix comment by Sebastian + [1881500] bochsrc, allow boot: network by Sebastian + [1880755] Win32 version information for bochs.exe by Sebastian + [1880471] SMBIOS fix type 0 by Sebastian + [1878558] SMBIOS fixes by Sebastian + [1864692] SMBIOS support by Filip Navara + [1865105] Move bios_table_area_end to 0xcc00 by Sebastian + [1875414] Makefile.in - change make use by Sebastian + [1874276] Added instrumentation for sysenter/sysexit by Lluis + [1873221] TLB page flush: add logical address to instrumentation by Lluis + [1830626] lba32 support by Samuel Thibault + [1861839] Move option rom scan after floppy and hard drive post by Sebastian + [1838283] Early vga bios init by Sebastian + [1838272] rom_scan range parameter by Sebastian + [1864680] Save CPUID signature by Filip Navara + +- these S.F. bugs were closed + [1976171] Keyboard missing break code for enter (0x9C) + [666433] physical read/write breakpoint sometimes fails + [1744820] info gdt and info idt shows the entire tables + [1755652] graphics: MenuetOS64 shows black screen + [1782207] Windows Installer malfunction, Host=Linux, Guest=Win98SE + [1697762] OS/2 Warp Install Failed + [1952548] String to char * warnings + [1940714] SYSENTER/SYSEXIT doesn't work in long mode + [1422342] SYSRET errors + [1923803] legacy rombios - e820 map and ACPI_DATA_SIZE + [1936132] Link problem with --enable-debugger & --enable-disasm + [1934477] Linear address wrap is not working + [1424984] virtual machine freezes in Bochs 2.2.6 + [1902928] with debugger cpu_loop leaves CPU with unstable state + [1898929] Bochs VESA BIOS violates specs (banks == 1) + [1569256] bug in datasegment change in long mode + [1830662] ACPI: no DMI BIOS year, acpi=force is required + [1868806] VGA blink enable & screen disable + [1875721] Bit "Accessed" in LDT/GDT descriptors & #PF + [1874124] bx_Instruction_c::ilen() const + [1873488] bochs-2.3.6 make fails on dbg_main.cc + +- these S.F. feature requests were implemented + [1422769] SYSENTER/SYSEXIT support in x86-64 mode + [1847955] Version information for bochs(dbg).exe + [939797] SMBIOS support + +------------------------------------------------------------------------- +Changes in 2.3.6 (December 24, 2007): + +Brief summary : + ++ More than 25% emulation speedup vs Bochs 2.3.5 release! + + - Thanks to Darek Mihocka (http://www.emulators.com) + for providing patches and ideas that made the + speedup possible! + ++ Up to 40% speedup vs Bochs 2.3.5 release with trace cache optimization! + +- Lots of bugfixes in CPU emulation +- Bochs benchmarking support +- Added emulation of Intel SSE4.2 instruction set + +Detailed change log : + +- CPU + - Added emulation of SSE4.2 instruction set, to enable use + --enable-sse=4 --enable-sse-extension configure options + to enable POPCNT instruction only use configure option + --enable-popcnt + - Implemented MTRR emulation, to enable use --enable-mtrr configure + option. MTRRs is enabled by default when cpu-level >= 6. + - Implemented experimental MONITOR/MWAIT support including optimized + MWAIT CPU state and hardware monitoring of physical address range, + to enable use --enable-monitor-mwait configure option. + - Removed hostasm optimizations, after Bochs rebenchmarking it was found + that the feature bringing no speedup or even sometimes slows down + emulation! + - Merged trace cache optimization patch, the trace cache optimization + is enabled by default when configure with --enable-all-optimizations + option, to disable trace cache optimization configure with + --disable-trace-cache + - Many minor bugfixes in CPU emulation (both ia32 and x86-64) + - Updated CPU instrumentation callbacks + +- Bochs Internal Debugger and Disassembler + - Many fixes in Bochs internal debugger and disassembler, some debugger + interfaces significantly changed due transition to the param tree + architecture + - Added support for restoring of the CPU state from external file + directly from Bochs debugger + +- Configure and compile + - Renamed configure option --enable-4meg-pages to --enable-large-pages. + The option enables page size extensions (PSE) which refers to 2M pages + as well. + - Removed --enable-save-restore configure option, save/restore feature + changed to be one of the basic Bochs features and compiled by default + for all configurations. + - Added new Bochs benchmark mode. To run Bochs in benchmark mode execute + it with new command line option 'bochs -benchmark time'. The emulation + will be automatically stopped after 'time' millions of emulation + cycles executed. + - Another very useful option for benchmarking of Bochs could be enabled + using new 'print_timestamps' directive from .bochsrc: + print_timestamps: enable=1 + - Added --enable-show-ips option to all configuration scripts used to + build release binaries, so all future releases will enjoy IPS display. + - Enable alignment check in the CPU and #AC exception by default for + --cpu-level >= 4 (like in real hardware) + +- SF patches applied + [1491207] Trace Cache Speedup patch by Stanislav + [1857149] Define some IPL values by Sebastian + [1850183] Get memory access mode in BX_INSTR_LIN_READ by Lluis Vilanova + [1841421] pic: keep slave_pic.INT and master_pic.IRQ_in bit 2 in sync by Russ Cox + [1841420] give segment numbers in exception logs by Russ Cox + [1801696] Allow Intel builds on Mac OS X + [1830658] Fix >32GB disk banner by Samuel Thibault + [1813314] Move #define IPL_* and typedef ipl_entry by Sebastian + [1809001] Save PnP Option ROM Product Name string in IPL Boot Table by Sebastian + [1821242] Fix for #1801285, Niclist.exe broken by Sebastian + [1819567] Code warning cleanup + [1816162] Update comment on bios_printf() by Sebastian + [1811139] Trivial Fix when BX_PCIBIOS and BX_ROMBIOS32 not defined by Myles Watson + [1811190] Improve HD recognition and CD boot by Myles Watson + [1811860] Implement %X in bios_printf by Sebastian + [1809649] printf %lx %ld %lu by Myles Watson + [1809651] move BX_SUPPORT_FLOPPY by Myles Watson + [1809652] dpte and Int13DPT fixes by Myles Watson + [1809669] clip cylinders to 16383 in hard drive by Myles Watson + [1799903] Build BIOS on amd64 by Robert Millan + [1799877] Fix for parallel build (make -j2) by Robert Millan + +- these S.F. bugs were closed + [1837354] website bug: View the Source link broken + [1801268] Reset from real mode no longer working + [1843250] Using forward slashes gives invalid filename + [1823446] BIOS bug, local APIC #0 not detected + [1801285] Niclist.exe broken + [1364472] breakpoints sometimes don't work + [994451] breakpoint bug + [1801295] NSIS installer vs Windows Notepad + [1715328] Unreal mode quirk + [1503972] debugger doesn't debug first instruction on exception + [1069071] div al, byte ptr [ds:0x7c18] fails to execute + [1800080] Wrong "BX_MAX_SMP_THREADS_SUPPORTED" assertion + +- these S.F. feature requests were implemented + [1662687] Download for Win32-exe with x64 Mode and debugging + [604221] Debugger command: query lin->phys mapping + +------------------------------------------------------------------------- +Changes in 2.3.5 (September 16, 2007): + +Brief summary : +- Critical problems fixed for x86-64 support in CPU and Bochs internal debugger +- ACPI support +- The release compiled with x86-64 and ACPI +- Hard disk emulation supports ATA-6 (LBA48 addressing, UDMA modes) +- Added emulation of Intel SSE4.1 instruction set + +Detailed change log : + +- CPU + - Fixed critical bug with 0x90 opcode (NOP) handling in x86-64 mode + - implied stack references where the stack address is not in canonical form + should causes a stack exception (#SS) + - Added emulation of SSE4.1 instruction set (Stanislav) + - Do not save and restore XMM8-XMM15 registers when not in x86-64 mode + - Fixed zero upper 32-bit part of GPR in x86-64 mode + - CMOV_GdEd should zero upper 32-bit part of GPR register even if the + 'cmov' condition was false ! + - Implemented CLFLUSH instruction, report non-zero cache size in CPUID + - Fixed PUSHA/POPA instructions behavior in real mode + - Fixed detection of inexact result by FPU + - Fixed denormals-are-zero (DAZ) handling by SSE convert instructions + - Implemented Misaligned Exception Mask support for SSE (MXCSR[17]) + - Implemented Alignment Check in the CPU and #AC exception, to enable + use --enable-alignment-check configure option + +- General + - 2nd simulation support in wxBochs now almost usable (simulation cleanup + code added and memory leaks fixed) + +- Configure and compile + - several fixes for MacOSX, OpenBSD and Solaris 10 + - enable save/restore feature by default for all configurations + - reorganized SSE configure options to match Intel(R) Programming + Reference Manual, new option introduced for SSE extensions enabling. + To enable Intel Core Duo 2 new instructions use + --enable-sse=3 --enable-sse-extension + enabling of SSE4.1 (--enable-sse=4) will enable SSE3 extensions as well + - removed old PIT, always use new PIT written by Greg Alexander, + removed configure option --enable-new-pit + +- I/O devices (Volker) + - Floppy + - partial non-DMA mode support (patch by John Comeau) + - Hard drive / cdrom + - hard disk emulation now supports ATA-6 (LBA48 addressing, UDMA modes) + - VMWare version 4 disk image support added (patch by Sharvil Nanavati) + - PCI + - initial support for the PIIX4 ACPI controller + - Serial + - added support for 3-button mouse with Mousesystems protocol + - USB + - experimental USB device change support added + - rewrite of the existing USB devices code + - new USB devices 'disk' and 'tablet' (ported from the Qemu project) + +- Bochs internal debugger + - fixed broken debugger "rc file" option (execute debugger command from file) + - implementation of a gui frontend ("windebug") for win32 started + - gdbstub now accepts connection from any host + - several documentation updates + - a lot of disasm and internal debugger x86_64 support fixes + +- Configuration interface + - fixes and improvements to the save state dialog handling + +- Display libraries + - text mode color handling improved in some guis + - win32 fullscreen mode (patch by John Comeau) + +- System BIOS (Volker) + - 32-bit PM BIOS init code for ACPI, PCI, SMP and SMM (initial patches by + Fabrice Bellard) + - PCI BIOS function "find class code" implemented + +- SF patches applied + [1791000] 15h 8600h is reading the wrong stack frame by Sebastian + [1791016] rombios32.c, ram_probe(), BX_INFO missing value by Sebastian + [1786429] typo in bochsrc.5 by Sebastian + [1785204] Extend acpi_build_table_header to accept a revision number by Sebastian + [1766536] Partial Patch for Bug Report 1549873 by Ben Lunt + [1763578] ACPI Table Revision 0 -> 1 + [1642490] implement alignment check and #AC exception by Stanislav Shwartsman + [1695652] [PATCH] .pcap pktlog and vnet PXE boot by Duane Voth + [1741153] Add expansion-ROM boot support to the ROMBIOS + [1734159] Implemented INT15h, fn 0xC2 (mouse), subfn 3, set resolution + [1712970] bios_printf %s fix + [1573297] PUSHA/POPA real mode fix by Stanislav Shwartsman + [1641816] partial support for non-DMA access to floppy by John Comeau + [1624032] shows where write outside of memory occurred by John Comeau + [1607793] allow fullscreen when app requests it by John Comeau + [1603013] Bugfix for major NOP problem on x64 by mvysin + [1600178] Make tap and tuntap compile on OpenBSD by Jonathan Gray + [1149659] improve gdbstub network efficiency by Avi Kivity + [1554502] Trivial FPU exception handling fix + +- these S.F. bugs were closed + [1316008] Double faults when it shouldn't - gcc 4.0.2 + [1787289] broken ABI for redolog class when enable-compressed-hd + [1787500] tftp_send_optack not 64bit clean + [1264540] Security issue with Bochs website + [1767217] Debugger Faults including ud2 + [1729822] Various security issues in io device emulation + [1675202] mptable hosed (bad entry count in header) + [1197141] 'make install' installs to bad location + [1157623] x86Solaris10 cannot recoginize ACPI RSD PTR + [1768254] large HDD in Bochs/bximage + [1496157] Windows Vista Beta2 dosn't boot + [1755915] Illegal Hard Disk Signature Output + [1717790] info gdt and info idt scrolls away, too long result + [1726640] Debugger displays incorrect segment for mov instruction + [1719156] Typo in misc_mem.cpp + [1715270] Debugger broken in/beyond 2.3 + [1689107] v8086 mode priviledge check failed + [1704484] A few checks when CPU_LEVEL < 4 + [1678395] Problem with zero sector... + [876990] SA-RTL OS fails on PIC configuration + [1673582] save/restore didn't restore simulation correctly + [1586662] EDD int 13h bug, modify eax + [666618] POP_A Panic in DOS EMU + [1001485] panic: not enough bytes on stack + [1667336] delay times an order of magnitude slow + [1665601] crash disassembling bootcode + [1657065] CVS sources won't compile + [1653805] bochs's gdbstub uses incorrect protocol + [1640737] ASM sti command frezzes guest OS + [1636439] latest CVS sources don't compile under Cygwin + [1634357] disasm incorrect (no sign ext) displacement in 64-bit mode + [1376453] pcidev segfaults bochs + [1180890] IOAPIC in BOCHS - WinXP 64 in MP version + [1597528] 2.3 fails to compile on amd64 + [1526255] FLD1 broken when compaling with gcc 4.0.x + [1597451] eth_fbsd is broken under FreeBSD + [1571949] Bochs will not compile under Solaris + [1500216] Bochs fails to boot BeOs CD + [1458339] bochs-2.2.6 WinXP Binary ACPI error installing FreeBSD 6.0 + [1440011] patches needed for FreeBSD 6.0 to compile Bochs + [431674] some devices don't have a prefix + [458150] QNX demo disk crashes with new pit + [818322] Bochs 2.1 cvs: OS/2 - read verify on non disk + [906840] KBD: bogus scan codes generated in set 3 + [1005053] No keyboard codes translation + [1109374] Problem with Scancodeset 2 + [1572345] Bochs won't continue + [1568153] Bochs looks for (and loads?) unspecified display libraries + [1563462] Errors in /iodev/harddrv.h + [1562172] TLB_init() fails to initialize priv_check array if USE_TLB 0 + [1385303] debugger crashes after panic + [1438227] crc.cpp missing in bx_debug version 2.2.6 + [1501825] debugger crashes on to high input + [1420959] Memory leak + buffer overflow in Bochs debugger + [1553289] Error in Dis-assembler + [542464] I cannot use FLAT + [1548270] Bochs won't die with its pseudo terminal + [1545588] roundAndPackFloatx80 does not detect round up correctly + +------------------------------------------------------------------------- +Changes in 2.3 (August 27, 2006): + +Brief summary : +- limited save/restore support added (config + log options, hardware state) +- configuration parameter handling rewritten to a parameter tree +- lots of cpu and internal debugger fixes +- hard disk geometry autodetection now supported by most of the image types +- hard disk emulation now supports ATA-3 (multiple sector transfers) +- VBE memory size increased to 8MB and several VGA/VBE fixes +- updated LGPL'd VGABIOS to version 0.6a + +Detailed change log : + +- CPU and internal debugger fixes + - Fixed bug in FSTENV instruction (Stanislav Shwartsman) + - Recognize #XF exception (19) when SSE is enabled + - Fixed bug in PSRAW/PSRAD MMX and SSE instructions + - Save and restore RIP/RSP only for FAULT-type exceptions, not for traps + - Correctly decode, disassemble and execute multi-byte NOP '0F F1' opcode + - Raise A20 line after system reset (Stanislav Shwartsman) + - Implemented SMI and NMI delivery (APIC) and handling in CPU (Stanislav) + - Experimental implementation of System Management Mode (Stanislav) + - Added emulation of SSE3E instructions (Stanislav Shwarstman) + - Save and restore FPU opcode, FIP and FDP in FXSAVE/FRSTOR instructions + - Fixed bug in MOVD_EdVd opcode (always generated #UD exception) + - Fixed critical issue, Bochs was not supporting > 16 bit LDT.LIMIT values + - Many fixes in Bochs internal debugger and disassembler + +- CPU x86-64 fixes + - Fixed SYSRET instruction implementation + - Fixed bug in CALL/JMP far through 64-bit callgate in x86-64 mode + - Correctly decode, disassemble and execute 'XCHG R8, rAX' instruction + - Correctly decode and execute 'BSWAP R8-R15' instructions + - Fixed ENTER and LEAVE instructions in x86-64 mode (Stanislav) + - Fixed CR4 exception condition (No Name) + - Fixed x86 debugger to support x86-64 mode (Stanislav) + +- APIC and SMP + - Support for Dual Core and Intel(R) HyperThreading Technology. Now you + could choose amount of cores per processor and amount of HT threads per + core from .bochsrc for SMP simulation (Stanislav Shwartsman) + - Allow to control SMP quantum value through .bochsrc CPU + option parameter. Previous Bochs versions used hardcoded quantum=5 + value. + - Fixed interrupt priority bug in service_local_apic() + - Fixed again reading of APIC IRR/ISR/TMR registers. Finally it becomes + fully correct :-) + +- Configure and compile + - Moved configure time --enable-reset-on-triple-fault option to runtime, + the 'cpu' option in .bochsrc is extended and the old configure option + is deprecated (Stanislav Shwartsman) + - Removed --enable-pni configure option, to compile with PNI use + --enable-sse=3 instead (Stanislav Shwartsman) + - enable SEP (SYSENTER/SYSEXIT) support by default for Penitum II+ + processor emulation (i.e. if cpu-level >= 6 and MMX is enabled) + +- general + - Limited save/restore support added. The state of CPU, memory and all + devices can be saved now (state of harddisk images not handled yet). + - Fixed several memory leaks + +- configuration interface + - Configuration parameter handling rewritten to a parameter tree. This is + required for dynamic menus/dialogs, user-defined options and save/restore. + - Support for user-defined bochsrc options added + - help support at the parameter prompt in textconfig added + +- I/O devices (Volker) + - Floppy + - partial sector transfers fixed + - Hard drive / cdrom + - several fixes to the IDE register behaviour (e.g. in case of a channel + with only one drive connected) + - fixed data alignment of 'growing' hard drive images (sharing images + between Windows and Linux now possible) + - disk geometry autodetection now supported by most of the image types + (unsupported: external, dll and compressed modes) + - multi sector read/write commands implemented + - hard disk now reporting ATA-3 supported + - ATAPI 'inquiry' now returns a unique device name + - Keyboard + - reset sent to keyboard has no effect on the 8042 (scancode translation) + - PCI + - forward PIRQ register changes to the I/O APIC (if present) + - attempt to fix and update the emulation part of 'pcidev' (untested) + - VGA + - VBE memory size increased to 8MB and several VBE fixes + - VGA memory read access fixed (bit plane access and read mode) + - VGA memory is now a part of the common video memory + +- System BIOS (Volker) + - enable interrupts before executing INT 19h + - fixed ATA device detection in case of one drive only connected to controller + - improved INT 15h function AX=E820h + - real mode PCI BIOS now returns IRQ routing information (function 0Eh) + - keyboard LED flags handling fixed and improved + - fixed handling of extended keys in INT 09h + - Updated LGPL'd VGABIOS to version 0.6a + +- SF patches applied + [1340111] fixes and updates to usb support by Ben Lunt + [1539420] minor addition to pci_usb code by Ben Lunt + [1455958] call/jmp through call gate in 64-bit mode + [1433107] PATCH: fix compile with wxwindows 2.6 (unicode / utf8) by jwrdegoede + [1386671] Combined dual core and hyper-threading patch + +- these S.F. bugs were closed + [833927] TTD: System Error TNT.40025: Unexpected processor exception + [789230] Sending code that shows lock up when setting idt + [909670] Problems with Symantec Ghost + [1540241] include missing in osdep.cc + [1539373] Incorrect disasm for "mov moffset,bla" in 64bit + [1538419] incorrect disassembly of [rip+disp] with rex.b + [1535432] shift+cursor key maps to a digit + [1504891] Knoopix 5.0.1 error + [1424355] bochs-2.2.6 ata failure in windoze 98se + [1533979] wrong disassembly of IN instruction + [620059] paste won't stop + [1164904] status bar doesn't show num/caps/scroll lock status + [1061720] ATA Support level for HD + [1522196] Broken CHANGES link in main page + [1438415] crash if screen scrolled downwards + [778441] Shouldn't interrupts be enable after BIOS? + [1514949] I got a problem with the 8253 timer + [1513544] disasm of 0xec (in AL,DX) returns ilen of 2 instead of 1 + [1508947] APIC interrupt priority checking and interrupt delivery + [766286] Debugger halts after any GPF exception + [639143] va_list is not a pointer on linuxppc + [1501815] debugger examines memory over page-boundary wrong + [1503978] movsb/w/d doesn't work when direction is stored + [1499405] WinPCap has changed URL hosting + [1498519] APIC IRR bits not set while interrupts disabled + [1498193] Bochs segfaults on LTR instruction + [787140] Guest2HostTLB optimization bug + [1492070] instrument stop + [1487772] No SEP on P4 + [1488335] Growing hard disk images severe interoperability errors! + [1076312] Shadow RAM and TLB + [1282249] The real i440FX chipset Award bios hangs + [1479763] mistake "mov ax,[es:di]" for "mov ax,[ds:di]" + [1453575] Misconfigured floppy DMA transfers do not terminate. + [1460068] Incorrect handling for the Options Menu Item + [910203] bochs-2.1.1 wx.lo failed + [1438654] PANIC when trying to run install-amd64-minimal-2005.0.iso + [1458320] compile hdimage.h fails + [1455880] bochs-2.2.6,2: make error on FreeBSD + [696890] Network wouldn't run under W2k hosting MSDOS + [673391] SMP timer problems + [1291059] wxWindows GUI on non-windows/configure issue + [1356450] bochs 2.2.1 errors-omittions + [1178017] Win98 guest cannot receive network packets from host + [1076315] a20_mask after restarting + [1436323] real hw does not panic when bad Ib in CMPSS_VssWssIb + [1435269] cdrom_amigaos is not compilable + [1433314] disasm issues + [1170614] relative jumps/calls wrong in debugger + [758121] user might get confused when interrupt handler invoked + [1170622] You cannot toggle OFF "show" flags + [1406387] JMP instruction should display absolute address + [1428813] PANIC: ROM address space out of range + [1426288] DR-DOSs EMM386 problem + [1412036] Bochs cannot recognize PCI NIC correctly + [435115] dbg: modebp broken and no docs + [1419366] disasm cs:eip does not work anymore + [1419393] SSE's #XF exception -> "exception(19): bad vector" + [1419429] disassembly of "260f6f00" show DS: instead of ES: prefix + [1417583] Interrupt behaviour changed from 2.2.1 to 2.2.5 + [1418281] 'push' (6A) incorrectly disassembled + [1417791] FLDENV generating exception when real hw does not. + [1264583] OS/2 1.1 doesn't run + +------------------------------------------------------------------------- +Changes in 2.2.6 (January 29, 2006): + +- First major SMP release ! + - several APIC and I/O APIC fixes make SMP Bochs booting Windows NT4.0 + or Knoppix 4.0.2 without noapic kernel option in SMP configuration. + - critical APIC timer bug fixed + - obsolete SMP BIOS images removed (MP tables created dynamicaly) + - determine number of processors in SMP configuration through .bochsrc + new .bochsrc option 'CPU' allows to choose number of processors to emulate + - new configure option --enable-smp to configure Bochs for SMP support, + the old --enable-processors=N option is deprecated +- CPU and internal debugger fixes + - enabled #PCE bit in CR4 register, previosly setting of this bit + generated #GP(0) fault + - enabled LAHF/SAHF instructions in x86-64 mode + - fixed bug in PMULUDQ SSE2 instruction + - fixes in Bochs debugger +- Configure and compile + - enable VME (virtual 8086 mode extensions) by default if cpu-level >= 5 + - enable Bochs disassembler by default for all configurations + - win32 installer script improvements + - ips parameter moved to new 'CPU' option + - show IPS value in status bar if BX_SHOW_IPS is enabled +- Other + - several fixes in the hard drive, keyboard, timer, usb and vga code + - new user button shortcut "bksl" (backslash) + - updated Bochs instrumentation examples + - user and development documentation improved + +------------------------------------------------------------------------- +Changes in 2.2.5 (December 30, 2005): + +Brief summary : +- added virtual 8086 mode extensions (VME) implementation +- several fixes/improvements in x86-64 emulation, debugger and disassembler +- new serial mode 'socket' connects a network socket +- IDE busmaster DMA feature for harddisks and cdroms completed and enabled +- many improvements in Bochs emulated I/O devices (e.g. floppy, cdrom) +- Updated LGPL'd VGABIOS to version 0.5d + +Detailed change log : + +- CPU + - fixed XMM registers restore in FXRSTOR instruction (Andrej Palkovsky) + - print registers dump to the log if tripple fault occured + - fixed PANIC in LTR instruction (Stanislav) + - added virtual 8086 mode extensions (VME) implementation, to enable + configure with --enable-vme (Stanislav) + - flush caches and TLBs when executing WBINVD and INVD instructions + - do not modify segment limit and AR bytes when modifying segment + register in real mode (support for unreal mode) + - fixed init/reset values for LDTR and TR registers + - reimplemented hardware task switching mechanism (Stanislav) + - generate #GP(0) when fetching instruction cross segment boundary + +- CPU (x86-64) (Stanislav Shwartsman) + - implemented call_far/ret_far/jmp_far instructions in long mode + - fixed IRET operation in long mode + - fixed bug prevented setting of NXE/FFXSR bits in MSR.EFER register + - implemented RDTSCP instruction + - do not check CS.limit when prefetching instructions in long mode + - fixed masked write instructions (MASKMOVQ/MASKMOVDQU) in long mode + - fetchdecode fixes for x86-64 + +- APIC + - Fixed bug in changing local APIC id (Stanislav) + - Fixed reading of IRR/ISR/TMR registers (patch by wmrieker) + - Implemented spurious interrupt register (Stanislav, patch by wmrieker) + - Fixed interrupt delivery bug (anonymous #SF patch) + - Correctly implemented ESR APIC register (Stanislav) + +- Bochs debugger + - Fixed bug in bochs debugger caused breakpoints doesn't fire sometimes + (Alexander Krisak) + - watchpoints in device memory fixed (Nickolai Zeldovich) + - new debug interface to access Bochs CPU general purpose registers + with support for x86-64 + +- Disassembler (Stanislav Shwartsman) + - Fixed disassembly for FCOMI/FUCOMI instructions + - Full x86-64 support in disassembler. The disassembler module extended + to support x86-64 extensions. Still limited by Bochs debugger which + is not supporting x86-64 at all ;( + +- I/O devices (Volker) + - general + - memory management prepared for large BIOS images (up to 512k) + - slowdown timer sleep rate fixed (now using 1 msec on all platforms) + - some device specific parameter handlers moved into the device code + - serial + - new serial mode 'socket' connects a network socket (#SF patch by Andrew Backer) + - hard drive / cdrom + - assign a unique serial number to each drive (fixes harddrive detection + problems with Linux kernels 2.6.x: "ignoring undecoded slave") + - geometry autodetection for 'flat' hard disk images added. Works with + images created with bximage (heads = 16, sectors per track = 63) + - ATAPI command 'read cd' implemented, some other commands improved + - cdrom read block function now tries up to 3 times before giving up + - emulation of raw cdrom reads added, some other lowlevel cdrom fixes + - IDE busmaster DMA feature for harddisks and cdroms completed and enabled + - disk image size limit changed from 32 to 127 GB + - split ATA/ATAPI emulation code and image handling code + - floppy + - fixes for OS/2 (patch by Robin Kay) + - disk change line behaviour fixed (initial patch by Ben Lunt) + - end-of-track (EOT) condition handling implemented + - more accurate timing for read/write data and format track commands using + a motor speed of 300 RPM + - timing of recalibrate and seek commands now depends on the step rate, + date rate and the steps to do + - floppy controller type changed to 82077AA + - cmos + - RTC 12-hour and binary mode implemented + - number of CMOS registers changed from 64 to 128 + - bochsrc option 'cmosimage' improved + - save cmos image on exit if enabled + - speaker + - simple speaker support for OS X added (patch by brianonn@telus.net) + - pci + - BeOS boot failure fix in the PCI IDE code + - don't register i/o and memory regions during PCI probe + - vga + - memory allocation for vga extensions fixed + - usb + - some bugfixes by Ben Lunt (mouse and keypad are usable now) + - networking modules + - VDE networking module now enabled on Linux + +- display libraries + - general + - new syntax for the userbutton shortcut string and more keys supported + - win32 + - fixed keycode generation for right alt/ctrl/shift keys + - runtime dialog is now a property sheet + - x11 + - simple dialog boxes for the "ask" and "user shortcut" feature implemented + - Slovenian keymap added (contributed by Mitja Ursic) + +- configuration interface + - ask dialog is now enabled by default for win32, wx and x display libraries + - bochsrc option floppy_command_delay is obsolete now (floppy timing now based + on hardware specs) + - floppy image size detection now available in the whole config interface + - some device specific parameter handlers moved into the device code + - calculate BIOS ROM start address from image if not specified + +- System BIOS (Volker) + - PCI i/o and memory base address initialization added + - several keyboard interrupt handler fixes (e.g. patch by japheth) + - several floppy fixes (e.g. OS/2 works with patch by Robin Kay) + - some more APM functions added + - Updated LGPL'd VGABIOS to version 0.5d + - generate SMP specific tables dynamicly by the Bochs memory init code + +- SF patches applied + [1389776] Disk sizes over 64 Gbytes by Andrzej Zaborowski + [1359162] disasm support for x86-64 by Stanislav Shwartsman + [857235] task priority and other APIC bugs, etc by wmrieker + [1359011] build breaks for 386 + debugger + disasm by shirokuma + [1352761] Infinite loop when trying to debug a triple exception + [1311170] small APIC bug fix (interrupt sent to the wrong CPU) + [1309763] Watchpoints don't work in device memory by Nickolai Zeldovich + [1294930] change line status on floppy by Ben Lunt + [1282033] SSE FXRESTORE not working correctly by Ondrej Palkovsky + [816979] wget generalizations by Lyndon Nerenberg + [1214886] No more pageWriteStamp / unified icache by H. Johansson + [1107945] com->socket redirection support by Andrew Backer + +- these S.F. bugs were closed + [669180] win95 install : unknown SET FEATURES subcommand 0x03 + [1346692] bochs 2.2.1 VGA BIOS error + [1354963] floppy in KolibriOS + [1378204] error: bochs-2.2.1, --enable-sb16, --disable-gameport + [1368412] VDE problems in BOCHS + [533446] CPU and APIC devices appear twice + [1000796] bximage fails to create image of specified size + [1170793] Quarterdeck QEMM doesn't work + [923704] Multiple opcode prefixes don't reflect Trap 13 + [1166392] DocBook/documentation issues + [1368239] broken grater than 4GB size of sparse type hd image + [1365830] i386 compile breaks on paging + [427550] Incomplete IRETD implementation + [1215081] MSVC workspace STILL not fixed + [736279] Jump to Task + [1356488] FD change fail & occur error + [957615] [CPU ] prefetch: RIP > CS.limit + [1353866] not booting linux-2.6.14 + [1351667] load32bitOSImage does not work with --enable-x86-debugger + [1217476] Incorrect (?) handling of segment registers in real mode + [1184711] OS2 DOS crash [2.2.pre2] + [624330] support for disks > 32GiB + [1348368] bochs 2.2.1 bximage error + [1342081] Configuration Menu option failed + [1138616] OS/2 Warp 4 hangs when booting + [1049840] mouse and video conflict + [1164570] Unable to perform Fedora Core 4 test 1 installation + [1183201] Windows 2000 (MSDN build 2150?) does not completely install + [1194284] Can't boot from CD-ROM (Windows NT) + [962969] Windows NT crashes while trying to intall them. + [1054594] WinXP install halts (redo) + [1153107] Windows XP fails with BSOD on 'vga' + [938518] Win XP installation fails + [645420] getHostMemAddr vetoed direct read + [1179985] MS XENIX: >>PANIC<< VGABIOS panic at vgabios.c, line 0 + [1329600] WBINVD and INVD should flush caches and TLB + [638924] eliminate BX_USE_CONFIG_INTERFACE + [1048711] Funny behaviour with CTRL + [1288450] keyboard BIOS error + [1310706] Keyboard - about key SHIFT + [1295981] Ubuntu 5.04 Live-CD won't boot in Bochs + [879047] APIC timer behavior different before reset and after + [1188506] I still can't install the german Windows XP! + [1301847] Windows XP dosn't boot - FXRSTOR problem ? + [661259] does not boot QNX under WinX + [924412] Keyboard lock states all whacked + [681127] MIPSpro compiler (IRIX) is allergic to ^M + [1285923] BIOS keyboard handler + [516639] ATA controller revisited... + [657918] does not boot BeOS under WinX + [649245] BeOS CD locks halfway on boot + [1094385] Attachment for bug 1090339 (beos failure) + [1183196] BeOS 4.5 developer CD does not install + [1090339] BeOS fails to boot + [639484] panics when int 13 is called + [711701] divide by zero + [704295] ATAPI/BIOS call missing + [682856] hard drive problems + [627691] Cursor keys problem + [588011] keyboard not working + [542260] os/2 warp crashes with floppy handling + [1273878] SB16 doesn't work in pure DOS + [542254] OS/2 FDC driver dies + [1099610] Windows 98 SE Does not install + [875479] cr3 problem on task switch + [731423] NE2000 causing PANIC on Win2K detection + [1156155] bochs fails to boot plan9 iso + [1251979] --enable-cpu-level=3 should assume --without-fpu + [1257538] Interupt 15h 83h - set wait event interval + [658396] Panic for DR DOS emm386 + [679339] /? doesn't divulge Bochs command-line syntax + [1167016] call/jump/return_protected doesn't support x86-64 + [1252432] Mac OS X compile bug + [881442] Bochs 2.1 PANIC when loading DOS Turbo Pascal protected mode + [1249324] Boch2.2.1 Buffer Overfollow in void bx_local_apic_c::init () + [1197144] 'make install' has dependency on wget + [1079595] LTR:386TSS: loading tr.limit < 103 + [1244070] Compilation Error in gui/rfb.cc + [761707] CPU error when trying to start Privateer + [517281] Crash running Privateer in DOS... + +------------------------------------------------------------------------- +Changes in 2.2.1 (July 8, 2005): + +- Fixed several compilation warnings and errors for different platforms (Volker) +- Fixed FPU tag word restore in FXRSTOR instruction (Stanislav) +- Added missing scancodes for F11 and F12 to BIOS translation table (Volker) +- Bochs disassembler bugfixes (h.johansson) +- About 5% emulation speed improvement (h.johansson) +- Handle writing of zero to APIC timer initial count register (Stanislav) +- Enable Idle-Hack for 'TERM' GUI (h.johansson) +- Reduced overhead of BX_SHOW_IPS option to minimum. Now every simulation + could run with --enable-show-ips without significant performance + penalty. (Stanislav) +- Fixed pcipnic register access (Volker) +- Limited write support for TFTP server in 'vnet' networking module added (Volker) +- Changed some timing defaults to more useful values (Volker) +- WinXP/2003 style common controls now supported (Vitaly Vorobyov) +- Updated LGPL'd VGABIOS to version 0.5c (Volker) +- Added new BX_INSTR_HLT callback to instrumentation (Stanislav) + +------------------------------------------------------------------------- +Changes in 2.2 (May 28, 2005): + +Brief summary : +- New floating point emulator based on SoftFloat floating point + emulation library. +- improved x86-64 emulation +- Cirrus SVGA card emulation added +- status bar with indicators for keyboard, floppy, cdrom and disk (gui dependant) +- many improvements in Bochs emulated I/O devices (e.g. PCI subsystem) + +Detailed change log : + +- CPU + - fixes for booting OS/2 by Dmitri Froloff + - fixed v8086 priveleged instruction processing bug (was also reported + by LightCone Aug 7 2003) + - exception process bug (was reported by Diego Henriquez Sat Nov 15 + 01:16:51 CET 2003) + - segment validation with IRET instruction + - CS segment not present exception processing with IRET + - several fixes by Kevin Lawton + - add MSVC host asm instructions (patch by suzu) + - fixed bug in HADDPD/HSUBPD (SSE3) instructions + - fixed bug in float to integer SSE/SSE2 convert instructions + - fixed BCD instructions implementation + - execution speed improvements (sshwarts and psychosmur) + - fix MSR_APICBASE base address (Kangmo Kim, Christian Neubert) + - change BX_PANIC messages to BX_INFO when behaviour exactly + matches Intel docs + - EIP > CS.limit case should always cause #GP(0), even in real mode. + Fixed all jump, call and ret instructions for 16/32 modes + - fixed using invalid segment register for MOV instruction (h.johansson) + - fixed ET bit mismatch between CR0 and SMSW instruction + - fixed possible simulator #DIVZERO fault when executing IDIV instruction + - fixed undocumented flags handling for BTS, BTR, SHR, SHLD, MUL and IMUL + instructions (Stanislav Shwartsman) + - added missed #GP(0) exception when loading incorrect flags combination + to CR0 (Stanislav Shwartsman) + - in case of --enable-ignore-bad-msr enabled read ignored MSRs as zero + - enabled #DE, #TSD and #MCE bits in CR4 register, previosly setting + of one of these bits generated #GP(0) (Stanislav, Volker Ruppert) + - exceeding the instruction length limit of 15 bytes (this only can + occur when redundant prefixes are placed before an instruction) + generate #GP(0) (Stanislav Shwartsman) + - corrected PAE functionality + +- CPU (x86-64) + - fetchdecode fixes for x86-64 and 3DNow! (Stanislav) + - fixed CF flag handling for SHL instruction in x86-64 mode (Stanislav) + - implemented CR8 register (aliased to APIC.TPR[7:4]) (Stanislav) + - implemented NXE bit (No-Execute page protection) support (Stanislav) + - STOSQ instruction emulation fixed (Avi Kivity) + - allow null SS selector for MOV SS, POP SS, and LSS instructions + in long mode (Avi Kivity) + - ignore segment bases for all segments (except FS and GS) in long + mode (Avi Kivity) + - allow SYSENTER/SYSEXIT instructions together with x86-64 (Stanislav) + - canonical address checking for RIP (Stanislav) + +- FPU (Stanislav Shwartsman) + - totally rewritten all FPU code based on softfloat library + - significantly improved accuracy of all floating point + instructions. + - implemented all missed P6 and PNI floating point instructions. + - hundreds of bug fixes in FPU code. + + TODO: + ! Unmasked underflow/overflow should correct the result + by magic number for all operations, including float32 + and float64. + +- APIC (Zwane Mwaikambo) + - APIC arbitration + - Processor priority + - Various interrupt delivery fixes + - Focus processor checking + - ExtINT delivery + +- Disassembler + - fixed MOV opcode 0x88, had exchanged the operands (h.johansson) + - fixed MOV opcode 0xA3, had wrong operand size (h.johansson) + - fixed BOUND opcode 0x62 (Stanislav) + - fixed CALLW opcode 0xFF /3 and JMPW opcode 0xFF /5 (Stanislav) + - fixed INS opcode 0x6D, had wrong operand size (Stanislav) + - fixed disassembly for repeatable instructions (Stanislav) + - fixed sign-extended immediate opcodes (Stanislav) + - fixed MOVSS/MOVSD instructions opcode names (Stanislav) + - fixed NEG instruction opcode name (Stanislav) + - fixed CMPXCHG8B instruction, had wrong operand size (Stanislav) + - fixed floating point instructions operands (Stanislav) + - experimental support of AT&T syntax in disassembler (Stanislav) + +- I/O devices + - general + - handle cpu reset through port 0x92 + - new memory handler API for PCI i/o and memory handling (Frank Cornelis) + - speaker emulation for Linux (David N. Welton) and Win32 (Volker Ruppert) added + - pci + - PCI slot configuration added for 5 slots (Volker) + - PCI irq routing, irq sharing and level sensitive irq mode implemented + - ne2k device appears as a Realtec 8029 NIC if connected to a PCI slot + - PCI IDE controller dummy device added + - PCI host device mapping for Linux (Frank Cornelis) + - PCI Pseudo-NIC emulation (Michael Brown) + - serial + - multiple serial port support added (4 ports now available) + - partial raw serial support on win32 (transmit data) + - serial port i/o mode option added (modes: null, file, term, raw, mouse) + - parallel + - multiple parallel port support added (2 ports now available) + - mouse + - serial mouse support (Volker) + - PS/2 and serial wheel mouse support (Ben Lunt) + - usb + - USB mouse and keypad support (Ben Lunt) + - config option to specify devices connected to USB ports + - vga + - VBE 8 bit DAC support added + - VBE memory now registered using DEV_register_memory_handlers() + - CL-GD 54xx SVGA emulation added (Makoto Suzuki) + - vga extension option added (choices: vbe, cirrus, none) (Volker) + - floppy + - raw floppy access now works on Win9x host (Ben Lunt) + - sb16 + - MacOSX sound support (Brian Huffman) + - networking modules + - new: 'eth_vnet' simulates ARP, DHCP, ICMP-echo and read-only TFTP + (m_suzu, easeway) + - new: 'eth_vde' for Virtual Distributed Ethernet (Renzo Davoli) + +- System BIOS + - turn floppy motor off 2 seconds after last read/write/recalibrate command + (Ben Lunt) + - int13_cdrom / 32 bit register update fixes for FreeBSD cdrom boot + (Fabrice Bellard) + - APM and system shutdown support (Fabrice Bellard) + - checksum calculation for expansion ROMs + - extended floppy parameter table (Mike Nordell, Derek Favcus) + - PCI IRQ initialisation added + - boot sequence with up to 3 boot devices added + +- display libraries + - status bar with indicators for cdrom, floppy, harddisk and keyboard added + (done in rfb, sdl, win32, wx and x) + - 3rd (middle) mouse button now supported (rfb, sdl, win32, wx, x) + - mouse wheel support (sdl, win32, x) + - CTRL key + middle mouse button now used to toggle the mouse capture mode + (sdl, win32, wx, x) + - text mode split screen feature added (sdl, win32, wx, x) + - new gui function returns the display library capabilities (xres, yres, bpp) + for the Bochs VBE support + - display library specific options added - currently supported: + rfb: timeout (time to wait for client connection) + sdl: fullscreen (startup in fullscreen mode) + win32: legacyF12 (use F12 to toggle mouse) + - new graphics update API added (used by svga_cirrus) (Robin Kay) + +- configuration interface + - win32: gui runtime dialogs replace textconfig runtime dialogs + - set default IPS to 10000000 in .bochsrc sample + - SB16 options dmatimer and loglevel now available at runtime + +- configure script / compile + - --enable-ignore-bad-msr (ignore bad MSR references) option is enabled + by default + - --enable-mmx enabled by default only if cpu-level >= 5 + - --enable-4meg-pages will be enabled by default if cpu-level >= 5 + - fixes for Solaris SunPro (Robin Kay) + - --enable-pni option added + - --enable-show-ips option added, enable Instruction Per Second counter + in log file + - autodetection for lowlevel sound support added + +- documentation + - a bunch of updates in user and documentation docs (Alexander Schuch) + +- SF patches applied + [894595] MSR_APICBASE always returns APIC ADDRESS 0 by Kangmo Kim + [907163] ctrl_xfer8 clean/speed up + [907161] clean/speed up of io.cc + [899972] data xfer performance patch V 2.0.4 + [904549] imul gives incorrect result in long mode + [877510] amd64 fixes... + [903465] SEGV in iodev/ne2k.cc line 1211 on Alpha architecture by Christian Lestrade + [903332] copy the bximage result to clipboard, etc by Lukewarm + [950905] Do not PANIC on rare, bad input from user-mode by h.johansson + [924428] ET bit mismatch between CR0 and MSW + [869822] a real SVGA implementation by m_suzu + [867045] fix for compiler errors on VC++ by m_suzu + [838601] support for the over 2GB disk size with MSVC++ + [874816] local ARP/ping/DHCP simulator by m_suzu + [976066] Keyboard: Get controller version by Ben Lunt + [832330] ROMBIOS improvement (reduce stack consumption, etc.) + [977900] READ_CDROM_TOC and base address by Ben Lunt + [961665] WinXP patch to read physical CDROM's TOC by Ben Lunt + [978793] CDROM_SENSE_MODE medium_type by Ben Lunt + [615457] gif to png migration + [1021767] Portability in sb16ctrl.c by Robert Millan + [690400] gzip is confused by GZIP variable in Makefile + [567595] guess floppy image size from image file length by Tal Benavidor + [888426] bochsrc to make vnet useful by m_suzu + [1021758] GNU/k*BSD host support by Robert Millan + [969967] int 15/ah=87h clearing cr0 by Ben Lunt + [1048327] Russian Keymap by Dmitry Soshnikov + [851332] DESTDIR support for install_dlx by Ville Skytt + [970929] gdbstub support for MinGW tool chains by Muranaka Masaki + [1021740] Turn gdb stub into a runtime option by Charles Duffy + [1063329] RFB key press/release bug fix by Remko van der Vossen + [1079240] Wheel Mouse by Ben Lunt + [1087537] Fix for Win9x CD boot by lukewarm + [1083218] Start of wheel for USB #2 by Ben Lunt + [1098480] bochsrc: fixed floppya example by Alexander Schuch (ci-dev) + [1094407] configure.in: changed wxWindows to wxWidgets by Alexander Schuch + [1092058] serial.cc debug output cleanup by Ben Lunt + [1101165] APIC base address by Christian Neubert (flashburn) + [1093796] Fix for bug #1093786 (Nigel Horne) + [1082584] The start of Bus mice and USB mice by Ben Lunt + [1104695] msvc6 compatibility update (Royce Mitchell III) + [1059199] VGA text font bug fix (Anonymous) + [1108001] Null pointer on bx_atexit() (Ben Lunt) + [1112093] Fixed mouse cursor remain area drawing (Anonymous) + [1114826] Fix PCIBIOS (Destruction prevention of esi and edi) + [1095473] Reading from a CDRW (Fixed) by Ben Lunt + [1123895] x86-64 gdb/debugger fixes by Avi Kivity + [1145423] stosq simulation bugfix by Avi Kivity + [1151012] allow null ss on x86-64 by Avi Kivity + [1153327] ignore segment bases in x86-64 by Avi Kivity + [1153511] Fixed broken screen update (VBE) + [1152808] use 'install' instead of 'cp' during installation by Avi Kivity + [1159626] bugfix [1156776] keyboard scanmode fault by Rene Kootstra + [843328] PATCH: support for Flat-style ToolBar with Win32GUI + [1198308] PATCH: fix incorrect moving mouse cursor when wheel used + [1200515] add TFTP server to vnet & ipv4 bug fix by easeway + [1203305] tuntap incompatibility by Jan Kratochvil + +- SF patches partially applied + [896733] Lazy flags, for more instructions, only 1 src op + [1005422] Improve mouse cursol Grub when 2 buttons-mouse use (WIN32) + (TODO: improved japanese keyboard support) + +- patches applied + - patch.rombios.markevich (Start/Stop Wait Timer) (Kory Markevich) + - patch.apic-zwane (APIC fixes) (Zwane Mwaikambo) + - patch.v8086-exception.lightcone (LightCone) + +- these S.F. bugs were closed + #957660 >>PANIC<< APIC: R(curr timer count): delta < initial + #1192654 60 x 90 text not quite right... + #1189097 "configure --with-sdl --with-rfb" doesn't compile + #1188980 Crash on XP when break into debugger + #1186693 Improving quality of ./configure --help + #1185245 Errors Making Bochs with Mingw32 + #1185289 PSE is not enabled by default on Pentium + #1170620 info cpu scrolls away, is too long + #1157998 ips shown even when waiting for input + #663108 APIC Timer Bug + #831750 bochs unlike real PC in paging + #1182698 PAE support doesn't work + #954400 debugger causes segfaults when gcc 3.4.0 is used + #1171312 Possible SMP problem with ICACHE pageWriteStamp + #1179964 PANIC: RIP>CS.limit when jumping to longmode + #1171067 configure fails to add -lpthread + #1171065 Term UI needs -lncurses + #1171061 SDL GUI startup failure + #1022056 win32 error build debug version..c2146 + #957190 error while attempting to compile sb16.cc + #804797 Debugger: visualization problem (jmp) + #675523 2.0.1 doesn't run on W2K? + #1167358 When using 5430PCI in DR-DOS Bochs would panic with a PUSHAD + #1164654 Bochs VBE bios causing exception 0B in Windows 95 (SVGA bios) + #1162983 conflicts which configure could detect + #1164536 Windows 95 B crashes during install + #526978 cygwin: in an rxvt, stdout is flaky + #542303 >>PANIC<< call_protected: CS selector null + #859457 BRICKS game doesn't work + #1159639 text modes on address A0000-BFFFF are not handled properly + #1164225 define BX_SUPPORT_X86_64 0 + #1163720 ROL bug + #1156776 keyboard scanmode fault + #1162042 Duke Nukem 3D: >>PANIC<< iret: VM set on stack, CPL!=0 + #1161945 ctrl_xfer32 compile/make error + #1157124 Bochs doesn't run with large amounts of memory in bochsrc + #1154266 weird INT handling in V86 mode + #1157051 default Bochs CVS doesn't work-out-of-the-box + #923954 enter() with level > 0, >>PANIC<< iret: return CS selector + #1098476 Privilege Problem after SYSEXIT + #1121734 Bochs crashes when shutting down Win95 + #1099294 VESA for Win98 bogus + #1112836 PGE-Bit crashes Bochs + #947586 The specification difference in x86-64 emulation + #1117145 Push reset Button, APIC0 Error occur + #1123043 fpu stack pointer changed *despite* fault occured (e.g. #pf) + #1122066 PANIC: iret: IP > descriptor limit when installing os/2 warp + #809574 rm -f segfaults + #593952 SuSE rm segfaults + #929783 floppy not recogniced since 2.1 + #1099298 SB16 for Win98 Bogus + #1079483 Reading from a CDRW + #549793 flaw in interrupt gate handling(exception.cc) + #692055 SMP Error + #805479 Booting from disk causes illegal instruction warnings + #909677 pc-speaker doesn't work + #831751 behaviour unrealistic + #661213 CR4.TSD is broken + #685508 PANIC: prefetch: RIP > CS.limit + #1037923 Non-executable page support missed (NX bit, x86-64) + #1106530 wrong disassemble result + #1105208 drive order for boot gets saved wrong + #661060 Problem with Win98SE + #837377 Norton Ghost don't boot + #876689 Unknown register 0x17 [CPU] / WIN98SE + #947282 Bochs segfault + #963317 Persistent Win98SE + #1101168 APIC base address change + #680737 panic when installing winme + #1097187 Install FC3 on bochs-win failed + #875461 vgabios-lgpl should be default + #594797 Bochs segfaults + #602994 bochs breaks boot kernel + #571539 FreeBSD Install from CD Fails + #774257 Device doesn't work under W98 + #759228 Installing Suse 8.2 in Bochs on WinME + #792561 cant boot freebsd 5.1 from cdrom + #804004 Live cd will halt on boot.. + #956173 FreeBSD won't boot iso install images in Bochs v2.1 or 2.2. + #864401 >>PANIC<< jmp_ev: IP out of CS limits! + #853831 Error on int 15h + #1094150 DR-DOS 7.03: panics when using multitasker + #655592 win98 hardwaredetection + #1093786 Solaris 9 installation CD fails + #959585 USB UHCI IO-Device + #963314 Redhat Fedora Installer Kernel Panic and Crash + #1086920 Bochs (cvs) doesn't compile on FreeBSD 5 + #879050 Bochs reports enabled APIC without support + #1071199 dBaseII cause prefetch: RIP > CS limit + #1070812 typecast error while compiling wx.cc + #1068786 FSINCOS Cos value wrong at 90 degrees + #675248 Panic: EIP > limit on win98 install + #829793 [CPU ] prefetch: RIP > CS.limit + #1034059 >>PANIC<< prefetch: running in bogus memory + #1067813 pbm fpu_proto.h:144 ebuild gentoo bochs 2.1.1 + #922034 bios not aliased at 0xFFFFF000, registers wrong after reset + #912666 Configure fails on Yellow Dog Linux 3.0.1 + #922038 Unexisting memory should read back as 0xFFFFFFFF + #1019723 HD image + #1057814 Shadow RAM not aligned + #1057240 Invalid IRET32 implementation + #809682 >> PANIC << : prefetch: RIP > CS.limit + #618680 memory referencing problems + #724262 A few things (Windows 2.03, Wolfenstein) + #985375 Crash Mandrake 7.1 + #913418 compiler errors with --enable-external-debugger option + #708847 CR8 access should not panic X86-64 + #1039499 Compile error pcipnic.cc (cygwin) + #978024 compile against wxGTK-2.5.2 fails + #639073 MacOSX: Networking not implemented + #639074 MacOSX: Soundblaster not implemented + #963264 Latest CVS --enable-pcidev fails to configue on YDL Linux + #586282 Mac OS X, will not "make" + #699532 CVS (as of 2003/03/07) cannot read disk images + #639275 wrong more than 2GB size DVD-ROM + #766020 info registers / dump_cpu get old eflags + #655920 QuickBasic (qbx.exe) panics + #676188 Error BX_MAX_DIRTY_PAGE_TABLE_MEGS + #923821 LOCK not generating exceptions properly + #1007747 Wrong configure? + #1022577 show "call" command crashes bochs every time + #681849 SuSE 8.1 Compile problem + #660322 Install bochs 2.0 on SuSe 8,0 + #1022587 "Unrecognized args" message wrong after invalid show command + #833118 TUN/TAP interface bug + #1022178 tuntap module mangles incoming broadcast packets + #1028682 Report incorrect disk parameters of floppy + #1026234 make fails on Cygwin because of missing .exe extension + #1026241 --enable-cpp needed for .conf.win32-cygwin + #855323 BIOS Panic at rombios.c, line 1563 + #762773 ROM checksum is not checked in rom_scan_loop + #657604 concat_image_t.lseek to byte -1378816 fa + #800140 No AH=83h INT15h implemented + #831965 Win32.zip BIOSes in wrong directory + #873280 bximage crashes after createing "growing" + #892223 bochsrc-sample.txt/vgaromimage option error + #1014361 Bximage on WinXP won't create image + #651510 bximage won't create larger than 2GB + #759206 bximage fails on Win32 for hd images over 2Gb + #759210 Bochs fails on image files over 2Gb on Win32 + #799785 bximage doesn't work + #903345 Problem compiling harddrv.cc + #933303 Bochs cannot lseek() HD images > 2GB on W32 platforms + #888438 bximage crashes...(hacked fix included) + #871720 bximage 2GB file size limit + #930368 Can't create big hard drives (>2 GB) + #912496 IDIV can cause simulator divide error + #522111 Host os SIGILL, booting grub from hd + #1005052 DMA Controller Model Problem + #552939 Bochs window doesn't resize when win311 + #989478 I-Cache and undefined Instructions + #661008 make install fails + #845691 Workaround: Ne2k and Windows 2000 not working + #923662 BIOS diskette motor countdown byte broken + #848141 VGA problems running Scitech Display Driver on Win95 + #799370 Problem booting ReactOS 0.1.3 + #670143 No rule to make config.h + #653444 with vbe/lgpl bios, scrn updates broken + #655696 quickstart broken? + #659350 FDC + #620853 Ne2000 ethernet card *NOT* supported + #607611 Numlock + #543476 Sound card does not work in Windows 95 + #529554 unsupported VBE features DISPI update + #487316 Access violation on Win32 + #576253 RTC too fast + #489748 io read from address 000003c0, len=2 + #656861 Gentoo Linux panics in VGA code + #787184 Video BIOS's don't checksum correctly + #988529 textconfig [Save options to] function output obsolete option + #987293 Cannot accesss header/toolbar + #988246 floppy read error + #933199 speedup Bochs compilation 4x -> suggestion + #979106 Incorrect disassembly table entry + #658374 FPU incorrect emulation + #706933 Problem with the F12-Key + #477043 math_abort panic in RH 7.1 + #634371 Floating point problems + #681138 // is not valid in C + #643300 cpuid feature flag 15, cmov and fcmov + #913697 missing division by 0 exeption in fpu emuation + #923682 FSTENV/FINIT problems + #923855 FPTAN doesn't work right with full NPX stack + #924379 ET bit mismatch between CR0 and MSW + #716116 Direct floppy access + #962919 Mac: iodev/cdrom.cc disordered + #954751 Two FPU.CPP in project + #954359 Compile faile is 3dnow support is selected without SSE support + #906412 FreeSCO error + #942060 FDC Controller not conforming to specifications + #938522 Win XP installation fails + #923613 BOUND instruction exception handling is broken + #923223 memtest86 errors + #593342 autoconf script doesn't regenerate clean + #616116 Crash on exit... + #922042 shutdown through port 92 does not work + #891633 02839990390p[CPU0 ] >>PANIC<< RDMSR: Unknown register 0x17 + #923653 DAA instruction is broken + #911225 obscure AAA / AAS bugs + #837206 Problems with numerical keys + #658765 BOCHS halts in runtime config + #890734 Bochsrc Parser Bug with commas included in strings + #877285 MSR_APICBASE zero upon startup + #526984 SDL compiled in cygwin just quits + #886406 I/O permissions bug + #883239 undefined symbols in gui/siminterface.h:1215 + #419647 on OSF1, cxx hates C++ inlines + #809790 "No rule to make target `devices.cc?..." + #873654 How compile without plug-in support ? + #837161 Test case for BX_CPU_C::IRET32 + #888116 mmx.cc compile error + +------------------------------------------------------------------------- +Changes in 2.1.1 (February 8, 2004): + +- fix bug in int15h function 0xe820 (Christian Neubert) +- fix vmware3 disk support on big-endian platforms (Christophe Bothamy) +- fix conditions for NM exception on FWAIT instruction (Christophe) +- fix symbol conflict in rfb and x display libraries (Volker Ruppert) +- allow 16 bit writes to ne2k page 0 (Kenneth Stailey) +- notify display libraries on change of bpp (Volker) +- fix bug in int13h function 0x10 (Volker) +- fix floppy dialog error on win2k (Volker) +- fix adress check in TSS IO permission bitmap (Christophe) +- fix buffer overflow vulnerability pointed out by SeSoX (Christophe) +- updates for MacOS compile (Daniel Gimpelevich) + +------------------------------------------------------------------------- +Changes in 2.1 (January 9, 2004): + +Brief summary : +- New disassembler +- 3DNow!/SSE/SSE2/PNI instruction support +- Vmware3/Sparse/Undoable/Growing harddisk images support +- many VGA emulation improvements (e.g. high/true color VBE modes added) +- No more X11 vga font required + +Detailed change log : + +- CPU + - added emulation of AMD 3DNow! instructions set. (Stanislav Shwartsman) + Bochs now could decode all AMD 3DNow! instructions. + Most of instructions still not implemented, but the basis already presents. + Configure --enable-3dnow to enable 3DNow! support. + Notes : + - These instructions are not implemented yet: + PFPNACC_PqQq, PF2IW_PqQq, PFNACC_PqQq, PFCMPGE_PqQq, PFMIN_PqQq, + PFRCP_PqQq, PFRSQRT_PqQq, PFSUB_PqQq, PFADD_PqQq, PFCMPGT_PqQq, + PFMAX_PqQq, PFRCPIT1_PqQq, PFRSQIT1_PqQq, PFSUBR_PqQq, PFACC_PqQq, + PFCMPEQ_PqQq, PFMUL_PqQq, PFRCPIT2_PqQq + - CPUID does not report 3DNow! instruction set. + - added emulation of SSE/SSE2 floating point instructions. (Stanislav) + All SSE/SSE2 floating point instructions are fully implemented using + free softfloat library (including DAZ support and floating point + exceptions). Correctness of the emulation checked with heavily random + testing. + - added emulation of SSE3 (PNI) instructions (Stanislav) + Currently only 3 PNI opcodes still not implemented: + FISTTP m16int, FISTTP m32int, FISTTP m64int + - added P4 CPU support to CPUID instruction. (Stanislav) + - fixed implementation of FXSAVE/FXRSTOR instructions. (Stanislav) + - bugfix: unallowed lock prefix cases must cause #UD exception. (Stanislav) + - fixed fetchdecode bug caused #UD in SYSENTER/SYSEXIT instructions + in 32bit mode. (Stanislav) + - fixed fetchdecode64 bug caused wrong decoding of opcodes containing + BxImmediate_IvIw or BxImmediate_IwIb in x86-64. (Stanislav) + - fixed bug in int01 (opcode 0xF1) emulation. (Vitaly Vorobyov) + - fixed bug in x86 debugger with dr0-dr3 registers (Vitaly) + - fixed bug with mov to/from dr register in v86mode. + (now exception is generated (according to Intel documentation) + instead of panic) (Vitaly) + - fixed stack limit checking, now message is generated as BX_DEBUG, + rather then BX_PANIC, and exception code is executed. (Vitaly) + - instrumentation code updated. (Stanislav) + - fix flaw in IO bitmap permission of TSS (Christophe Bothamy) + - cpu resets on triple fault (Christophe) + - remove calculation on cr3 in dtranslate_linear to increase + emulation speed (Conn Clark) + - numerous x86-64 fixes (Peter Tattam) + +- FPU + - hundreds of bugfixes in FPU emulation after checking of the emulation + with testfloat (Scott Duplichan). + - Fixed cases: + - floatx80_to_int32, floatx80_to_float32 + - floatx80_to_float64, floatx80_round_to_int + - floatx80_add, floatx80_sub, + - floatx80_mul, floatx80_div + - implemented FCMOVcc instructions (Stanislav) + - 64-bit addressing support for x86-64 mode (Peter) + +- Disassembler + - replaced Bochs disassember. New table-based disassembler fully supports + all IA-32 instruction sets including all FPU/MMX/SSE/SSE2/SSE3 opcodes. + (Stanislav) + +- I/O devices + - general + - i/o access mask implemented, unallowed cases are now handled in the devices + code and cause a BX_ERROR (Volker Ruppert) + - include slowdown timer as a runtime option (Christophe) + - netBSD : fix serial, ethernet, cdrom (fredb, uebayasi and David Laight) + - VGA + - color depth 15, 16, 24 and 32 bpp supported by VBE (Volker and + Christopher Nelson for 32 bpp on win32). Supported by sdl, x, win32 and wx. + - SVGA mode 0x6A (800x600x4bpp) implemented (Volker) + - new CGA graphics modes 640x200x1bpp and 160x100x4bpp (text mode 80x100) (Volker) + - raster operations AND, OR and XOR in write mode 2 (based on SF patch #707931) (Volker) + - 'split screen' in standard VGA graphics mode implemented (Volker) + - 'double scan' and 'double width' now handled in the VGA code (Volker) + - more accurate emulation of the horizontal and vertical retrace (Volker) + - changeable start address and variable line length supported by all + graphics modes (Volker) + - VBE: preserve video memory feature implemented (Volker) + - additional text mode features prepared (handled in the display library + code) (Volker) + - PCI + - add experimental PCI VGA card (Mike Nordell) + - add experimental PCI USB card (Ben Lunt) + - Harddisks + - per device selectable harddisk modes : + - undoable, volatile, growing disks support (Christophe) + - sparse disks support (justinSB) + - vmware3 disks support (Sharvil Nanavati) + - fix non detection of hard drives by minix2 (Christophe) + - implement atapi command 0xA8 read (12) (Christophe) + - mode sense command updated (Hartmut Birr) + - sb16 + - opl2 support enhanced (James E. Flemer) + - ne2k + - tap support for FreeBSD (Ronald Klop and Gen Otsuji) + - fix when booting with grub (Keir Fraser) + - cmos + - date/time change support added (Volker) + - UIP bit and divider chain reset implemented (Volker) + - initial time can now be set to local time or utc (Christophe, Daniel Gimpelevich) + - keyboard + - keyboard reset function (0xff) now resets the keyboard (Volker) + - gameport + - new standard PC gameport device (real joystick connected on Linux and + win32 only). Enable it with --enable-gameport or the SB16 emulation (Volker) + - serial + - FIFO emulation (UART type 16550A) implemented (Volker) + - floppies + - 160k,180k,320k floppies support (Ben Lunt) + +- display libraries + - X11 + - onboard vgacard charmap usage (no need for external X11 vga font any more) (Christophe) + - vgacard charmap change support (Christophe) + - fix black stripes on partial exposes (Dirk Thierbach) + - headerbar redraw optimizations (Dirk Thierbach) + - external font files and their installation mechanism removed (Volker) + - belgian keymap support (Wouter Verhelst, Eric Brasseur) + - win32 + wx + x: new application/window icon (bochs.ico / icon_bochs.xpm) (Volker) + - sdl + win32 + wx + x: new textmode features: variable line length, + char width switch, horizontal and vertical pel panning (Volker) + - win32 + wxMSW: key event handling rewritten (Volker) + - win32: status bar at the bottom of the simulation window added (Volker) + - wxMSW: resource problems fixed - wx dll plugin works now without errors (Volker) + - term: variable line length and cursor enable/disable feature implemented (Volker) + - rfb + - textmode: charmap change, better cursor emulation, variable line length (Volker) + - headerbar works now (power, reset and user button are okay) (Volker) + - key event handling rewritten (Volker) + - Bochs-RFB waits up to 30 seconds for a client connection. The emulation + starts after connecting the client. (Volker) + - carbon: Alt/Ctrl/Shift key handling rewritten & SysRq/Ctrl-Break key support added + (Daniel) + +- configuration interface + - gui dialogs as an extension of the textconfig interface on win32 added (Volker) + * ask dialog + * save text snapshot + * user button shortcut + * floppy image change + - wxwindows configuration dialogs improved (Volker, Christophe) + +- support tools + - bximage : added support for + - growing disks (Christophe) + - sparse disks (justinSB) + - created bxcommit tool for undoable disk images (Christophe) + +- System BIOS : + - fixed int15 function e801 (get memory size) (Christophe) + - added int75_handler for FPU Dos Exceptions (Christophe) + - added int16 function 0a (Get Keyboard ID) (Volker) + - added support for ElTorito Harddisk-on-CD emulation (Christophe) + - fixed ATA/Serial ioport conflict (Daniel) + +- VGA BIOS : updated to version 0.4c (Christophe) + +- configure script/compile/porting to other OSes/installation + - fixes for compilation with MSVC (Andrew Zabolotny) + - fixes for cross-compilation (Jeroen Janssen) + - win32 nsis installer script updates (Volker) + - small configure fixes for MacOS (Christophe) + - optimizations & compile fixes for MacOS/X (Daniel) + +- configuration files. The following options have been deprecated : + diskc, diskd, cdromd, time0, pit, newharddrivesupport. + +- documentation + - already ported and obsolete parts of the old documentation removed (Volker) + - user documentation updated and extended : + - improved section "What does Bochs need" (Volker) + - command line arguments (Volker) + - search order for the configuration file (Volker) + - the configuration interface 'textconfig' (Volker) + - FreeDOS Beta 8 installation instructions (Volker) + - disk modes (Christophe) + - LBA translation (Christophe) + - cdboot error codes (Christophe) + - SCO OpenServer install section (Carl Sopchak) + - MacOS-X DMG install guide (Aard Vark) + - update Win98 install guide (Dirk Thierbach) + +- SF patches applied + #658950 Bug in FPU (Anonymous) + #678117 build fail due to bad SGML punctuation (Anonymous) + #671873 minimal USB support (UHCI) (Ben Lunt) + #682539 Fix CapsLock and NumLock behavior (rock at gimp.org) + #720776 REX MOVB immediate broken for x86_64 (Arnd Bergmann) + #729450 new keymap x11-pc-be.map (Wouter Verhelst) + #735990 Limited patches for VC++ (Anonymous) + #742670 fix library dependencies in GUI plugins (Robert Millan) + #742782 LFB bugfix (Jan L. Hauffa) + #748414 load32bitOShack bug (kyriazis at nvidia.com) + #830079 Fix bochs's application error if unsupported key pressed (Anonymous) + #724466 enable building with CC=gcc-3.2 CXX=g++-3.2; dist-clean adds(Leonard Norrgard) + #834962 Fixed drawing graphics is broken (Anonymous) + #838401 Fixed redrawing of ToolBar on Win32GUI (Anonymous) + #850236 Fixed accessing DVD-ROM with direct device access on Win32 (Anonymous) + #847822 Bochs crash when exmining memory that crosses page boundary (ortal at jungo.com) + +- SF patches partially applied + #707931 Support EGA/VGA write mode 2 and others (Anonymous) + already applied: disable IME, split screen, write mode 2, + BIOS INT16h/AH=05h + #856506/#856510 Patch to fix compile-time iodev/cd-rom.cc error (alden.dima at nist.gov) + Correct patch provided in SF bug report #843433 (birkhofer at users.sourceforge.net) + +- patches applied + - patch.highmem (memory allocation) (Zwane Mwaikambo) + - patch.floppy-160k-180k-320k-benlunt (exotic floppies) (Ben Lunt) + - patch.perf-regparm-cclark (performance) (Conn Clark) + +- new patches present in the patches directory : + patch.pipelined-asm-cclark + patch.mingw-resources + patch.v8086-exception.lightcone + patch.pit-vitaly-vorobyov + patch.rombios-vitaly-vorobyov + patch.win32-vitaly-vorobyov + patch.win32-new-files-vitaly-vorobyov.tgz + patch.rombios.markevich + patch.rombios.dirk.thierbach + +- these S.F. bugs were closed + #865354 ">>PANIC<< CRA: divider chain control 0x07" in Linux 1.1 + #725796 configure script bug + #859768 cpuid + #863964 panic in duron 2000 + #843433 cdrom.cc on MacOSX: wrong const names + #818493 EMU][ (DJGPP app running on FreeDOS) broken + #787005 Some MOV instructions are not implemented!!! + #840664 2200136693936p[CPU ] >>PANIC<< prefetch: RIP > CS.limit + #837416 V2 OS not compatible !? + #650917 Serial port broken under win95 + #829863 Make bochs 2.0.2 build with gcc3 + #816971 main.cc: getcwd() missing argument + #813556 Compile error under gcc 3.3.1 + #809758 RIGHT ALT does not function properly + #809695 CVS complains about unknown files after compilation + #628762 Error in Floppy Booting + #474526 Crash under win32 (access violation) + #687619 test case for BX_CPU_C::IRET32 + #664544 Panic in IRET32 - Reporting test case + #637822 test case for BX_CPU_C::IRET32 + #603410 BX_CP U_C::IRET32 + #537047 IRET32 incomplete emulation, panic + #805541 Compile fails on i686, gcc 3.3 + #798829 Problem booting from ISO image + #688163 Panic at rombios.c + #688161 rombios.c crashes when boot from a CD. + #796339 int 15h, e801h broken? + #666946 Slowdown Timer should be a module + #783826 the clock is extremely fast + #645609 Real Time Clock is too *FAST* + #663320 flaw in IO bitmap permission handling + #764929 Timing is off. + #659510 Bochs timing off by x10 + #787138 No ROM BIOS character map + #787134 Config options not saved + #689201 Disassembler bug + #666202 Windows 2000 - random screen blanking with linux DLX demo + #629242 reset during Doom -> BIOS panic + #695434 minix floppies won't boot. + #764473 Freesco Linux crashes on boot + #656026 error when trying to run some stuff + #614202 HD: non-byte IO read to 01f4 + #777357 Strange FPU compiler error + #583758 gag bootloader doesn't run + #658639 ne2k panics with MS lanman Client/DOS62 + #536711 problem running smart bootmanager + #741433 Disabling all ata# results in HD error. + #753200 lock instruction doesn't do an illegal instruction trap + #679389 libbx_wx.so.0: undefined symbol + #758936 Problem Installing Bochs + #742580 I configured fants but bochs still give me the same error + #772242 iodev/vga.cc wrong memory access. + #739222 Cannot change resultion + #693344 libwx_gtk2.3.so.2 RedHat linux 8.0 + #639320 sparc: needs -lm to compile + #587422 Windows 95j doesn't boot + #547817 sparc: rfb needs -lsocket + #480963 RFB: option to wait for client + #763893 i've got problems with a "libvga.so.1" and another file + #766490 Documentation mistake + #766481 Bochs 2.0.2 Fails to compile on YDL3.0 + #626144 %lld is not portable + #752241 lock prefix erronously allowed for some instructions + #743305 fetchdecode.c probs + #658707 Automatic exit? + #696758 BeOS can't mount image disk, won't complete boot. + #737048 Enabling keyboard resets controllers translation mode + #717713 Bochs panics on startup on RH 9 + #741108 VGA PANIC + #730922 seg fault on "bochs boot: cdrom" + #658905 VGA read write error + #564218 Panic on vga_mem_write + #614231 X11 doesn't support charmap change + #708311 Missing CGA low-res emulation + #720776 REX MOVB immediate broken for x86_64 + #643296 lock prefix, unallowed cases + #716964 [sb16] OPL.timer_running not initialized + #662074 little mistake in the default config example + #470701 CD-ROM on Win2K needs FILE_SHARE_READ + #706454 bug?? + #653861 Win32 build bug + #421155 panic on vga read 0x3c7,0x3cb + #666434 VGA BIOS: Incompatible mode reporting + #681819 Incorrent return value from cdrom reads + #648222 Lotus Agenda futuristic dates off + #657455 doesn't boot plan9 + #658938 SGDT in VM8086 + +------------------------------------------------------------------------- +Changes in 2.0.2 (January 21, 2003): + +- fix possible segfault in wxWindows (Volker Ruppert) +- fix instrumentation (Stanislav Shwartsman) +- fix cdrom read_toc() function for *BSD (Keith Matthew Jones) +- fix NetBSD boot from cdrom (Christophe Bothamy) +- fix cmos checksum (Volker) +- fix "refresh bit" behaviour in pit (Volker) +- fix .bochsrc parsing (Volker) +- fix vga resize/redraw problems (Volker) +- fix compilation issues on Irix and Tru64 (Christophe) +- fix MMX/SSE bugs (Stanislav, Peter Tattam) + +------------------------------------------------------------------------- +Changes in 2.0.1 (January 4, 2003): + +- fix corrupt saved configuration files (Christophe Bothamy) +- fix missing break statements in apic (Shai Fultheim) +- fix compiling sb16 under FreeBSD (Volker Ruppert) +- updates to the documentation (Volker) +- fix text mode colors 8 to 15 (Volker) +- fix FPU integer load bug (Volker) +- stop pasting on hardware reset (Volker) + +------------------------------------------------------------------------- +Changes in 2.0 (December 21, 2002): + +Since the change log is hundreds of lines long, here is a very brief summary. +- 2x emulation speedup!!! +- added plugin devices and guis. Now you can compile with many more + options, and choose between them at runtime. +- added emulation of AMD x86-64, MMX, SSE, SSE2 instructions +- add wxWindows port (a graphical configuration interface and display lib) + and SVGAlib port (full screen display for Linux without X11) +- improvements in many I/O devices: for example up to 8 hard disks/cdroms, + TUN/TAP network interface, 360k floppies, +- improved MacOSX/Carbon interface and updated MacOS9 port +- GDB remote stub, allows symbolic debugging with Bochs simulation. +- support for up to 32gig hard disk images + +Detailed change log follows. + +- documentation + - manpages updated (Volker, Christophe) + - install HTML rendering of docbook documentation instead of + docs-html (Bryce) + - doc/docbook/Makefile is now generated by configure script. + if configure detects docbook2html on your system, it will turn on + --enable-docbook and run make in the doc/docbook directory. Also + make install will install documentation into $(docdir). You can use + --disable-docbook to turn this off, if necessary. (Bryce) + - add "make bochsdoc.tar.gz" target to create a documentation tarball. + If you do "make webinst" and you have write access on SF shell server, + it updates doc/docbook/* on the website (Bryce) + - user documentation additions: + - new options (Bryce, Volker, Christophe) + - Bios tips section (Christophe) + - Tuntap section (Christophe) + - Serial Port section (Christophe) + - "Will it Work for Me" / "Is Bochs Right for Me" sections + (N. David Guarneri) + - VESA section (Jeroen Janssen) + - several documents, previously existing as separate html files, have + been included : + - internal debugger section (Christophe) + - gdb stub debugger section (Christophe) + - WinME, WinNT, WinXP, The Hurd, Japanese Win95 install tips (Christophe) + - Win95, Win98 install tips (N. David) + - SB16 section (N. David) + +- configure script/compile/porting to other OSes/installation + - added plugin architecture + - plugin code written by Bryce, Christophe, Volker based on + plex86's plugin code by Kevin. Testing help from Psyon and Br'fin. + - Plugins are shared libraries that can be loaded on demand. Example: + the serial device is implemented as a plugin. In UNIX, the + serial plugin is called libbx_serial.so. When Bochs reads its + configuration file, if the serial device is enabled it loads + libbx_serial.so. + - all display libraries, most I/O devices are converted to plugins now + - plugins supported on Linux, Solaris, and MacOS X using libtool, + Cygwin using dlltool. On MacOSX, you must have dlcompat installed + and in your include/library paths at configure time. (See .conf.macosx + for an example.) + - we use libtool's LTDL library from libtool 1.4.2, with a number of + critical bug fixes (Bryce Denney) + - the Linux binary RPMs are built with plugin support + - to compile with plugins, configure with --enable-plugins + - the LTDL_LIBRARY_PATH variable tells Bochs where its plugins can be + found. Bochs has a compile-time default for this variable which is + correct if you do a make install. You would only need to set the + variable if the default is wrong. + - for win32 plugins we added "BOCHSAPI" in front of many classes + and methods, to aid in building DLLs. This turns into __declspecs + which are used when making an export library for Bochs. + - allow many display libraries to be configured and compiled at + a time. For example --with-win32 --with-sdl --with-rfb. + Also, we added an experimental option --with-all-libs which + tries to detect which --with-* options will work. If the + autodetection fails, just type the --with-* options explicitly. (Bryce) + - add #if's around all files which are conditionally compiled such + as cdrom.cc and sb16.cc. This makes it possible to compile every + source file all the time, which has the potential to simplify the + configure script and makefiles. At present we only take advantage + of this capability in the win32 VC++ workspace. (Bryce) + - the MacOS9 port has been updated so that it works again. It had + not been updated in at least 2 years, maybe more. (Christophe Bothamy) + - improve support for FHS standard (Robert Millan, Volker Ruppert) + See patches 551811 and 650066. + - keep separate CFLAGS and CXXFLAGS for Bochs (usually a graphical + program) and console programs such as bximage and niclist. Some + sdl and wx compile flags were making bximage and niclist unusable.(Bryce) + - add concept of cross-configuring in the configure script. If you + use the --target option to generate makefiles to be used on another + machine, some detection of compilers and libraries is disabled. (Bryce) + - fix term compile on Cygwin, but it has to be done without -mno-cygwin, + which means that several win32 features such as networking do not work. + - add "-Wno-multichar" on beos + - test for largefile support, and add required CFLAGS (Bryce) + - add -lm when it's needed, and not when it's not (Bryce) + - add configure support for 8 processors. Bochs can support up to 15 + with some work on the BIOS. + - fix nmake makefile generation (Psyon) + - improved pthread detection function from ac-archive project on SF + - add installer package for Windows, using Nullsoft (Michael Rich, Bryce) + - on MacOSX, add startup script that creates a text console and then + runs Bochs. Also add make target to create a DMG disk image (Br'fin) + - do not restart the font server on Unix/X11, if vga.pcf was already + installed. On several modern machines, if you restart the font + server the user has to restart X windows. (Bryce) + - update most .conf.* files with modern options such as + --enable-all-optimizations. (Bryce) + - The MacosX .conf script adds /sw/include and /sw/lib to the compile/link + path list because it is a common place to put dlcompat. Dlcompat is + required when building with plugins. (Bryce) + - rpms can now be built without root privileges (Bryce) + +- command line + - fixed up our command line options (Volker, Bryce, Christophe) + Usage: bochs [flags] [bochsrc options] + -n no configuration file + -f configfile specify configuration file + -q quick start (skip configuration interface) + --help display this help and exit + +- configuration file (bochsrc) + - There are several new options. See the documentation for more details. + - config_interface: select text mode menus or wxWindows for configuration + - display_library: select which display lib to use + - optromimage: load optional rom images + - ataN (N=0,1,2,3): up to 4 ATA controllers for hard disks, cdroms + - ataN-master, ataN-slave, N=0,1,2,3: defines a hard disk or cdrom. + The "ata*" options replace diskc, diskd, and cdromd, which are + now deprecated. + - floppy_bootsig_check: control the 0xaa55 signature check on boot floppies + - logprefix: lets you change the format of log messages + (patch by Carl Sopchak, help from Christophe) + - debugger_log: log all output from bochs debugger + - user_shortcut: allow you to type key combinations like Ctrl-Alt-Del + - pit: control the PIT model, including realtime option to try to + keep in sync with real time. + - Credits: Christophe added optromimage, everything about ATA, + floppy_bootsig_check, debugger_log. Bryce added config_interface + and display_library. Volker did the user_shortcut button. + Greg Alexander wrote the PIT model and added the realtime option. + - since v1.3 we've been able to use environment variables in pathnames + in the bochsrc file. Now, a few variables have default values, set at + compile time, that are used if the user does not set a value. If Bochs + is installed correctly, the defaults will be correct and the user will + not need to override them. + - $LTDL_LIBRARY_PATH is the path name where the plugins can be found. + The default value comes from $(plugdir) in the makefile. This is only + important if plugins are enabled. (Bryce) + - $BXSHARE is the path where the BIOSes and keymaps are installed. + The default value comes from $(sharedir) in the makefile. Disk + images on the Bochs website will begin to use BIOS pathnames like + $BXSHARE/BIOS-bios-latest. On win32, the $BXSHARE default is + set by the NSIS installer and read from the registry. On MacoSX, + the $BXSHARE default is set to the path containing bochs.app. + (Bryce, Volker, Br'fin) + - new option in the configuration interface to reset all bochsrc + settings to initial defaults. A reset occurs just before reading + a new configuration file, so that leftover parameters from a + previous configuration do not affect the new configuration. Also, + you can request a reset using the configuration interface. (Volker, Bryce) + - ne2k line can now specify a script to set up the interface (Christophe) + - on Unix, also search /etc/bochsrc (Bernhard Bablok) + - you can use #include in the bochsrc to read configuration from other + files (Volker) + +- CPU + - speed optimizations from Kevin Lawton, yielding around 2x speedup + - guest2host_tlb : for entries in the paging TLB which point to normal + physical memory pages, a pointer to the host address of the emulated + physical memory (from malloc()) page is stored in the TLB entry. In + many cases, this pointer can be used in memory accesses to directly + read/write the guest memory address. In exceptional cases, the physical + memory access routines are used. Turn on with --enable-guest2host-tlb. + - repeat IO/string : for some variants of repeatable IO and string + instructions, the segmentation and paging checks are done in batch along + with the data transfers, constrained within page boundaries and the + segment limits. Turn on with --enable-repeat-speedups. + - icache : The structure holding instruction decode information was + reduced to 32 bytes. 24 bytes for the actual decode data, and 4 each + for pointers to the address resolution routine (not always needed) and + the instruction emulation routine. With a reasonably small + per-instruction decode size, an instruction cache (iCache) was created, + which is simply a hash table. The main cpu loop looks in the table + first; if the instruction has already been decoded, execution can begin + immediately without decoding. Turn on with --enable-icache. + - host specific asm : when compiling on an x86 platform, use of + x86-specific asms can be enabled to accelerate several facets of + emulating instructions. For example, the EFLAGS values are much more + efficient to calculate when the actual x86 instructions are used to + generate the EFLAGS values. Turn on with --enable-host-specific-asms. + (Kevin, with help from Jas Sandys-Lumsdaine) + - if you want to enable all the speed optimizations that we believe + to be stable, use --enable-all-optimizations. The release binaries + are built with this option. + - add support for AMD's x86-64 instruction set. To enable, configure with + --enable-x86-64. The AMD x86-64 support is about 90% complete and is + still experimental. We've implemented the core x86-64 instruction set and + the changes to the rest of Bochs necessary to operate in long mode, but + we've still to implement checking for canonical 64 bit addresses. The code + has been tested on a limited number of test programs. It has been able to + successfully boot a x86-64 Linux kernel and run a 64 bit userland + application. It has also successfully run a DOS based 64 bit protected + mode test application. (Peter Tattam, with merge/bugfix help from Kevin + Lawton and Bryce Denney) + - add MMX support. To enable, configure with --enable-mmx. + (Stanislav Shwartsman) + - add SSE and SSE2 support. To enable, configure with --enable-sse=1 + or --enable-sse=2. (Stanislav) + - fixed the behaviour of the bcd instructions AAM, AAD and DAA based on + SF patch #537146 (Volker) + - stop printing an error for VERR/VERW. According to the i386 opcode + description there is no error present. (Volker) + - fix bug [ 625878 ] reset doesn't reset something(?). Fix cpu reset + when executing a rep instruction (Christophe) + - use accessors methods for CFLAGS and several other registers, so that + the implementation can be changed transparently later (Bryce, Stanislav) + - add support for page size extensions, also known as 4meg pages. + Turn on with --enable-4meg-pages. (Kevin Lawton) + - add support for page global extensions. Turn on with + --enable-global-pages. (Kevin) + - add support for physical address extensions. Turn on with --enable-pae. + (Peter Tattam) + - implement RDMSR and WRMSR. not all MSRs are supported (Zwane Mwaikambo) + - new configure option --enable-ignore-bad-msr, which makes unrecognized + MSR reads and writes into just a warning + - fix PIC/APIC interrupt problem that caused Linux 2.4.19 to hang + during boot (Peter) + - CMPXCHG8B patch (Michael Hohmuth) + - EFLAGS are now stored in the same form as the native EFLAGS on an x86, + so that we can use native machine instructions in some cases (Kevin) + - instrumentation code updated (Stanislav) + +- FPU + - fixed bug [ 452275 ] fprem emulation bug (Volker) + - fixed bug [ 648579 ] Mac OSX >>PANIC<< FPU_printall. There was an + endianness issue with the fpu (Christophe) + +- I/O devices + - rewrote pc_system timers (Kevin) + - biosdev + - this new device handles the panic/error/info/debug messages sent + by the Bios and VGABios. It was previously done in the unmapped device. + - cdrom + - implementation of the function READ TOC for cdrom image files. (Volker) + - function capacity() for win32 fixed. Now it returns the number of blocks + instead of bytes. (Volker) + - added multiple cdrom support for win32 (NT/2000 version untested). The + ASPI version uses the cdrom drives in the system's order. Drive letters + are not used by ASPI. (Volker) + - fix configure script's cdrom detection on BeOS (Bryce) + - fix physical CD change at runtime (Bryce) + - cmos + - fix panic when WinXP read port 70h (Christophe) + - add ps/2 style century at index 37 to allow WinXP to boot. (Bryce) + - dma + - DMA register and unregister functions for DMA channels added and macros + for DMA functions defined. The changes are based on the Plex86 functions. + (Volker) + - implementation of the DMA controller reset (Volker) + - the value of the command register must be always 0x00 (BX_ERROR fixed) + - floppy (Volker) + - implemented Tape Drive Register (Dave Poirier) + - added support for 360k floppy images + - the skip flag (SK) in command 'read sector' is ignored now + - floppy read and write function do not set the 'seek end' bit in status + register 0 (fixes SF bug #553377) + - the status of the 'disk changed' line depends on the selected drive. + The digital input register is now an array (DIR[4]). + - apply patch [ 635021 ] floppy cleanup by Alex Thiel + - distinguish between floppy drive type and media type + - hard drive + - add largefiles support, to allow disk images larger than 2gig. + (Stu Grossman) + - missing conditions for lower_irq() added (Volker) + - several noncritical panics replaced with BX_ERRORS and the controller + returns an error code until we implement the features (Volker) + - applied patch from Carl Sopchak for booting sco openserver + - allow disk block access only if concatenated images are not used + (Christophe) + - fix bug [ 419415 ] netbsd 1.5 rescue disk won't boot (Volker) + - multiple drq atapi data transfers corruption fixed (Christophe) + - added some commands to the unsupported "Set Feature" commands (Christophe) + - speedups in repeated IO transfers (Kevin) + - support for Peter Tattam's external disk simulator (Bryce) + - 4 channels / 8 devices support (Christophe) + - "inquiry" atapi command results corrected (Volker) + - check for incomplete devices configuration before starting the + simulation (Bryce) + - implemented the different bios disk translation schemes (Christophe) + - keyboard and mouse + - add commands 0xd2, 0xdd and 0xdf (Dave) + - fix bug [ 613975 ] wxWindows: params redefined on restart (Bryce) + - in function mouse_motion(): added parentheses to fix compilation problems + with MSVC. See SF bug #575301. (Volker) + - added missing register_irq() for the PS/2 mouse IRQ12 (Volker) + - fix "AltGr" key on European keyboards wxWindows/win32, SDL (Volker) + - NE2000 + - function reset() clears the IRQ line (Volker) + - added TUN/TAP interface (Renzo Davoli, Christophe) + - fix DOS based packet drivers that use an odd count for the NE2000 DMA (Peter) + - changed "TCR write, reserved bits set" panic into an error, fixes + networking with debian image (Bryce) + - parallel + - parport1 enable/disable support added (Volker) + - PCI (Volker) + - implementation of the PCI device register mechanism + - PCI memory handling moved to the memory code + - replaced memcpy() in pci_read() by a more portable code. Problems with + PCI on big-endian machines are fixed now (SF bug #638481). + - implementation of the PCI-to-ISA bridge started (still incomplete) + - PIC + - fixed detection of single mode and level senistive mode in ICW1 (Volker) + - fixed handling of rotate_on_autoeoi for master PIC (Volker) + - irq mask is now cleared on initialization (Dave) + - fixed lockup during mouse movements during win98 install. (patch from + Wilfried Weissmann) + - PIT + - Added realtime PIT support (Greg) + - Sound Blaster 16 + - it used to enable itself all the time; now only when you ask + - fix memory leaks (Bryce) + - serial + - don't cause problems when serial device is disabled (Volker) + - unmapped + - add programmatic shutdown feature at port 0x8900 (Christophe) + - vga + - VBE fixes (Jeroen, Volker) + - CRTC fixes (Volker) + - sequencer reset with bits 'reset1' and 'reset2' implemented (Volker) + - add charmap change support (used by SDL, win32 and wxWindows gui) (Volker) + - screen dimensions / updates for some graphics and text modes fixed (Volker) + - use the start address when calculating the byte offset for standard + EGA/VGA modes (Volker) + - byte offset for modeX fixed (use value of CRT register 0x13) (Volker) + - text mode memory mappings 0 and 1 support (Christophe) + - fix bug [ 612741 ] VBE mem conflicts w/ local APIC address (Jeroen) + - fix bug #635223: VGA tiles array access out of bounds (Bryce) + +- ROM BIOS + - improve compile process. Now bioses for 1, 2, 4 and 8 processors + are built at the same time (Bryce) + - fixes to be able to compile the bios with gcc2 or gcc3 (Jeroen and + Christophe) + - changes on boot signature check (Christophe): + - never done for cdroms + - always done for hard-disks + - conditional for floppies + - add keyboard int16 functions 0x09 (get keyboard functionality) and + 0x0a (get keyboard id) (Christophe) + - fix bug [ 629810 ] int 16/ah=01 broken? Enable interrupt on entering + int16 handler (Christophe) + - new keyboard init in POST (patch from Adam Sulmicki) + - flush input and output keyboard buffer before keyboard self test + (Volker and Christophe) + - fix bug [ 547603 ] kbd up/down arrows in dos install (Christophe) + - fix bug [ 549815 ] bios wrongly loads CS,ES. CS and ES are set to 0 + before the bootloader code is called. (Christophe) + - PCI functions support (Volker) : + - BIOS32 service directory + - real mode PCI int1a functions + - protected mode PCI int1a functions + - fix reset for MS-DOS and Win95 (Volker) + - 360K floppy support (Volker) + - enhanced ata/atapi support (Christophe) : + - 4 channels / 8 devices + - device auto detection (with help from Adam Sulmicki) + - EDD3.0 + - 32bits device access + - optional disk translation "large", "r-echs" or "lba" (up to 8.4GiB) + - re-enable harddisk controller interrupt after reads/writes. + Win95 can now use native access to harddisks and cdroms. (Volker) + - shutdown status handling (cmos index 0x0f) (Christophe) : + - fix bug [ 601166 ] CMOS Problem @ "0x0F Index 0x05 data". After reset + execution will resume by a jump to [0x40:0x67] if the shutdown status + is 5 + - the bios don't panic any more if the shutdown status is 9 + - two parallel ports detection in POST (Volker) + - two serial ports detection in POST (Volker) + - add int15 extended memory function 0xe820 (patch from osmaker) and + 0xe801 (patch from Hartmut Birr) + - fix return values on some int15 functions (Bryce) + - fix int70 handler overlapping int08 handler (Christophe) + - simplify 8 processors BIOS for operating systems which don't do + paranoia/sanity checks (Zwane) + +- configuration interface + - wxWindows config interface now allows you to change every bochsrc + option using menus and dialog boxes. There is also the beginning of + a wxWindows graphical debugger, but it needs a lot of work before it + will be useful. + - renamed control.cc to textconfig.cc. Now we're calling it a + text configuration interface, instead of a control panel. + +- display libraries + - Even though we've had them for years, the term "display library" is new in + release 2.0. In the gui directory, Bochs has a number of different C++ + files which you can select to display the text and graphics on the + simulated monitor. Each of these is a display library. The display + libraries are: + x use X windows interface, cross platform + win32 use native win32 libraries + carbon use Carbon library (for MacOS X) + beos use native BeOS libraries + macintosh use MacOS pre-10 + amigaos use native AmigaOS libraries + sdl use SDL library, cross platform + svga use SVGALIB library for Linux, allows graphics without X + term text only, uses curses/ncurses library, cross platform + rfb provides an interface to AT&T's VNC viewer, cross platform + wx use wxWindows library, cross platform + nogui no display at all + - it is now possible to compile Bochs with support for many different + display libraries and select the one to use at runtime (even without + plugins). See the display_library directive in .bochsrc. + - add new svgalib display library by Igor Popik + - fix bug [ 614724 ] SDL can get stuck in full screen mode + display libraries such as SDL which have a full screen mode can be + dangerous, if Bochs does not switch back to normal display mode at + the right time. This is fixed for SDL and the new svga. + - keymap support added in SDL interface (Bryce, Volker) + - new keymap files: SDL keymaps for US and DE keyboards, X11 keymap + for Danish keyboard. + - use keyboard mapping for keyup messages too + - renamed almost all references to data type "Boolean" to "bx_bool". + The Boolean data type was defined in Carbon.h headers, and conflicted + with Bochs's definition. See bug [ 618388 ] Unable to boot under MacOS X + Exceptions: When talking to the Carbon library, you must use Boolean. + Also, siminterface.h uses standard "bool" instead of bx_bool. + - "User" button added in toolbar. It can send keyboard shortcuts to + the guest OS. (Volker) + - snapshot improvement and memory leak fixed (Volker) + - testing framework, based on comparing screen content, added (Greg) + - term display library: + - support for color terminal, function keys, clear screen (Volker) + - solaris compilation problem (bug #613393) fixed (Bryce) + - win32 display library: + - use native win32 toolbar for headerbar, use system palette (Volker) + - many Carbon interface improvements: + - patch [ 549248 ] Fix Carbon key & menu handling (Chris Thomas) + - partial keymap support, copy&paste, menu items fixed, new toolbar + behavior, dialog box display for panics (Br'fin) + - sdl display library: + - keyboard fixes and key mapping added (Bryce) + - when captured, the mouse is forced to stay in the window. fix bug + [ 619283 ] SDL: os mouse pointer leaves the window (Bryce) + - x display library: + - bug [ #537593 ] vga font not being found fixed. If vga font not + found, search for a font called "-*-vga-*" (Bryce) + - keyboard problems fixed (Bryce, Christophe) + - beos platform, any display library: add a nice icon to the executable + (Bernd Korz) + +- wxWindows + - wxWindows is a cross-platform C++ user interface library which you can + download for free at http://wxwindows.org. wxWindows provides C++ + classes for all sorts of GUI controls (buttons, menubars, etc.) and + implements all of them using the native controls on the platform. + - The new wxWindows port of Bochs provides both a graphical configuration + interface (for editing bochsrc options) and a display. It was + written by Bryce Denney, Don Becker, Dave Poirier, and Volker Ruppert. + - In release 2.0, we concentrated on making the wxWindows port as stable + and functional as the other interfaces. wxWindows provides a great + toolbox that we can use to make Bochs easier to learn and use. + - wxWindows supports charmap changes, keyboard mapping, cut and paste, + text and graphics modes, text mode cursor size, and mouse (Volker, Bryce) + - To compile Bochs with wxWindows, you should install wxWindows 2.3.3 + or later. Then configure Bochs with --with-wx. + - if you have multiple versions of wxWindows installed (e.g. a debug + and a release version), you can set $WX_CONFIG before configuring + to select between them. (Bryce) + +- Bochs debugger + - [ 609616 ] remote GDB stub + add GDB Stub support from Johan Rydberg, with bug fixes by Stu Grossman + - add hooks for external debugger for win32. The external debugger + that connects to Bochs is distributed in + build/win32/tattam-external-debugger.zip in binary form. Turn on + with --enable-external-debugger. (Peter) + - add "debugger_log" option to bochsrc, which logs all debug output + into a file. feature [ 629068 ] (Christophe) + - debugger is now usable in fullscreen SDL and SVGA guis. It will + switch back to text mode for each debug prompt (Bryce) + - disassembly output cleaned up and improved + (Kernel Panic, Peter Tattam, Jonathan Shapiro, Luiz Henrique Shigunov) + - fix [ 628806 ] debug: x/c prints unprintable chars (Bryce) + - add the beginnings of a wxWindows debugger. Not ready for mainstream use + yet. CPU register display is implemented, and you can type any debugger + command you want into the Debug Console window. (Bryce) + - add help command (Alexander Krisak) + - symbol table lookups cleaned up a bit (Bryce) + - displays the address of the caught watchpoint, feature #435271 (Dave) + - remove obsolete "loader" + +- utilities + - fixed bug [ 487758 ] bximage fails on file creation >2048meg + Bximage should now work up to 32gig. (Bryce) + - on win32, both bximage and niclist now ask the user to press + return before exiting, so that you have time to read the results + before the window disappears. (Bryce) + +------------------------------------------------------------------------- +Changes in 1.4.1 (June 22, 2002): + +- now cdrom is enabled in configure, unless you specifically disable + it with --disable-cdrom. (Christophe) +- fix compile error in main.cc when SMP or APIC is enabled (Dave) +- the runtime menu now displays 11 (continue) by default (Bryce) +- initialize DMA controller before floppy and SB16 +- fix DMA panic when installing win95 (Volker) +- first character of the vga bitmap is blank on win32 (Volker) + Before, it was incorrectly coded as a '@'. +- AltGr key on European keyboards works now on win32 (Volker) +- fix problem with console/serial port on Bochs exit (Volker) +- enable serial port for GNU and GNU/Linux (Volker) +- small documentation fixes (Volker) +- remove unnecessary include statements for X11 (Volker) +- italian keymap added (Emanuele Goldoni) +- fix win32 ethernet frames error. It will no longer reject packets + that are less than 60 bytes long. (Peter Tattam) +- BIOS fixes : + - win2k cd-boot (Christophe) + - emm386 crash (Dave) + - cs=0 at boot time (Christophe) + - keyboard failure in scandisk (Dave) +- fix bug in forming the 64-bit APIC base address from two 32-bit registers. + A compiler warning in cpu/proc_ctrl.cc pointed this out. +- fix default choice in the runtime options menu + +------------------------------------------------------------------------- +Changes in 1.4 (March 27, 2002): +- ROM BIOS + - Boot from CDROM! Christophe Bothamy added partial El Torito support in + rombios.c, which allows Bochs to boot cdroms. Booting from win2k or winXP + cdrom is not supported yet. The default BIOS includes El Torito functions. + the boot line must say "cdrom". + Example: + boot: cdrom + - implementation of int13 diskette function 5 (format track) (Volker) + - initialisation of PIC and DMA-2 added to POST code (Volker) +- configure script (Bryce Denney) + - the configure script now detects your platform and provides a default + GUI and the required compiler flags. All supported platforms should + compile with simply "configure" and "make". + - default guis by platform: + - win32/windows/cygwin: win32 gui + - MacOS X: carbon gui + - MacOS 9 or earlier: macos gui + - BeOS: beos gui + - AmigaOS: amigaos gui + - all other platforms: X windows gui + - compile arguments supplied by configure script + - win32: too many to list here; see documentation + - cygwin: -mno-cygwin -DWIN32 + - MacOS X: -fpascal-strings -fno-common -arch ppc -Wno-four-char-constants + -Wno-unknown-pragmas -Dmacintosh + - the --with-GUINAME configure option is only needed if you want to override + the default GUI. This is the only way to use the Term, RFB, and SDL + GUIs. +- VGA + - added VESA BIOS Extensions code by Jeroen Janssen (banked mode only, LFB + support in patches) + - vga memory read/write functions in text mode fixed + - implementation of CGA mode 320*200*4 (patch from Sebastien Bechet) +- VGA BIOS + - updated Christophe Bothamy's LGPL VGA BIOS to version 0.3a. This consists + of a bug fix for function ah=13 and VBE support by Jeroen Janssen. +- networking + - chipmem read/write limit fixed (Mike Lerwill) + - writing a byte in 16-bit mode now possible (Mike Lerwill) + - new ethertap interface for Linux, which allows Bochs to talk to + the local machine and the internet (Bryce Denney) + - NE2000 is now enabled by default on Win32, Cygwin, and Linux compiles + in the .conf.* scripts and release binaries. + - fix check for auto transmit disable, which was checking the wrong bit + (Peter Tattam) + - Win32 only + - niclist.exe has been revised to work on more Windows versions, and it + suggests a usable ne2k line (Dean Payne) + - fix timeout setting so that ne2000 does not slow down the whole + simulation (Don Becker) + - bug fix: be able to handle multiple packets that arrive at once + (Mike Lerwill) +- GUI changes + - cdrom button: click this to notify Bochs when you changed the CDROM (Volker) + - snapshot button: saves the text on the Bochs screen into a file called + snapshot.txt (Volker) + - copy button: on Win32 and X windows, copy the text on the Bochs screen + to the clipboard (Volker) + - paste button: on Win32 and X windows, paste the characters on the + clipboard into the Bochs window. This requires keyboard_mapping to + be enabled. (Bryce Denney) + - improved text mode cursor for Win32, X11, and SDL (Volker) + - new SDL interface (Dave Poirier, debugging by Christophe, Volker, Bryce) + SDL is a graphics library that has works on many platforms. This interface + is experimental, and is missing a few features of the standard Bochs + interfaces: extended keys (arrows, keypad). + - MacOS X: add MacOS X carbonized event handlers by Jeremy Parsons + - X windows: when not enough colors can be allocated, force use of + private colormap (Bryce Denney) + - bug #490570 fixed: OUTB set and command 0xaa encountered (Dave Poirier) +- keyboard + - completed keyboard emulation with the implementation of the three scancodes + sets (mf1, mf2, mf3) with or without translation. This is based on Ludovic + Lange's plex86 keyboard patch. (Christophe Bothamy) + - added a "keyboard_type" option, that defines the answer to an "identify + keybord" request to the keyboard controller. The available values are + "xt","at","mf". (Christophe Bothamy) + - added an optional keyboard_mapping option that enables to use your + country specific keyboard with Bochs. If enabled, the keymap file must be + specified in bochsrc. The available keymaps are US, German, Spanish and + French for PCs running X11. Contributions are welcomed. (Christophe + Bothamy) + - added Windows(tm) key definitions (Volker Ruppert) + - added paste button, which causes the emulated keyboard to type characters + from the system clipboard. This only works when keyboard_mapping is + enabled. (Bryce Denney) +- cdrom + - bug fix: win32 could not read a cdrom image file + - eject cd support for linux (patch from Petr Stehlik) + - BeOS fixes + - changing cdrom media is possible now with CDROM button +- sound blaster(tm) emulation (Volker) + - you can use --enable-sb16=freebsd now + - 16-bit DMA controller added + - 16-bit mode of the SB16 implemented (output to file works) +- floppy drive (Volker Ruppert) + - implementation of the floppy command 'format track' + - implementation of read / write operations with MT=0 + - behaviour of a few floppy commands fixed + - floppy reset behaviour fixed + - lots of other fixes +- fixed bug [ #468340 ] pic:slave: OCW3 not implemented. Now the slave PIC + supports all the modes that the master PIC does, and nobody will see this + message again. +- serial port (by Volker Ruppert unless noted) + - improved IRQ handling + - now Windows 95 serial driver works correctly + - fixed the return value of the MCR (loopback bit) + - interrupt reasons LSR change and MSR change implemented + - the number of data bits is considered when sending data + - all serial port changes are tested in loopback mode only + - serial port emulation fixed for FreeBSD and OpenBSD (Stu Grossman) + - fix receiver poll frequency so that it doesn't slow emulation (Stu Grossman) +- Bochs debugger + - when tracing, print the instruction just before it is executed, instead + of just after (Greg Alexander) + - after a triple-fault panic, you can now return to the debugger +- symmetric multiprocessor (SMP) simulation + - no more panic if you read the EOI register + - fixed default destination format in local APIC + - fix SMP instruction tracing in bochs debugger + - fix deadlock when debugger enabled and all processors HLT + - MSR support added by Zwane Mwaikambo +- simulation of interrupts is more accurate (Volker) + - implemented edge triggered interrupt mode + - added functions raise_irq() and lower_irq() +- programmable interrupt timer (Greg Alexander) + - fixed the PIT gate and improved the PIT printing options + - experimental real-time PIT +- parallel port improvements (Volker Ruppert) +- bug fix: hard disk errors caused by overflowing imul in the BIOS code. + Sebastian Bechet and Peter Tattam tracked it down and fixed it. +- fix some memory leaks (patch from Darko Tominac) +- Double-Word IO is supported for ATA devices +- fix bash-specific syntax in install-x11-fonts script +- print stack_return_from_v86 error only the first 100 times + +------------------------------------------------------------------------- +Changes in 1.3 (December 10, 2001): +- networking works on Windows and Linux platforms +- emulated cdrom can now read from ISO image files, on any platform. +- new PIT model by Greg Alexander which is much more complete than the + old one. The new PIT is used by default, but you can switch back to + the old one if you configure with --disable-new-pit. + (PIT = 8254 programmable interrupt timer) +- new configuration menus by Bryce Denney, which allow you to change any + bochsrc option using text menus, then save the configuration into + a new bochsrc file for later use. You can disable the new code using + configure --disable-control-panel. Also you can use the command + line arguments -nocp or -nocontrolpanel. Also, there is a new + "Config" button on the GUI that allows limited changes to the + configuration at runtime, such as changing the floppy disk. +- add docbook documentation directory in the sources under doc/docbook. + The transition from HTML to docbook documentation is still in progress. +- Add new log action "ask", as shown in these example bochsrc lines: + panic: action=ask + error: action=ask + When an event occurs which is set to "ask", you get a beep and message + on the text terminal that asks what you want to do. Choices are: continue, + continue and disable future messages from this device, quit immediately, + or segfault (where abort() function is available). If compiled with + --enable-debugger, you can also choose to enter the debugger. +- Parallel port emulation cleaned up by Volker Ruppert. See .bochsrc for + syntax of new parport1 line in bochsrc. +- PCI support improved by Volker Ruppert, including BIOS changes. Still + not complete. +- floppy controller returns a proper error response if you try to write + a read-only disk image. For systems such as DOS that actually use the BIOS + services, it was also necessary to add code in int13_diskette_function to + recognize a write-protected error and return the correct error status code + (AH=3, Carry Set). +- the ROM BIOS now prints panic messages to the console. Thanks to Cliff + Hones for his console display code. +- the ROM BIOS detects nonbootable disks (Barry Allard), and prints a message + on the console. Barry Allard's patch who helped with checking the boot + signature. +- LBA support added for hard disks. (Not tested very much.) +- add dependencies to makefiles +- logging code moved into a separate file, logio.cc +- new option --enable-slowdown-timer, by Greg Alexander, which kicks in if + Bochs simulation time starts to run faster than real time. This helps to + keep the Bochs clock in sync with the real clock when the CPU is mostly + idle. +- new option --enable-iodebug, by Dave Poirier, which creates an I/O + interface to the debugger. This lets you write software to be emulated + in Bochs which can turn on instruction, register, or memory tracing + using I/O accesses. +- improved detection of readline in configure script +- configure substitutes the version number into many files, instead of + using sed in the makefile. There are still a few uses of sed remaining. +- you can now use environment variables in bochsrc values. For example, + diskd: file="$BOCHS_IMG/diskd.img", cyl=615, heads=6, spt=17 +- configure with --prefix=PATH works now +- running configure from a different directory works now, thanks to + a patch from Edouard G. Parmelan +- fix [ #433759 ] virtual address checks can overflow. + > Bochs has been crashing in some cases when you try to access data which + > overlaps the segment limit, when the segment limit is near the 32-bit + > boundary. The example that came up a few times is reading/writing 4 bytes + > starting at 0xffffffff when the segment limit was 0xffffffff. The + > condition used to compare offset+length-1 with the limit, but + > offset+length-1 was overflowing so the comparison went wrong. +- cmpxchg8b patch from Michael Hohmuth +- apply patch from Thomas Fitzsimmons to fix compile + problems when BX_SUPPORT_PAGING and BX_USE_TLB are turned off +- fix bug introduced in 1.2.1 which caused spurious exceptions. + See patch #439314, Exception 1 (debug) on HALT, from + thomas.petazzoni@meridon.com. +- add panic in ctrl_xfer32.cc where the IRET32 implementation is broken. + This only happens if you are NOT in vm8086 mode or protected mode. + The intent is to warn people when they are getting bad emulation, and + encourage people to report how they got to that point. +- apply patch from Santiago Bazerque. See this bug report: + [ #463018 ] retf not removing parameters sometimes +- fix bug [ #461730 ] IRETD causes problems if NT-flag is set + reported by Peter Lammich. +- apply patch [ #455014 ] CR0 bug in 80486, described as: + > In the register CR0, when the bit PM is enabled, the bit 4 is 0 + > when should be 1. +- apply patch from Mike Rieker associated with this bug + report: [ #480422 ] gdt 'accessed' bit +- in task_switch when it tried to ensure that the old TSS was paged in, + it actually used the new TSS address, fixed. +- updated the instrumentation code, and added a working example. To try + it, configure --enable-instrumentation=instrument/example1. Then when + you run bochs, you will get one line for each instruction PC and for + each I/O access in a new file called bxevent.txt. +- set a bit in the CMOS that says the processor has an FPU. This is + from patch [ #455006 ] Device byte is not initialized aptly. + Author did not leave their name. +- add logging code to the "null ethernet" which does not require host OS + support. All this does is print the outgoing packets from the guest OS. +- cleanup of log functions (Todd Fries) +- add BX_ERROR for every command in ATAPI-6 that bochs does not support. + I still need to do add some commands from older specs that are obsolete + (and not listed) in ATAPI-6. Commands that aren't in the spec will still + panic. +- only put 0xf into the 2nd hard disk field when the cdrom is not present. + This is a patch from Volker Ruppert , who + comments: "The fdisk command reports an unusable second harddisk if the cdrom + is enabled. This patch helps, but I don't know if it is the right way." +- make hard disk code return error codes when data is not available instead + of just panicing. In particular, if the logical sector is out of bounds + or the disk image cannot be read/written at the desired offset, we now + abort the ATA command and return an error code. Many of the old BX_PANIC + messages are turned to BX_ERROR, so they will still appear in the + log, but now the device model will try to communicate this fact to + the OS instead of simply giving up. +- don't blindly reject odd length atapi commands. There are cases when + it's really ok according to ATA-4. +- for big endian machines, reversed the bit fields in interrupt_reason. + This was pointed out by Nicholai Benalal. +- extended keyboard improvements by Dave Poirier +- major mouse patch from Dave Spring, that implements several missing + mouse modes. +- commit keyboard patch from David Haslam + posted to mailing list, that addresses the problem of each key press + printing ^@. See cvs log for details. +- mouse performance fixes by Greg Alexander and Robb Main +- NE2000 fixes by Frode Vatvedt Fjeld, ecelca@yahoo.com, Greg Alexander, + and angelos@openbsd.org. +- fix bug [ #468340 ] pic:slave: OCW3 not implemented. Some event handling + code appeared in the master pic but not the slave pic. +- fix compile problems in SB16 code, related to fpos_t being treated as + an integer. +- patch from Volker Ruppert to fix + midi output file so that winamp can play it. +- some cleanup of serial code by Todd Fries and Volker Ruppert, but it + doesn't work yet. + +X Windows specific: +- commit patch from David Haslam + [ #455763 ] Cursor trail with DOS Edit/Minix vi +- error for missing fonts now points to the documentation +- new option --enable-idle-hack, by Roland Mainz, which makes Bochs more + friendly toward other processes when its CPU is idle. Presently, + this option is specific to X windows. + +Win32 specific: +- now Windows 95/98/ME can read the physical cdrom (Don Becker) +- The default configuration for Win32 VC++, given in .conf.win32-vcpp, + now enables the NE2000 and renames all .cc files to .cpp. This keeps VC++ + happy but may make it hard to use CVS. +- The default configuration for Cygwin, given in .conf.win32-cygwin, now + enables cdrom and SB16. +- See "new docs" on the web site for compile instructions for VC++ and Cygwin. +- The sources include a VC++ workspace, in addition to the old "nmake" + makefile. +- ethernet support (emulated NE2000 card), coded by Don Becker. This + implementation requires a library called WinPCap, which you can + download from http://netgroup-serv.polito.it/winpcap. +- new utility called niclist.exe which lists the ID number of all your network + cards (well probably you just have one). The ID be used when setting up your + .bochsrc. +- patch [ #466403 ] make text colors more accurate. The author did not leave + his/her name. +- fix GUI bug [ #452159 ] win32: mouse stuck if bochs win partly off screen + Now we center the mouse periodically, whether or not the mouse has + wandered outside of the window or not. +- event handler recognizes the extended keycode flag +- fixes for raw floppy and floppy disk images (Don Becker) + +Linux specific: +- Ethernet (emulated NE2000 card) now works in Linux! Contributed by + splite@purdue.edu. This has been tested using host OS kernel 2.2.14, and + works with telnet, ftp, irc, lynx, etc. Because it is a packet filter + solution, you aren't able to talk to the host machine, only to other + machines on the network. +- The default configuration for Linux, given in .conf.linux, now enables + the NE2000 model. +- RPM build process configures with --prefix=/usr so that everything is + installed in /usr/bochs instead of /usr/local/bochs. +- DLX Linux disk image is now installed so that only root can write it, to + avoid security problems. When you run the bochs-dlx script, it creates a + local copy in your home directory and then runs it. +- code that determines the capacity of a cdrom now works for both ATAPI + and SCSI drives (splite@purdue.edu) +- applied patch from bochs@sigint.cs.purdue.edu. The comments are: + > The Linux 2.4.5 CD-ROM driver sends a READ_DISC_INFO command which caused + > an "unrecognized ATAPI command" panic. Looks like READ_DISC_INFO is only + > recognized by CD-R and CD-RW drives, so I ignore it for now. + +Amiga MorphOS specific: +- Bochs now compiles and works on Amiga MorphOS. Configure with + --with-amigaos. For AmigaOS only, see .bochsrc for use of fullscreeen and + screenmode options. The Amiga MorphsOS is written and maintained by + Nicholai Benalal . +- raw cdrom supported if you configure with --enable-cdrom + +BeOS specific: +- Bochs compiles and works on BeOS. Configure with --with-beos. + Bernd Thorsten Korz maintains the BeOS port. +- raw cdrom supported if you configure with --enable-cdrom + +MacOS X specific: +- Bochs now compiles and works on MacOS X. Configure with --with-carbon. + Emmanuel Mailliard ported the Macintosh code to the + Carbon API. +- The MacOS X application is built using (gasp) mkdir, copy, and rez. + Surely this is not the right way, but it works. +- raw cdrom supported if you configure with --enable-cdrom + +RFB mode: +- apply patch.rfb-mouse by MURANAKA Masaki (monaka@users.sf.net) + see this source forge bug [ #457968 ] Strange mouse motion on RFB +- add a retry loop in RFB code, so that if port 5900 is not available + it can try 5901, etc. + +Bochs Debugger: +- do a vga update whenever you print a debugger prompt. +- added debugger command "info fpu" that prints the FPU registers. If you + do "info all" you get cpu and fpu registers. +- added debugger command "info ne2k" which prints all the registers + of the NE2000 model +- add ability to do register tracing and flag tracing (Dave Poirier). + Try the trace-reg-on and trace-reg-off commands. +- instruction trace now includes time ticks +- fixed problems in which bochs compiled with debugger measured time + differently from bochs compiled without debugger. Also when instruction + trace was enabled, breakpoints and control-C did not work. Also, + breakpoints at the beginning of an interrupt handler did not work. + +------------------------------------------------------------------------- +Changes in 1.2.1 (June 12, 2001): +- more work on makefile for building RPMs +- [ #432382 ] build debian packages patch + add build/debian directory from Rob Lemley + which allows us to make Debian packages! +- optimize for speed when simulating one processor. Now 1-processor + performance should be equivalent to 1.1.2. +- [ #425640 ] sb16 assumes fpos_t is long int + This fixes compiles of iodev/sb16.cc on linux systems with newer libraries + in which fpos_t is not an integer. +- [ #432488 ] SMP:assert "n_logfn < MAX_LOGFNS" fails + increase MAX_LOGFNS since we ran out of them on an SMP simulation with + 4 processors +- changes to compile clean on cygwin: + - don't use the WIN32 snprintf define for cygwin + - add ssize_t definition for cygwin + - only compile "struct timeval tval" if select is available + on that platform. +- [ #432491 ] SMP: CPUID says no APIC feature + clean up inconsistent use of BX_SUPPORT_APIC and BX_APIC_SUPPORT, which + caused the CPUID to report no APIC was present +- [ #431025 ] --enable-external-device-models broken + removed configure options for external-device-models and + external-cpu-memory. These don't work and aren't going to be fixed. +- [ #429448 ] configure: -lreadline when not there + Now configure allows you to choose not to use readline, even if it's found + on your system. +- [ #428915 ] apply extended keyboard patch + extended keyboard patch by Dave Poirier +- [ #428626 ] if no X11 found, configure&make fails + Now configure halts if X windows is selected but no X libraries are found. +- updated rombios to version 1.13. This fixes several problems: + - [ #430472 ] DOS HIMEM "A20 line" error + This problem was apparantly caused when Bryce added a function that prints + the BIOS version, and he called it too early in the boot process. Now the + same function is called later, and it doesn't break the A20. + - [ #431010 ] SMP structure overwritten in v1.2 + SMP structures were getting overwritten by BCC-generated data, + preventing SMP operating systems from detecting that other processors + were available. + - [ #431016 ] bios: SMP struct has wrong entry count + SMP structure had the wrong entry counts +- very minor doc updates (typos, replace broken link to mtools info) +- quit when the user clicks the power button, even if they have disabled + panics. +- win32 now defaults to having mouse capture mode turned off. For new users, + it would be distressing for their mouse cursor to disappear until they + pressed F12. +- [ #428222 ] vga font not installed + added script called "install-x11-fonts" which should help people install + the VGA font on X windows systems, if it isn't already there. + +------------------------------------------------------------------------- +Changes in 1.2 (June 3, 2001): +- [ #427259 ] rombios HALT calls don't print + Fixed bios/rombios.c HALT macro so that it writes the line number of the + panic to the PANIC_PORT (port 0x400) and then does NOT do a halt + instruction. Also changed iodev/unmapped.cc so that the line number written + to PANIC_PORT is displayed as a BX_PANIC message. Because the HALT + macro now triggers the normal panic behavior, it can be controlled by + the bochsrc. +- [ #429016 ] crash if no hard drive + rombios used to call HALT macro if no hard drive was found. Now it only + calls HALT if a hard drive has an illegal geometry. +- [ #425388 ] include source for simple disk img tool + [ #428478 ] mkimg tool creates image 1 byte too big + Added bximage tool, which makes empty floppy and hard disk images. + It is now included in the top level Makefile, so it will get built + by default on all platforms. +- [ #426036 ] eth_fbsd.cc compile problem on solaris26 + added configure test so that "configure --enable-ne2000" only + includes the Berkeley Packet Filter code (eth_fbsd) if the header + file can be found. If you don't have BPF the ne2000 + will not actually move packets, but at least it will compile clean now. +- [ #428214 ] 1.2.pre1 need documentation for binaries + Write windows and linux specific documentation to be installed in + binary releases. +- [ #429258 ] disable RESET for version 1.2 + Since soft reset was not completely working, I reverted the reset patch. + Now it does panics on reset instead of trying to reboot, as the old + bochs versions did. +- [ #428222 ] Should the linux RPM install vga font? + now font/vga.pcf will be installed in the RPM package +- [ #429020 ] stop renaming the BIOS!!! + new BIOS changes are now in BIOS-bochs-latest, instead of a BIOS + whose name changes every time we change anything! To help distinguish + different BIOS versions, the BIOS now prints its RCS Id into the + log file. +- [ #428625 ] compile problem if SHOW_IPS is on + removed extra paren that broke SHOW_IPS +- [ #428219 ] PCI doesn't compile with SMF=1 +- [ #429375 ] pthreads detection broken +- [ #429073 ] configure: if no X11, makes bad config +- [ #429229 ] install current .bochsrc in binary rels +- install Tim's man pages on linux RPM +- BIOS prints messages in log in case of boot failure +- rewrote instructions for compiling in win32 (win32.txt) +- fixed link in HTML changelog.html to point to the real sources on SF. +- added missing LOG_THIS definition to gui/nogui.cc and gui/rfb.cc +- added additional check for null pointer in debugger exit routine +- added diskd to .bochsrc + +------------------------------------------------------------------------- +Changes in version 1.2-pre1 (May 25, 2001): +- major cleanup of .bochsrc +- major cleanup of stderr output: prints bochs version information when + starting, and at the end it tries to print the message that caused + bochs to quit. +- two hard disk support (diskd). At present, you cannot have two + hard drives and a cdrom at the same time, because there is only + one IDE controller with two channels. +- split hard disk support allows different partitions to be stored in + different image files +- two new GUI choices: term mode and RFB mode. Term is a text-only + interface, and RFB creates a server that can be accessed using + the AT&T VNC viewer. +- now Bochs can simulate an SMP machine, if you configure with + --enable-processors=N. Configuring more than one processor has + a major performance impact, so the default is 1 processor. + See SMP documentation for more details. +- to make SMP work, bx_mem and bx_cpu have been replaced with + bx_mem_array[] and bx_cpu_array[]. The cpus are referenced through + the BX_CPU(n) macro and memories through the BX_MEM(n). Normal + mode has one cpu and one memory, SMP mode has multiple cpu's and + one memory, cosimulation mode has multiple cpus and multiple memories. +- use --enable-cpu-level=6 to make Bochs claim to be a Pentium Pro. + The only feature that requires CPU level 6 is apic support. +- new logging system by Todd Fries, which has 4 levels of event + severity (panic, error, info, debug). There are new .bochsrc + options that control what action to take when a + panic/error/info/debug event occurs. +- now searches for .bochsrc, bochsrc, bochsrc.txt, and (on unix only) + $HOME/.bochsrc. +- use GNU readline library if --enable-debugger is on, as long as readline + can be found on the machine +- configure checks for existence strtoull and strtouq. if neither exists, + Bochs uses its own implementation +- applied patches from Cliff Hones to fix up the + rombios. This includes many improvements, which you can list by + doing "cvs log -r 1.6 bios/rombios.c" or looking at cvsweb. +- added suggested geometries of larger disks to the documentation +- this is the first release to have official binary packages for win32 + and Linux. There is a new "make rpm" in the top-level Makefile which + will create an RPM of the current bochs directory. To use this, + become root and type "configure; make rpm". +- applied some FreeBSD patches from Maxim Sobolev (cdrom and serial). + +------------------------------------------------------------------------- +Changes in version 1.1.2 (bugfix3, May 16, 2001): +- updated Elpin VGA BIOS to version 2.40, and changed pointer in .bochsrc +- fixed .conf.x86 script so that it uses c++ instead of egcs for C++ files +- now Makefile targets that recurse into subdirectories use double colons, + so that it will always recurse into subdirectories. Now a single make + command should notice a modified source file in a subdir. +- fixed bug in bx_panic. If BX_PANIC_IS_FATAL==0 and a (non-fatal) panic + occurs, it used to call bx_atexit() and then return. It should never + call bx_atexit, which starts to shut down the simulator, unless it's + really going to quit! +- support 2.88 MB floppy disks +- since dataseghack is checked in as non-executable, invoke it with + "csh dataseghack" +- double fault patch from Thomas Petazzoni , + sourceforge patch #423726. +- removed -fno-builtin from fpu makefiles +- redefine u_char, u_short, etc. in order to not conflict with system + definitions of these same types. +- in cdrom.cc, remove the extern "C" { } structure around some of the + header files. This is no longer necessary. +- do not panic on hard disk command 0x1f2 (read sector count) +- in keyboard.cc: + - apply Todd Fries' reset patch + - recognize most of the "Grey" insert/delete/home/end/etc. keys the + same as keypad keys. + - removed panic on "kbd_ctrl_to_kbd(): got value of 0x??" + - implement mouse command 0xf6 (set defaults) +- apply Suboner@aol.com's Xwindows timing patch from + http://sourceforge.net/tracker/index.php?func=detail&aid=418730&group_id=12580&atid=312580 +- remove all patches from patches subdir which have already been applied. + The remaining ones are under consideration but not applied. + +------------------------------------------------------------------------- +Changes in version 1.1.1 (bugfix2, April 9, 2001): +- in soundwin.cc, arg 3 should be typecast to LPWAVEFORMATEX +- in fpu_entry.c, Bryce mistyped his own initials! +- in configure.in and configure, define good defaults for VC++ + #define BX_64BIT_CONSTANTS_USE_LL 0 + #define inline __inline + #define BX_NO_EMPTY_STRUCTS 1 + #define BX_NO_ATTRIBUTES 1 + #define BX_HAVE_HASH_MAP 0 +- in config.h.in, fixed typo in #error message + +------------------------------------------------------------------------- +Changes in version 1.1 (bugfix1, April 6, 2001): + +(FIXED, patch #414360: update copyrights) +update headers. Change copyright to 2001, replace config.h.in header with +the standard mandrake header that every other file uses. + +(FIXED, patch #414356: inlines) +make macro to replace inline and static/extern keywords. Then make +define the macro appropriately based on configure. + +(FIXED: patch #414234: macos-no-strdup) +--with-macos should force HAVE_STRDUP=0. + +(FIXED, patch #403027: Fix mouse bugs in Linux and BSD) +Linux and BSD (maybe others) cause panic in mouse code. + +(FIXED, patch #413851: const64bit patch) +VC++ does not allow "LL" after 64-bit constant. + +(FIXED, patch #413859: fabs symbol conflict) +fpu code contains fabs, which conflicts with math library fabs. + +(FIXED, patch #403004: Implement aborts on a few SET FEATURE commands...) +Implement aborts on a few SET FEATURE commands for ATA. + +(FIXED, patch #402991: Update to iodev/vga.cc to add 3c3h read support) +Implement VGA enable register, at 0x3c3. + +(FIXED, patch #403027: Fix mouse bugs in Linux and BSD) +Mouse panic in linux/BSD: +KBD: io write 0x64: command = 0xD3(write mouse outb) + +(FIXED, patch #414229: panic-is-fatal) +Allow user to decide if panic is fatal, or just a warning + +(FIXED, patch #414230: sun-cdrom) +Support Sun CDROM + +(FIXED, patch #413574: portable1) +there are cases where a pointer is cast to a 32-bit int, +then later cast to a pointer and dereferenced, which crashes any 64-bit +machine. + +(FIXED, patch #413574: portable1) +some machines have no snprintf or strtoull. include a replacement function +when needed. + +(FIXED, patch #413574: portable1) +Some compilers don't allow "typedef struct { } foo;" + +(FIXED, patch #413574: portable1) +Some people don't have hash_map.h, used in dbg_main.cc. Disable this code +if hash_map.h not found. + +(FIXED, patch #413574: portable1) +Some compilers can't handle labels at the end of a block, as in + void main () { /*code*/ label: } + +(FIXED, patch #413574: portable1) +Most compilers can't handle __attribute__. Use macro to define it away. + +(FIXED, patch #413574: portable1) +if --enable-debugger, turn on --enable-disasm too. + +(FIXED, patch #413574: portable1) +ome compilers can't handle any chars after an #endif + +(FIXED, patch #413574: portable1) +wrong type arg1 of bx_dbg_watch and bx_dbg_unwatch. The code in +lexer.l was calling it with integers (not booleans) + +(FIXED, patch #413574: portable1) +in fpu code, "setcc" macro was implemented with braces inside parens, +which some compilers don't understand. + +(FIXED, patch #413574: portable1) +in fpu_entry.c, FPU_load_int32 was consistently called with arg1 of +type (s32 *), but should be (u32 *) + +(FIXED, patch #413574: portable1) +comment out sigcontext structure in fpu/stubs/asm/sigcontext.h because +it conflicted with sigcontext of other machines. This struct was never +used by bochs anyway. + +(FIXED, patch #414046: portable2) +move definition of missing library functions into osdep.h and osdep.cc, +include contents of macutils*. + +(FIXED, patch #414061: win32-rawcd) +CDROM drive letter for WIN32 should not be hardcoded. + +(FIXED, patch #414060: win32-rawfloppy) +Bypass fstat when opening WIN32 raw floppy disk. + +(FIXED, patch #414226: pit-panic) +WinME install dies with panic: +bochs: panic, pit: outp(43h): comm Bh, mode 00, bcd 00 unhandled +I think I had a similar problem. All three timers should support modes +0, 2, and 3. Other modes really aren't implemented. diff --git a/bochs/COPYING b/bochs/COPYING new file mode 100644 index 00000000..654ead3a --- /dev/null +++ b/bochs/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/bochs/Makefile.in b/bochs/Makefile.in new file mode 100644 index 00000000..6930d9bf --- /dev/null +++ b/bochs/Makefile.in @@ -0,0 +1,726 @@ +# Copyright (C) 2001 The Bochs Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#################################################### +# NOTE: To be compatibile with nmake (microsoft vc++) please follow +# the following rules: +# use $(VAR) not ${VAR} + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +srcdir = @srcdir@ +VPATH = @srcdir@ +bindir = @bindir@ +libdir = @libdir@ +plugdir = @libdir@/bochs/plugins +datarootdir = @datarootdir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +man5dir = $(mandir)/man5 +docdir = $(datarootdir)/doc/bochs +sharedir = $(datarootdir)/bochs +top_builddir = . +top_srcdir = $(srcdir) + +DESTDIR = + +VERSION=@VERSION@ +VER_STRING=@VER_STRING@ +REL_STRING=@REL_STRING@ +MAN_PAGE_1_LIST=bochs bximage bxcommit bochs-dlx +MAN_PAGE_5_LIST=bochsrc +INSTALL_LIST_SHARE=bios/BIOS-bochs-* bios/VGABIOS* @INSTALL_LIST_FOR_PLATFORM@ +INSTALL_LIST_DOC=CHANGES COPYING README TODO +INSTALL_LIST_BIN=bochs@EXE@ bximage@EXE@ bxcommit@EXE@ +INSTALL_LIST_BIN_OPTIONAL=bochsdbg@EXE@ +INSTALL_LIST_WIN32=$(INSTALL_LIST_SHARE) $(INSTALL_LIST_DOC) $(INSTALL_LIST_BIN) $(INSTALL_LIST_BIN_OPTIONAL) niclist@EXE@ +INSTALL_LIST_MACOSX=$(INSTALL_LIST_SHARE) $(INSTALL_LIST_DOC) bochs.scpt +# for win32 and macosx, these files get renamed to *.txt in install process +TEXT_FILE_LIST=README CHANGES COPYING TODO VGABIOS-elpin-LICENSE VGABIOS-lgpl-README +CP=cp +CAT=cat +RM=rm +MV=mv +LN_S=ln -sf +DLXLINUX_TAR=dlxlinux4.tar.gz +DLXLINUX_TAR_URL=http://bochs.sourceforge.net/guestos/$(DLXLINUX_TAR) +DLXLINUX_ROMFILE=BIOS-bochs-latest +GUNZIP=gunzip +WGET=@WGET@ +SED=sed +MKDIR=mkdir +RMDIR=rmdir +TAR=tar +CHMOD=chmod +# the GZIP variable is reserved by gzip program +GZIP_BIN=gzip -9 +GUNZIP=gunzip +ZIP=zip +UNIX2DOS=unix2dos +LIBTOOL=@LIBTOOL@ +DLLTOOL=dlltool +RC_CMD=@RC_CMD@ + +@SUFFIX_LINE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +SHELL = /bin/sh + +@SET_MAKE@ + +CC = @CC@ +CXX = @CXX@ +CFLAGS = @CFLAGS@ @GUI_CFLAGS@ $(MCH_CFLAGS) $(FLA_FLAGS) @DEFINE_PLUGIN_PATH@ -DBX_SHARE_PATH='"$(sharedir)"' +CXXFLAGS = @CXXFLAGS@ @GUI_CXXFLAGS@ $(MCH_CFLAGS) $(FLA_FLAGS) @DEFINE_PLUGIN_PATH@ -DBX_SHARE_PATH='"$(sharedir)"' + +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +# To compile with readline: +# linux needs just -lreadline +# solaris needs -lreadline -lcurses +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +XPM_LIB = @XPM_LIB@ +GUI_LINK_OPTS_X = $(X_LIBS) $(X_PRE_LIBS) -lX11 $(XPM_LIB) -lXrandr +GUI_LINK_OPTS_SDL = `sdl-config --cflags --libs` +GUI_LINK_OPTS_SVGA = -lvga -lvgagl +GUI_LINK_OPTS_BEOS = -lbe +GUI_LINK_OPTS_RFB = @RFB_LIBS@ +GUI_LINK_OPTS_AMIGAOS = +GUI_LINK_OPTS_WIN32 = -luser32 -lgdi32 -lcomdlg32 -lcomctl32 -lwsock32 -lshell32 +GUI_LINK_OPTS_WIN32_VCPP = user32.lib gdi32.lib winmm.lib \ + comdlg32.lib comctl32.lib wsock32.lib advapi32.lib shell32.lib +GUI_LINK_OPTS_MACOS = +GUI_LINK_OPTS_CARBON = -framework Carbon +GUI_LINK_OPTS_NOGUI = +GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@ +GUI_LINK_OPTS_WX = @GUI_LINK_OPTS_WX@ +GUI_LINK_OPTS = @GUI_LINK_OPTS@ @DEVICE_LINK_OPTS@ +RANLIB = @RANLIB@ + +CFLAGS_CONSOLE = @CFLAGS@ $(MCH_CFLAGS) $(FLA_FLAGS) +CXXFLAGS_CONSOLE = @CXXFLAGS@ $(MCH_CFLAGS) $(FLA_FLAGS) +BXIMAGE_LINK_OPTS = @BXIMAGE_LINK_OPTS@ + +BX_INCDIRS = -I. -I$(srcdir)/. -I@INSTRUMENT_DIR@ -I$(srcdir)/@INSTRUMENT_DIR@ + +#SUBDIRS = iodev bx_debug + +#all install uninstall: config.h# +# for subdir in $(SUBDIRS); do # +# echo making $@ in $$subdir; # +# ($(MAKE) -C $$subdir $(MDEFINES) $@) || exit 1; # +# done# + + + +# gnu flags for clean up +#CFLAGS = -ansi -O -g -Wunused -Wuninitialized + + +NONINLINE_OBJS = \ + logio.o \ + main.o \ + config.o \ + load32bitOShack.o \ + pc_system.o \ + osdep.o \ + plugin.o \ + crc.o \ + @EXTRA_BX_OBJS@ + +EXTERN_ENVIRONMENT_OBJS = \ + main.o \ + config.o \ + load32bitOShack.o \ + pc_system.o + +DEBUGGER_LIB = bx_debug/libdebug.a +DISASM_LIB = disasm/libdisasm.a +INSTRUMENT_LIB = @INSTRUMENT_DIR@/libinstrument.a +FPU_LIB = fpu/libfpu.a +READLINE_LIB = @READLINE_LIB@ +EXTRA_LINK_OPTS = @EXTRA_LINK_OPTS@ + +GDBSTUB_OBJS = gdbstub.o + +BX_OBJS = @NONINLINE_VAR@ + +BX_INCLUDES = bochs.h config.h osdep.h + + +.@CPP_SUFFIX@.o: + $(CXX) @DASH@c $(BX_INCDIRS) $(CXXFLAGS) @CXXFP@$< @OFP@$@ +.c.o: + $(CC) @DASH@c $(BX_INCDIRS) $(CFLAGS) $(FPU_FLAGS) $< @OFP@$@ + + +all: @PRIMARY_TARGET@ @PLUGIN_TARGET@ bximage@EXE@ bxcommit@EXE@ @BUILD_DOCBOOK_VAR@ + +@EXTERNAL_DEPENDENCY@ + +bochs@EXE@: @IODEV_LIB_VAR@ @DEBUGGER_VAR@ \ + cpu/libcpu.a memory/libmemory.a ../core/libfail.a gui/libgui.a \ + @DISASM_VAR@ @INSTRUMENT_VAR@ $(BX_OBJS) \ + $(SIMX86_OBJS) @FPU_VAR@ @GDBSTUB_VAR@ @PLUGIN_VAR@ + @LINK@ @EXPORT_DYNAMIC@ $(BX_OBJS) $(SIMX86_OBJS) \ + @IODEV_LIB_VAR@ @DEBUGGER_VAR@ cpu/libcpu.a memory/libmemory.a ../core/libfail.a gui/libgui.a \ + @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \ + @GDBSTUB_VAR@ @FPU_VAR@ \ + @NONPLUGIN_GUI_LINK_OPTS@ \ + $(MCH_LINK_FLAGS) \ + $(SIMX86_LINK_FLAGS) \ + $(READLINE_LIB) \ + $(EXTRA_LINK_OPTS) \ + $(LIBS) + +# Special make target for cygwin/mingw using dlltool instead of +# libtool. This creates a .DEF file, and exports file, an import library, +# and then links bochs.exe with the exports file. +.win32_dll_plugin_target: @IODEV_LIB_VAR@ @DEBUGGER_VAR@ \ + cpu/libcpu.a memory/libmemory.a ../core/libfail.a gui/libgui.a \ + @DISASM_VAR@ @INSTRUMENT_VAR@ $(BX_OBJS) \ + $(SIMX86_OBJS) @FPU_VAR@ @GDBSTUB_VAR@ @PLUGIN_VAR@ + $(DLLTOOL) --export-all-symbols --output-def bochs.def \ + $(BX_OBJS) $(SIMX86_OBJS) \ + @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a ../core/libfail.a gui/libgui.a \ + @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \ + @GDBSTUB_VAR@ @FPU_VAR@ + $(DLLTOOL) --dllname bochs.exe --def bochs.def --output-lib dllexports.a + $(DLLTOOL) --dllname bochs.exe --output-exp bochs.exp --def bochs.def + $(CXX) -o bochs.exe $(CXXFLAGS) $(LDFLAGS) -export-dynamic \ + $(BX_OBJS) bochs.exp $(SIMX86_OBJS) \ + @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a ../core/libfail.a gui/libgui.a \ + @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \ + @GDBSTUB_VAR@ @FPU_VAR@ \ + $(GUI_LINK_OPTS) \ + $(MCH_LINK_FLAGS) \ + $(SIMX86_LINK_FLAGS) \ + $(READLINE_LIB) \ + $(EXTRA_LINK_OPTS) \ + $(LIBS) + touch .win32_dll_plugin_target + +bochs_plugins: + cd gui @COMMAND_SEPARATOR@ + $(MAKE) plugins + @CD_UP_ONE@ + cd iodev @COMMAND_SEPARATOR@ + $(MAKE) plugins + @CD_UP_ONE@ + +bximage@EXE@: misc/bximage.o + @LINK_CONSOLE@ $(BXIMAGE_LINK_OPTS) misc/bximage.o + +bxcommit@EXE@: misc/bxcommit.o + @LINK_CONSOLE@ misc/bxcommit.o + +niclist@EXE@: misc/niclist.o + @LINK_CONSOLE@ misc/niclist.o + +# compile with console CXXFLAGS, not gui CXXFLAGS +misc/bximage.o: $(srcdir)/misc/bximage.c $(srcdir)/iodev/hdimage.h + $(CC) @DASH@c $(BX_INCDIRS) $(CFLAGS_CONSOLE) $(srcdir)/misc/bximage.c @OFP@$@ + +misc/bxcommit.o: $(srcdir)/misc/bxcommit.c $(srcdir)/iodev/hdimage.h + $(CC) @DASH@c $(BX_INCDIRS) $(CFLAGS_CONSOLE) $(srcdir)/misc/bxcommit.c @OFP@$@ + +misc/niclist.o: $(srcdir)/misc/niclist.c + $(CC) @DASH@c $(BX_INCDIRS) $(CFLAGS_CONSOLE) $(srcdir)/misc/niclist.c @OFP@$@ + +$(BX_OBJS): $(BX_INCLUDES) + +# cannot use -C option to be compatible with Microsoft nmake +iodev/libiodev.a:: + cd iodev @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libiodev.a + @CD_UP_ONE@ + +bx_debug/libdebug.a:: + cd bx_debug @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libdebug.a + @CD_UP_ONE@ + +cpu/libcpu.a:: + cd cpu @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libcpu.a + @CD_UP_ONE@ + +memory/libmemory.a:: + cd memory @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libmemory.a + @CD_UP_ONE@ + +gui/libgui.a:: + cd gui @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libgui.a + @CD_UP_ONE@ + +disasm/libdisasm.a:: + cd disasm @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libdisasm.a + @CD_UP_ONE@ + +@INSTRUMENT_DIR@/libinstrument.a:: + cd @INSTRUMENT_DIR@ @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libinstrument.a + @CD_UP_TWO@ + +fpu/libfpu.a:: + cd fpu @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libfpu.a + @CD_UP_ONE@ + +libbochs.a: + -rm -f libbochs.a + ar rv libbochs.a $(EXTERN_ENVIRONMENT_OBJS) + $(RANLIB) libbochs.a + +libbochs_cpu.a: @DEBUGGER_VAR@ $(BX_OBJS) + -rm -f libbochs_cpu.a + ar rv libbochs_cpu.a $(BX_OBJS) + $(RANLIB) libbochs_cpu.a + +# for wxWidgets port, on win32 platform +wxbochs_resources.o: wxbochs.rc + windres $(srcdir)/wxbochs.rc -o $@ --include-dir=`@WX_CONFIG@ --prefix`/include + +# for win32 gui +win32res.o: win32res.rc bxversion.rc + $(RC_CMD)$@ $(srcdir)/win32res.rc + +##################################################################### +# Install target for all platforms. +##################################################################### + +install: all @INSTALL_TARGET@ + +##################################################################### +# Install target for win32 +# +# This is intended to be run in cygwin, since it has better scripting +# tools. +##################################################################### + +install_win32: download_dlx @INSTALL_DOCBOOK_VAR@ + -mkdir -p $(prefix) + cp obj-release/*.exe . + for i in $(INSTALL_LIST_WIN32); do if test -f $$i; then cp $$i $(prefix); else cp $(srcdir)/$$i $(prefix); fi; done + cp $(srcdir)/misc/sb16/sb16ctrl.example $(prefix)/sb16ctrl.txt + cp $(srcdir)/misc/sb16/sb16ctrl.exe $(prefix) + #cat $(srcdir)/build/win32/DOC-win32.htm | $(SED) -e 's/@VERSION@/$(VERSION)/g' > $(prefix)/DOC-win32.htm + cp $(srcdir)/.bochsrc $(prefix)/bochsrc-sample.txt + -mkdir $(prefix)/keymaps + cp $(srcdir)/gui/keymaps/*.map $(prefix)/keymaps + cat $(DLXLINUX_TAR) | (cd $(prefix) && tar xzvf -) + echo '..\bochs' > $(prefix)/dlxlinux/start.bat + dlxrc=$(prefix)/dlxlinux/bochsrc.txt; mv $$dlxrc $$dlxrc.orig && sed < $$dlxrc.orig 's/\/usr\/local\/bochs\/latest/../' > $$dlxrc && rm -f $$dlxrc.orig + mv $(prefix)/README $(prefix)/README.orig + cat $(srcdir)/build/win32/README.win32-binary $(prefix)/README.orig > $(prefix)/README + rm -f $(prefix)/README.orig + for i in $(TEXT_FILE_LIST); do mv $(prefix)/$$i $(prefix)/$$i.txt; done + cd $(prefix); $(UNIX2DOS) *.txt */*.txt + cd $(prefix); NAME=`pwd|$(SED) 's/.*\///'`; (cd ..; $(ZIP) $$NAME.zip -r $$NAME); ls -l ../$$NAME.zip + +##################################################################### +# install target for unix +##################################################################### + +install_unix: install_bin @INSTALL_PLUGINS_VAR@ install_man install_share install_doc @INSTALL_DOCBOOK_VAR@ + +install_bin:: + for i in $(DESTDIR)$(bindir); do mkdir -p $$i && test -d $$i && test -w $$i; done + for i in $(INSTALL_LIST_BIN); do if test -f $$i; then install $$i $(DESTDIR)$(bindir); else install $(srcdir)/$$i $(DESTDIR)$(bindir); fi; done + -for i in $(INSTALL_LIST_BIN_OPTIONAL); do if test -f $$i; then install $$i $(DESTDIR)$(bindir); else install $(srcdir)/$$i $(DESTDIR)$(bindir); fi; done + +install_libtool_plugins:: + for i in $(DESTDIR)$(plugdir); do mkdir -p $$i && test -d $$i && test -w $$i; done + list=`cd gui && echo *.la`; for i in $$list; do $(LIBTOOL) --mode=install install gui/$$i $(DESTDIR)$(plugdir); done + list=`cd iodev && echo *.la`; for i in $$list; do $(LIBTOOL) --mode=install install iodev/$$i $(DESTDIR)$(plugdir); done + $(LIBTOOL) --finish $(DESTDIR)$(plugdir) + +install_dll_plugins:: + for i in $(DESTDIR)$(plugdir); do mkdir -p $$i && test -d $$i && test -w $$i; done + list=`cd gui && echo *.dll`; for i in $$list; do cp gui/$$i $(DESTDIR)$(plugdir); done + list=`cd iodev && echo *.dll`; for i in $$list; do cp iodev/$$i $(DESTDIR)$(plugdir); done + +install_share:: + for i in $(DESTDIR)$(sharedir); do mkdir -p $$i && test -d $$i && test -w $$i; done + for i in $(INSTALL_LIST_SHARE); do if test -f $$i; then install -m 644 $$i $(DESTDIR)$(sharedir); else install -m 644 $(srcdir)/$$i $(DESTDIR)$(sharedir); fi; done + -mkdir $(DESTDIR)$(sharedir)/keymaps + for i in $(srcdir)/gui/keymaps/*.map; do install -m 644 $$i $(DESTDIR)$(sharedir)/keymaps/; done + +install_doc:: + for i in $(DESTDIR)$(docdir); do mkdir -p $$i && test -d $$i && test -w $$i; done + for i in $(INSTALL_LIST_DOC); do if test -f $$i; then install -m 644 $$i $(DESTDIR)$(docdir); else install -m 644 $(srcdir)/$$i $(DESTDIR)$(docdir); fi; done + $(RM) -f $(DESTDIR)$(docdir)/README + $(CAT) $(srcdir)/build/linux/README.linux-binary $(srcdir)/README > $(DESTDIR)$(docdir)/README + install -m 644 $(srcdir)/.bochsrc $(DESTDIR)$(docdir)/bochsrc-sample.txt + + +build_docbook:: + cd doc/docbook; make + +dl_docbook:: + cd doc/docbook; make dl_docs + +install_docbook: build_docbook + cd doc/docbook; make install + +install_man:: + -mkdir -p $(DESTDIR)$(man1dir) + -mkdir -p $(DESTDIR)$(man5dir) + for i in $(MAN_PAGE_1_LIST); do cat $(srcdir)/doc/man/$$i.1 | $(SED) 's/@version@/$(VERSION)/g' | $(GZIP_BIN) -c > $(DESTDIR)$(man1dir)/$$i.1.gz; chmod 644 $(DESTDIR)$(man1dir)/$$i.1.gz; done + for i in $(MAN_PAGE_5_LIST); do cat $(srcdir)/doc/man/$$i.5 | $(GZIP_BIN) -c > $(DESTDIR)$(man5dir)/$$i.5.gz; chmod 644 $(DESTDIR)$(man5dir)/$$i.5.gz; done + +download_dlx: $(DLXLINUX_TAR) + +$(DLXLINUX_TAR): + $(RM) -f $(DLXLINUX_TAR) + $(WGET) $(DLXLINUX_TAR_URL) + test -f $(DLXLINUX_TAR) + +unpack_dlx: $(DLXLINUX_TAR) + rm -rf dlxlinux + $(GUNZIP) -c $(DLXLINUX_TAR) | $(TAR) -xvf - + test -d dlxlinux + (cd dlxlinux; $(MV) bochsrc.txt bochsrc.txt.orig; $(SED) -e "s/1\.1\.2/$(VERSION)/g" -e 's,/usr/local/bochs/latest,$(prefix)/share/bochs,g' < bochsrc.txt.orig > bochsrc.txt; rm -f bochsrc.txt.orig) + +install_dlx: + $(RM) -rf $(DESTDIR)$(sharedir)/dlxlinux + cp -r dlxlinux $(DESTDIR)$(sharedir)/dlxlinux + $(CHMOD) 755 $(DESTDIR)$(sharedir)/dlxlinux + $(GZIP_BIN) $(DESTDIR)$(sharedir)/dlxlinux/hd10meg.img + $(CHMOD) 644 $(DESTDIR)$(sharedir)/dlxlinux/* + for i in bochs-dlx; do cp $(srcdir)/build/linux/$$i $(DESTDIR)$(bindir)/$$i; $(CHMOD) 755 $(DESTDIR)$(bindir)/$$i; done + +uninstall:: + $(RM) -rf $(DESTDIR)$(sharedir) + $(RM) -rf $(DESTDIR)$(docdir) + $(RM) -rf $(DESTDIR)$(libdir)/bochs + for i in bochs bximage bxcommit bochs-dlx; do rm -f $(DESTDIR)$(bindir)/$$i; done + for i in $(MAN_PAGE_1_LIST); do $(RM) -f $(man1dir)/$$i.1.gz; done + for i in $(MAN_PAGE_5_LIST); do $(RM) -f $(man5dir)/$$i.5.gz; done + +VS2008_WORKSPACE_ZIP=build/win32/vs2008ex-workspace.zip +VS2008_WORKSPACE_FILES=vs2008/bochs.sln vs2008/*.vcproj + +vs2008workspace: + zip $(VS2008_WORKSPACE_ZIP) $(VS2008_WORKSPACE_FILES) + +######## +# the win32_snap target is used to create a ZIP of bochs sources configured +# for VC++. This ZIP is stuck on the website every once in a while to make +# it easier for VC++ users to compile bochs. First, you should +# run "sh .conf.win32-vcpp" to configure the source code, then do +# "make win32_snap" to unzip the workspace files and create the ZIP. +######## +win32_snap: + unzip $(VS2008_WORKSPACE_ZIP) + $(MAKE) zip + +tar: + NAME=`pwd|$(SED) 's/.*\///'`; (cd ..; $(RM) -f $$NAME.zip; tar cf - $$NAME | $(GZIP_BIN) > $$NAME.tar.gz); ls -l ../$$NAME.tar.gz + +zip: + NAME=`pwd|$(SED) 's/.*\///'`; (cd ..; $(RM) -f $$NAME-msvc-src.zip; $(ZIP) $$NAME-msvc-src.zip -r $$NAME -x \*CVS\* -x \*.cvsignore ); ls -l ../$$NAME-msvc-src.zip + +clean: + @RMCOMMAND@ *.o + @RMCOMMAND@ *.a + @RMCOMMAND@ bochs + @RMCOMMAND@ bochs.exe + @RMCOMMAND@ bximage + @RMCOMMAND@ bximage.exe + @RMCOMMAND@ bxcommit + @RMCOMMAND@ bxcommit.exe + @RMCOMMAND@ niclist + @RMCOMMAND@ niclist.exe + @RMCOMMAND@ bochs.out + @RMCOMMAND@ bochsout.txt + @RMCOMMAND@ bochs.exp + @RMCOMMAND@ bochs.def + @RMCOMMAND@ bochs.scpt + @RMCOMMAND@ -rf bochs.app + @RMCOMMAND@ -rf .libs + @RMCOMMAND@ .win32_dll_plugin_target + +local-dist-clean: clean + @RMCOMMAND@ config.h config.status config.log config.cache + @RMCOMMAND@ .dummy `find . -name '*.dsp' -o -name '*.dsw' -o -name '*.opt' -o -name '.DS_Store'` + @RMCOMMAND@ bxversion.h build/linux/bochs-dlx _rpm_top *.rpm + @RMCOMMAND@ build/win32/nsis/Makefile build/win32/nsis/bochs.nsi + @RMCOMMAND@ build/macosx/Info.plist build/macosx/script_compiled.rsrc + @RMCOMMAND@ libtool + @RMCOMMAND@ ltdlconf.h + +all-clean: clean + cd iodev @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd bx_debug @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd cpu @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd memory @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd gui @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd disasm @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd @INSTRUMENT_DIR@ @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_TWO@ + cd misc @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd fpu @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ + cd doc/docbook @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_TWO@ + cd host/linux/pcidev @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_THREE@ + +dist-clean: local-dist-clean + cd iodev @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd bx_debug @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd bios @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd cpu @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd memory @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd gui @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd disasm @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd @INSTRUMENT_DIR@ @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_TWO@ + cd misc @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd fpu @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ + cd doc/docbook @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_TWO@ + cd host/linux/pcidev @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_THREE@ + @RMCOMMAND@ Makefile + +########################################### +# Build app on MacOS X +########################################### +MACOSX_STUFF=build/macosx +MACOSX_STUFF_SRCDIR=$(srcdir)/$(MACOSX_STUFF) +APP=bochs.app +APP_PLATFORM=MacOS +SCRIPT_EXEC=bochs.scpt +SCRIPT_DATA=$(MACOSX_STUFF_SRCDIR)/script.data +SCRIPT_R=$(MACOSX_STUFF_SRCDIR)/script.r +SCRIPT_APPLESCRIPT=$(MACOSX_STUFF_SRCDIR)/bochs.applescript +SCRIPT_COMPILED_RSRC=$(MACOSX_STUFF)/script_compiled.rsrc +REZ=/Developer/Tools/Rez +CPMAC=/Developer/Tools/CpMac +RINCLUDES=/System/Library/Frameworks/Carbon.framework/Libraries/RIncludes +REZ_ARGS=-append -i $RINCLUDES -d SystemSevenOrLater=1 -useDF +STANDALONE_LIBDIR=`pwd`/$(APP)/Contents/$(APP_PLATFORM)/lib +OSACOMPILE=/usr/bin/osacompile +SETFILE=/Developer/Tools/SetFile + +# On a MacOS X machine, you run rez, osacompile, and setfile to +# produce the script executable, which has both a data fork and a +# resource fork. Ideally, we would just recompile the whole +# executable at build time, but unfortunately this cannot be done on +# the SF compile farm through an ssh connection because osacompile +# needs to be run locally for some reason. Solution: If the script +# sources are changed, rebuild the executable on a MacOSX machine, +# split it into its data and resource forks and check them into CVS +# as separate files. Then at release time, all that's left to do is +# put the data and resource forks back together to make a working script. +# (This can be done through ssh.) +# +# Sources: +# 1. script.r: resources for the script +# 2. script.data: binary data for the script +# 3. bochs.applescript: the source of the script +# +# NOTE: All of this will fail if you aren't building on an HFS+ +# filesystem! On the SF compile farm building in your user directory +# will fail, while doing the build in /tmp will work ok. + +# check if this filesystem supports resource forks at all +test_hfsplus: + $(RM) -rf test_hfsplus + echo data > test_hfsplus + # if you get "Not a directory", then this filesystem doesn't support resources + echo resource > test_hfsplus/rsrc + # test succeeded + $(RM) -rf test_hfsplus + +# Step 1 (must be done locally on MacOSX, only when sources change) +# Compile and pull out just the resource fork. The resource fork is +# checked into CVS as script_compiled.rsrc. Note that we don't need +# to check in the data fork of tmpscript because it is identical to the +# script.data input file. +$(SCRIPT_COMPILED_RSRC): $(SCRIPT_R) $(SCRIPT_APPLESCRIPT) + $(RM) -f tmpscript + $(CP) -f $(SCRIPT_DATA) tmpscript + $(REZ) -append $(SCRIPT_R) -o tmpscript + $(OSACOMPILE) -o tmpscript $(SCRIPT_APPLESCRIPT) + $(CP) tmpscript/rsrc $(SCRIPT_COMPILED_RSRC) + $(RM) -f tmpscript + +# Step 2 (can be done locally or remotely on MacOSX) +# Combine the data fork and resource fork, and set attributes. +$(SCRIPT_EXEC): $(SCRIPT_DATA) $(SCRIPT_COMPILED_RSRC) + rm -f $(SCRIPT_EXEC) + $(CP) $(SCRIPT_DATA) $(SCRIPT_EXEC) + if test ! -f $(SCRIPT_COMPILED_RSRC); then $(CP) $(srcdir)/$(SCRIPT_COMPILED_RSRC) $(SCRIPT_COMPILED_RSRC); fi + $(CP) $(SCRIPT_COMPILED_RSRC) $(SCRIPT_EXEC)/rsrc + $(SETFILE) -t "APPL" -c "aplt" $(SCRIPT_EXEC) + +$(APP)/.build: bochs test_hfsplus $(SCRIPT_EXEC) + rm -f $(APP)/.build + $(MKDIR) -p $(APP) + $(MKDIR) -p $(APP)/Contents + $(CP) -f $(MACOSX_STUFF)/Info.plist $(APP)/Contents + $(CP) -f $(MACOSX_STUFF_SRCDIR)/pbdevelopment.plist $(APP)/Contents + echo -n "APPL????" > $(APP)/Contents/PkgInfo + $(MKDIR) -p $(APP)/Contents/$(APP_PLATFORM) + $(CP) bochs $(APP)/Contents/$(APP_PLATFORM) + $(MKDIR) -p $(APP)/Contents/Resources + $(REZ) $(REZ_ARGS) $(MACOSX_STUFF_SRCDIR)/bochs.r -o $(APP)/Contents/Resources/bochs.rsrc + $(CP) -f $(MACOSX_STUFF_SRCDIR)/bochs-icn.icns $(APP)/Contents/Resources + ls -ld $(APP) $(SCRIPT_EXEC) $(SCRIPT_EXEC)/rsrc + touch $(APP)/.build + +$(APP)/.build_plugins: $(APP)/.build bochs_plugins + rm -f $(APP)/.build_plugins + $(MKDIR) -p $(STANDALONE_LIBDIR); + list=`cd gui && echo *.la`; for i in $$list; do $(LIBTOOL) cp gui/$$i $(STANDALONE_LIBDIR); done; + list=`cd iodev && echo *.la`; for i in $$list; do $(LIBTOOL) cp iodev/$$i $(STANDALONE_LIBDIR); done; + $(LIBTOOL) --finish $(STANDALONE_LIBDIR); + touch $(APP)/.build_plugins + +install_macosx: all download_dlx install_man @INSTALL_DOCBOOK_VAR@ + -mkdir -p $(DESTDIR)$(sharedir) + for i in $(INSTALL_LIST_MACOSX); do if test -e $$i; then $(CPMAC) -r $$i $(DESTDIR)$(sharedir); else $(CPMAC) -r $(srcdir)/$$i $(DESTDIR)$(sharedir); fi; done + $(CPMAC) $(srcdir)/.bochsrc $(DESTDIR)$(sharedir)/bochsrc-sample.txt + -mkdir $(DESTDIR)$(sharedir)/keymaps + $(CPMAC) $(srcdir)/gui/keymaps/*.map $(DESTDIR)$(sharedir)/keymaps + cat $(DLXLINUX_TAR) | (cd $(DESTDIR)$(sharedir) && tar xzvf -) + dlxrc=$(DESTDIR)$(sharedir)/dlxlinux/bochsrc.txt; mv "$$dlxrc" "$$dlxrc.orig" && sed < "$$dlxrc.orig" 's/\/usr\/local\/bochs\/latest/../' > "$$dlxrc" && rm -f "$$dlxrc.orig" + mv $(srcdir)/README $(srcdir)/README.orig + cat $(srcdir)/build/macosx/README.macosx-binary $(srcdir)/README.orig > $(DESTDIR)$(sharedir)/README + rm -f $(DESTDIR)$(sharedir)/README.orig + $(CPMAC) $(SCRIPT_EXEC) $(DESTDIR)$(sharedir)/dlxlinux +# for i in $(TEXT_FILE_LIST); do mv $(srcdir)/$$i $(DESTDIR)$(sharedir)/$$i.txt; done + +########################################### +# BeOS make target. +# Build the binary normally, then copy the resource attributes. +########################################### +.bochs_beos_target: bochs@EXE@ + unzip $(srcdir)/build/beos/resource.zip + copyattr -t ICON BeBochs.rsrc bochs + copyattr -t MICN BeBochs.rsrc bochs + +########################################### +# dependencies generated by +# gcc -MM -I. -Iinstrument/stubs *.cc | sed -e 's/\.cc/.@CPP_SUFFIX@/g' -e 's,cpu/,cpu/,g' +########################################### +config.o: config.@CPP_SUFFIX@ bochs.h config.h osdep.h bx_debug/debug.h config.h \ + osdep.h bxversion.h gui/siminterface.h gui/paramtree.h memory/memory.h \ + pc_system.h plugin.h extplugin.h ltdl.h gui/gui.h \ + instrument/stubs/instrument.h iodev/iodev.h bochs.h param_names.h \ + param_names.h +crc.o: crc.@CPP_SUFFIX@ config.h +gdbstub.o: gdbstub.@CPP_SUFFIX@ bochs.h config.h osdep.h bx_debug/debug.h config.h \ + osdep.h bxversion.h gui/siminterface.h gui/paramtree.h memory/memory.h \ + pc_system.h plugin.h extplugin.h ltdl.h gui/gui.h \ + instrument/stubs/instrument.h param_names.h cpu/cpu.h \ + cpu/model_specific.h cpu/crregs.h cpu/descriptor.h cpu/instr.h \ + cpu/ia_opcodes.h cpu/lazy_flags.h cpu/icache.h cpu/apic.h cpu/i387.h \ + fpu/softfloat.h fpu/tag_w.h fpu/status_w.h fpu/control_w.h cpu/xmm.h \ + cpu/stack.h iodev/iodev.h bochs.h param_names.h +load32bitOShack.o: load32bitOShack.@CPP_SUFFIX@ bochs.h config.h osdep.h \ + bx_debug/debug.h config.h osdep.h bxversion.h gui/siminterface.h \ + gui/paramtree.h memory/memory.h pc_system.h plugin.h extplugin.h ltdl.h \ + gui/gui.h instrument/stubs/instrument.h param_names.h cpu/cpu.h \ + cpu/model_specific.h cpu/crregs.h cpu/descriptor.h cpu/instr.h \ + cpu/ia_opcodes.h cpu/lazy_flags.h cpu/icache.h cpu/apic.h cpu/i387.h \ + fpu/softfloat.h fpu/tag_w.h fpu/status_w.h fpu/control_w.h cpu/xmm.h \ + iodev/iodev.h bochs.h param_names.h +logio.o: logio.@CPP_SUFFIX@ bochs.h config.h osdep.h bx_debug/debug.h config.h \ + osdep.h bxversion.h gui/siminterface.h gui/paramtree.h memory/memory.h \ + pc_system.h plugin.h extplugin.h ltdl.h gui/gui.h \ + instrument/stubs/instrument.h cpu/cpu.h cpu/model_specific.h \ + cpu/crregs.h cpu/descriptor.h cpu/instr.h cpu/ia_opcodes.h \ + cpu/lazy_flags.h cpu/icache.h cpu/apic.h cpu/i387.h fpu/softfloat.h \ + fpu/tag_w.h fpu/status_w.h fpu/control_w.h cpu/xmm.h iodev/iodev.h \ + bochs.h param_names.h +main.o: main.@CPP_SUFFIX@ bochs.h config.h osdep.h bx_debug/debug.h config.h \ + osdep.h bxversion.h gui/siminterface.h gui/paramtree.h memory/memory.h \ + pc_system.h plugin.h extplugin.h ltdl.h gui/gui.h \ + instrument/stubs/instrument.h param_names.h gui/textconfig.h cpu/cpu.h \ + cpu/model_specific.h cpu/crregs.h cpu/descriptor.h cpu/instr.h \ + cpu/ia_opcodes.h cpu/lazy_flags.h cpu/icache.h cpu/apic.h cpu/i387.h \ + fpu/softfloat.h fpu/tag_w.h fpu/status_w.h fpu/control_w.h cpu/xmm.h \ + iodev/iodev.h bochs.h param_names.h +osdep.o: osdep.@CPP_SUFFIX@ bochs.h config.h osdep.h bx_debug/debug.h config.h \ + osdep.h bxversion.h gui/siminterface.h gui/paramtree.h memory/memory.h \ + pc_system.h plugin.h extplugin.h ltdl.h gui/gui.h \ + instrument/stubs/instrument.h +pc_system.o: pc_system.@CPP_SUFFIX@ bochs.h config.h osdep.h bx_debug/debug.h \ + config.h osdep.h bxversion.h gui/siminterface.h gui/paramtree.h \ + memory/memory.h pc_system.h plugin.h extplugin.h ltdl.h gui/gui.h \ + instrument/stubs/instrument.h cpu/cpu.h cpu/model_specific.h \ + cpu/crregs.h cpu/descriptor.h cpu/instr.h cpu/ia_opcodes.h \ + cpu/lazy_flags.h cpu/icache.h cpu/apic.h cpu/i387.h fpu/softfloat.h \ + fpu/tag_w.h fpu/status_w.h fpu/control_w.h cpu/xmm.h iodev/iodev.h \ + bochs.h param_names.h +plex86-interface.o: plex86-interface.@CPP_SUFFIX@ bochs.h config.h osdep.h \ + bx_debug/debug.h config.h osdep.h bxversion.h gui/siminterface.h \ + gui/paramtree.h memory/memory.h pc_system.h plugin.h extplugin.h ltdl.h \ + gui/gui.h instrument/stubs/instrument.h plex86-interface.h \ + plex86/plex86.h plex86/descriptor.h +plugin.o: plugin.@CPP_SUFFIX@ bochs.h config.h osdep.h bx_debug/debug.h config.h \ + osdep.h bxversion.h gui/siminterface.h gui/paramtree.h memory/memory.h \ + pc_system.h plugin.h extplugin.h ltdl.h gui/gui.h \ + instrument/stubs/instrument.h iodev/iodev.h bochs.h param_names.h diff --git a/bochs/PARAM_TREE.txt b/bochs/PARAM_TREE.txt new file mode 100644 index 00000000..50225323 --- /dev/null +++ b/bochs/PARAM_TREE.txt @@ -0,0 +1,267 @@ +$Id$ + +Starting from Bochs 2.3 the parameters are organized in a tree structure +instead of a huge flat list. The parameter tree was required for implementing +the save/restore feature, and it gives access to the device state from within +the debugger. +-Volker + +Current organization of parameters in the tree + +general + config_interface + start_mode + benchmark + restore + restore_path + debug_running + +cpu + n_processors + n_cores + n_threads + ips + quantum + reset_on_triple_fault + msrs + +cpuid + cpuid_limit_winnt + stepping + vendor_string + brand_string + mmx + sep + sse + aes + movbe + xsave + xapic + 1g_pages + pcid + fsgsbase + mwait + mwait_is_nop + +memory + standard + ram + size + rom + path + address + vgarom + path + optrom + 0 + path + addr + 1 + path + addr + 2 + path + addr + 3 + path + addr + optram + 0 + path + addr + 1 + path + addr + 2 + path + addr + 3 + path + addr + +clock_cmos + clock_sync + time0 + cmosimage + enabled + path + rtc_init + +pci + i440fx_support + slot + 1 + 2 + 3 + 4 + 5 + pcidev + vendor + device + +display + display_library + displaylib_options + private_colormap + fullscreen + screenmode + vga_extension + vga_update_interval + +keyboard_mouse + keyboard + type + serial_delay + paste_delay + use_mapping + keymap + user_shortcut + mouse + type + enabled + +boot_params + boot_drive1 + boot_drive2 + boot_drive3 + floppy_sig_check + load32bitos + which + path + iolog + initrd + +floppy + 0 + devtype + path + type + readonly + status + 1 + devtype + path + type + readonly + status + +ata + 0 + resources + enabled + ioaddr1 + ioaddr2 + irq + master + present + type + path + mode + journal + cylinders + heads + spt + status + model + biosdetect + translation + slave + (same options as master) + 1 + (same options as ata.0) + 2 + (same options as ata.0) + 3 + (same options as ata.0) + +ports + serial + 1 + enabled + mode + dev + 2 + (same options as ports.serial.1) + 3 + (same options as ports.serial.1) + 4 + (same options as ports.serial.1) + parallel + 1 + enabled + outfile + 2 + (same options as ports.parallel.1) + usb + uhci + enabled + port1 + device + options + port2 + device + options + ohci + (same options as ports.usb.uhci) + +network + ne2k + enabled + ioaddr + irq + macaddr + ethmod + ethdev + script + pnic + enabled + macaddr + ethmod + ethdev + script + +sound + sb16 + enabled + midifile + wavefile + logfile + midimode + wavemode + loglevel + dmatimer + +misc + text_snapshot_check + gdbstub + port + text_base + data_base + bss_base + user_plugin + 1 ... 8 + +log + filename + prefix + debugger_filename + +menu + disk + disk_win32 + memory + runtime + cdrom + usb + misc + +bochs + (subtree containing Bochs state) + +wxdebug + (special subtree for wxBochs debugger) + +user + (subtree for user-defined options) + +(updated Jan 16, 2011 by vruppert) diff --git a/bochs/README b/bochs/README new file mode 100644 index 00000000..9fd43aa6 --- /dev/null +++ b/bochs/README @@ -0,0 +1,84 @@ +Bochs - The cross platform IA-32 (x86) emulator +Updated: Tue Feb 22 18:07:00 CET 2011 +Version: 2.4.6 + +WHAT IS BOCHS? + +Bochs is a highly portable open source IA-32 (x86) PC emulator +written in C++, that runs on most popular platforms. It includes +emulation of the Intel x86 CPU, common I/O devices, and a custom +BIOS. Currently, Bochs can be compiled to emulate a 386, 486, +Pentium/PentiumII/PentiumIII/Pentium4 or x86-64 CPU, including optional +MMX, SSEx and 3DNow! instructions. Bochs is capable of running +most Operating Systems inside the emulation, for example Linux, DOS, +Windows 95/98/NT/2000/XP or Windows Vista. +Bochs was written by Kevin Lawton and is currently maintained by +the Bochs project at "http://bochs.sourceforge.net". + +Bochs can be compiled and used in a variety of modes, some which are +still in development. The 'typical' use of bochs is to provide +complete x86 PC emulation, including the x86 processor, hardware +devices, and memory. This allows you to run OS's and software within +the emulator on your workstation, much like you have a machine +inside of a machine. Bochs will allow you to run Windows +applications on a Solaris machine with X11, for example. + +Bochs is distributed under the GNU LGPL. See COPYING for details. + +GETTING CURRENT SOURCE CODE + +Source code for Bochs is available from the Bochs home page at +http://bochs.sourceforge.net. You can download the most recent +release, use CVS to get the latest sources, or grab a CVS +snapshot which is updated nightly. The releases contain the most +stable code, but if you want the very newest features try the +CVS version instead. + +WHERE ARE THE DOCS? + +The Bochs documentation is written in Docbook. Docbook is a text +format that can be rendered to many popular browser formats such +as HTML, PDF, and Postscript. Each binary release contains the +HTML rendering of the documentation. Also, you can view the +latest documentation on the web at + http://bochs.sf.net/doc/docbook/index.html + +Some information has not yet been transferred from the older +HTML docs. These can be found at http://bochs.sf.net/docs-html + +WHERE CAN I GET MORE INFORMATION? HOW DO I REPORT PROBLEMS? + +Both the documentation and the Bochs website have instructions on how +to join the bochs-developers mailing list, which is the primary +forum for discussion of Bochs. The main page of the website also +has links to bug reports and feature requests. You can browse and +add to the content in these areas even if you do not have a (free) +SourceForge account. We need your feedback so that we know what +parts of Bochs to improve. + +There is a patches section on the web site too, if you have made +some changes to Bochs that you want to share. + +HOW CAN I HELP? + +If you would like contribute to the Bochs project, a good first step +is to join the bochs-developers mailing list, and read the archive +of recent messages to see what's going on. + +If you are a technical person (can follow hardware specs, can write +C/C++) take a look at the list of open bug reports and feature +requests to see if you are interested in working on any of the +problems that are mentioned in them. If you check out the CVS +sources, make some changes, and create a patch, one of the +developers will be very happy to apply it for you. Developers who +frequently submit patches, or who embark on major changes in the +source can get write access to CVS. Be sure to communicate with the +bochs-developers list to avoid several people working on the same +thing without realizing it. + +If you are a Bochs user, not a hardware/C++ guru, there are still +many ways you could help out. For example: + - write instructions on how to install a particular operating system + - writing/cleaning up documentation + - testing out Bochs on every imaginable operating system and + reporting how it goes. diff --git a/bochs/README-plugins b/bochs/README-plugins new file mode 100644 index 00000000..8853bbe2 --- /dev/null +++ b/bochs/README-plugins @@ -0,0 +1,357 @@ +README-plugins + +This is the README file that came from the CVS branch called BRANCH_PLUGINS. +It's not intended to be user documentation for plugins. It's more like a +bunch of to-do lists that the developers used to coordinate their efforts +while working on plugins. At the bottom are some miscellaneous notes by the +plugin developers and some references to useful usenet articles. + +------------------------------------------------------------------------- +BRANCH_PLUGINS + +The branch is called BRANCH_PLUGINS. There is a normal tag called +BRANCH_PLUGINS_BASE that marks the point where the branch began. The +base marker will help at merge time. + +This branch is a place to experiment with Bochs plugins. Bryce created +the branch on October 4, 2002, and he and Christophe began working on +Bochs plugins. + +We started from Bryce's patch.plugins3, which was a patch from December 2001 +that copied in some of the plugin architecture from plex86. Here are the +comments from that patch: + +> Patch name: patch.plugins3 +> Author: Bryce Denney +> Date: Wed Dec 12 17:56:11 EST 2001 +> +> This patch replaces the Bochs keyboard with a slightly modified version +> of the plex86 keyboard device, which is implemented as a plugin. This +> is sort of a proof of concept, rather than anything that I'm about to +> check in. It uses GNU libtool to compile the plex86 keyboard code into +> a shared library, and installs that shared library in +> /tmp/bochslib/libplex-keyboard.so. Then the new code in plugin.cc (which +> is adapted from the plex86 plugin code) loads the libplex-keyboard library +> during initialization and installs the plex86 keyboard instead of the +> bochs keyboard. +> +> I chose the keyboard because it takes about 2 seconds to test that it's +> basically working, and because the bochs and plex86 implementations hadn't +> changed very much since they split. +> +> If you look at plex-keyboard.cc and plex-keyboard.h, it is fundamentally the +> same as the current plex86 code. I have changed lots of names from bx_* to +> plex_* just to reduce confusion and mayhem when I was compiling with both +> kbd implementations. I didn't change anything except to get it to compile. + +Christophe had made a plugins5 patch, so he checked it in, with these +changes: + - plex86 keyboard device was marged with Bochs keyboard, as a plugin + - plugin.cc was cleaned up + - a device registration mechanism was set up + - the biosdev and unmapped devices were plugin-ized + +TO DO: +- (LATER) some plugins, such as the GUI, PIT, SB, and NE2000, have several different + possible implementations. In this case, all implementations should be + children of a single stub class. The stub's methods produce errors or + panics if they are called, depending on the importance of the device. + There is always one instance of the stub class lying around, which will be + used if none of the implementation plugins is loaded. Either an optional + plugin or a user plugin can fill in these slots. + +- platform specific issues + - (LATER) make sure LTDL works on VC++. It doesn't and won't without + significant work. Maybe it's easier to support VC++ with ifdefs in + plugin.cc rather than using ltdl at all. This will have to wait. + - (DONE) nmake build: we must use lib.exe, not $(LIBTOOL) $(CXX) stuff + +- configure script work + - LTDL has a feature called dlpreload which sort of emulates dlopen + by linking all the modules statically and then emulating dlopen calls. + I don't see any value in this for plugins. If the platform cannot + support dlopen or some equivalent, let the configure script crash and + tell the user to configure without plugins instead. + - (DONE) to support plugins on MacOSX, the user must install dlcompat. + Otherwise libtool's configure script will discover that no dlopen() or + equivalent function is found, and it will not be able to build/load + plugins. The configure script should bomb in this case, with an error + that says where to find dlcompat. dlcompat IS installed on SF compile + farm in /sw/include and /sw/lib. + +- Understand/resolve simulation differences between CVS head and + BRANCH_PLUGINS. Simulation is slightly different. + - compare four versions + - BRANCH_PLUGINS with --enable-plugins + - BRANCH_PLUGINS without --enable-plugins + - BRANCH_PLUGINS_BASE + - CVS head + - these differences seem to be explained by a few things: + 1. devices are initialized in a different order, so they are assigned + different timer id. For any events that occur at the same tick, the + timer handlers would get called in a different order. I believe I + have fixed the order of timer registration so that it matches, and + that cleaned up some simulation differences. + 2. bx_gui->handle_events is now called from iodev/devices.cc instead of + from iodev/keyboard.cc. + 3. bx_keyb_c::periodic() used to be called directly from devices.cc + but now the keyboard registers its own timer + - I have never seen any problems caused by the sim differences, but they + make me nervous. -Bryce + +- (LATER) convert remaining devices + +- (LATER) maybe the implementation class for each plugin device should go into + the .cc file instead of the header file. If all their methods are called + through the stub class virtual functions, and no external file has access to + the real non-stub class, then maybe there is no point in letting anybody + else see the real class at all? (If you do use the class you will get + undefined symbols when you compile for plugins anyway.) For the hard drive, + we could put bx_hard_drive_stub_c in harddrv.h, and any constants or types + that external files might need, and then put the real class, bx_hard_drive_c, + at the top of harddrv.cc. + + +- (LATER) eventually we need to clarify the connection between plugins and + devices. At the moment, each plugin creates exactly one device, but it does + not have to work that way. + - it would be more correct to mark the devices as core, optional, etc. than + to use a type field in the plugin struct. The reason that the type + (core,optional,user) is currently passed into the PLUG_load_plugin macro + and placed in the plugin struct instead of letting the device code decide + is: devices.cc is responsible for initting and resetting devices, so I + wanted devices.cc to decide whether the device would be managed by the + plugin infrastructure (init_all, reset_all) or not. This is not that + important yet, but when Volker wants to write a plugin with multiple + devices, we will need to sort it out. + +- (LATER) make a way for users to replace a core plugin with one of their + choice. + +- (LATER) implement user plugins. These are plugins that Bochs does not know + anything about at compile time. The user asks Bochs to load a plugin using + just its filename. It loads the plugin and registers any bx_params that + the user can configure, and either the text config interface or the + wxWindows interface can display this param list as a menu or dialog. + Then at simulation start time, we call init() on the user device and + it can be used like any other device. + +- (LATER) make plugin CPU??? + +DONE: +- applied patch.plugins5 +- updated makefile dependencies now that plugin.h is in there +- all guis converted to plugins +- 8 I/O devices are converted to plugins +- make the Makefile use libtool to build dynamic libraries +- use libtool's ltdl library to open and read dynamic libraries, since it + has cross platform support +- the Boolean/bx_bool thing will be resolved in the main branch. I have + made patch.replace-Boolean.gz which I will apply later, after the + plugins branch has been merged. This become more urgent because it + caused bug #623152 MacOSX: Triple Exception Booting win95 +- take a look at the code generated by calls to virtual functions, to + check if there's huge overhead that I don't know about. + Answer: I don't believe there is that much extra overhead. If you call + a nonvirtual function, it must push all the args onto the stack, then + push the THIS pointer, then call the method using a known constant address. + With a virtual function, you push all the args onto the stack, then push + the THIS pointer, then do one extra memory reference to THIS+constant to read + the pointer to the virtual method, and call it. This is just what I + expected to find--no strange and magicial code was inserted by the + compiler in this case. +- wxWindows configuration interface and display works fine as a plugin now +- selection of config interface is controlled by the bochsrc line + "config_interface: NAME" and the parameter bx_options.Osel_config. +- selection of display library is controlled by the bochsrc line + "display_library: NAME" and the parameter bx_options.Osel_displaylib. +- renamed vga_library to display_library (Christophe's suggestion) +- add --with-all-libs option, which attempts to detect all the display + libraries that Bochs can compile with. You can use this with or without + plugins, compile with multiple guis in the same binary, and select between + them at runtime. If the detection fails, you can always write a bunch + of --with-PACKAGE options yourself. +- load plugins as they are needed, in main.cc and iodev/devices.cc. + - plugins are loaded using a macro PLUG_load_plugin(plugin_name, plugin_type). + When plugins are enabled, this macro calls bx_load_plugin() in plugin.cc, + which loads the plugin with lt_dlopen and calls its plugin_init method. + When plugins are disabled, the code is already linked into the binary so + the macro calls the plugin_init method directly. + - The plugin_init method for plugin ABC is called libABC_LTX_plugin_init() + and the same prefix is added before the plugin_fini method. This "name + mangling" makes the symbols unique so that they can all be linked + statically into the binary when plugins are turned off. This turned out + to be a very useful thing! + - The choice of lib*_LTX_* is not random... The libtool LTDL library + automatically searches for symbols of the form lib_LTX_ + before looking for . Libtool recommends making global symbols in + every plugin unique in some way, and in fact on MacOSX the dynamic linker + will not allow two libs to be linked in that both have plugin_init symbols, + so this sort of mangling is required. +- how do we know what plugins should be available when we start Bochs? + - we have core plugins, optional plugins, and user plugins. + - (V2.0) core plugin: These are so fundamental that Bochs won't even + initialize without them, for example the CMOS. The user can substitute + his own equivalent plugin to replace the CMOS, but he cannot say "Don't + load the CMOS at all." Core plugin devices are initialized and reset + explictly by code in iodev/devices.cc, since the initialization order for + some of them is critical. They are currently NOT added to the device + list in pluginRegisterDevice and pluginRegisterDeviceDevmodel, so that + the plugin system does not call init() and reset(). If a core plugin + cannot be found, Bochs will panic. + In the bochsrc we can provide a way for the user to REPLACE a core plugin + with a different plugin that implements the same C++ interface, but there + is no way to ask bochs to NOT load a core plugin. I'm not sure how to + configure the replacement plugin--this may have to be added later. + Bochsrc line: + replace_core_plugin: old=pic, new=mypic + - (V2.0) optional plugin: These can be loaded or not without affecting + Bochs's ability to start up and simulate. Initialization and reset for + all optional plugins are handled by bx_init_plugins() and + bx_reset_plugins(), which are now called from bx_devices_c::init() and + bx_devices_c::reset(). Bochs knows how to configure optional plugins at + compile time, and they are loaded only if the configuration settings + enables the device. Examples: serial, parallel, ne2k. See the call to + is_serial_enabled() in iodev/devices.cc. There are some plugins that you + wouldn't ever want to leave out, like vga. Maybe the term "optional" is + not clear and I need to think of a better name. Bochs will panic if an + optional plugin cannot be found. If the plugin was compiled, then + it should be available at runtime too! + - (NOT DONE) user plugin: These are plugins that Bochs does not know + anything about at compile time. The user asks Bochs to load a plugin + using just its filename. It loads the plugin and (somehow) gets + information about what settings the user can configure. The settings are + adjusted by either bochsrc lines or the user interface, and then the + device can be used. I'm missing some details here because I haven't + thought through it all the way. User plugins may not be supported until + after v2.0. + - list of plugins sorted into categories + - core plugins: unmapped, biosdev, cmos, dma, pic, vga + - optional: floppy, harddrv, keyboard, serial, parallel + - user: none yet +- clarify relationship of plugin and device + - a plugin is a shared object that you load that has a plugin_init() and + plugin_fini() function inside. The plugin_init() can create any number of + "devices" and register them. Devices are added to a global list so that we + can do operations on every registered device. + - There is (now) a pointer from each device to the plugin that created it. + - Devices created by core plugins are called core devices. These will not be + added to the device list because they are managed by existing code in + devices.cc and elsewhere. Instead of referring to them by their device_t + structure, we will use a global pointer to them, similar to the + bx_devices.pluginKeyboard pointer. (Alternative: maybe we should add + them to device list anyway, but exclude them in init_all and reset_all + functions.) + - MACOSX PLUGINS WORK! to support plugins on MacOSX, we must ensure that no + plugins have any global symbol names in common, including plugin_init! An + easy solution to this is to say that all plugin functions which can be + looked up with dlsym must follow a pattern like "%s_BXPLUG_%s", where the + first %s is the module name and the second is the plain symbol name, e.g. + pic_BXPLUG_plugin_init. Symbols that are used internally can be declared + static (file scope only). + - SOLARIS PLUGINS WORK! to support plugins on Solaris, we must not rely on + the use of global object constructors. In fact every global variable in a + module MUST BE set to a compile-time constant. We must declare object + pointers as globals, not actual objects. + - WIN32 PLUGINS WORK! to support plugins on win32, I added the + BOCHSAPI macro which expands to __declspec(dllexport) in the nonplugin + code and __declspec(dllimport) in the plugin code. Some makefile hacks + were required too. A few differences between win32 and other platforms: + - use semicolon to separate path names in LTDL_LIBRARY_PATH + - every path name in LTDL_LIBRARY_PATH should start with a drive letter, + for example: c:/cygwin/home/bryce/plugins. +- how do we locate plugins on the disk? + - make install copies the plugins into ${prefix}/lib + - if people install into a standard location, no action may be needed (?) + - we can tell people to set the LTDL_LIBRARY_PATH variable. + - if necessary we can implement a bochsrc command like + plugin_search_directory: /path/to/libs + which would call lt_dlsetsearchpath() to add the path to LTDL's list of + directories it will search. +- change log for BRANCH_PLUGINS is in patches/patch.plugins. It is + pretty complete now. + + + + + + +----------------------------------------------- +random notes: + +class heirarchy: + logfunctions + - bx_devmodel_c + - bx_keyb_stub_c + - bx_keyb_c + +bx_devmodel_c is an abstract class that defines standard functions that all +devices should define, like init and reset. Each method is defined as empty +in bx_devmodel_c so that child classes can choose to implement them or not. + +bx_keyb_stub_c declares the methods that code outside the keyboard would need +to call, such as mouse_motion, gen_scancode, etc. It declares these methods +virtual, and provides a minimal definition for each that just does a panic. A +global variable pluginKeyboard initially points to an instance of +bx_keyb_stub_c so that if you forget/fail to load the load the keyboard plugin, +you will see these panics when the methods are called. + +bx_keyb_c is the real keyboard code. In its constructor, it changes +pluginKeyboard to point to "this". This is equivalent to installing all +the plugin callbacks associated with the keyboard. It also works in +nonplugin code, which is a plus. + + +hard drive read_handler. Right now the read_handler +is a static method so it must get its object pointer from somewhere. + 1) It can get it from global variable bx_hard_drive + 2) The hard drive object can be passed in to it +We've always used #2, so every device has methods that look like this: + + static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len); + static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsi + +If/when we switch over to using virtual methods, there will no longer be +any problem finding the this pointer. If we go that route, the this_ptr +can be eliminated. For now, we must use the this_ptr. Otherwise we could +never support more than one device of a given type. + + + +------------------------------------------ +References + +From: Tero Pulkkinen (p150650@zori.cs.tut.fi) + Subject: Re: undefined reference to `pm virtual table' + Newsgroups: gnu.g++.help + Date: 1996/11/15 + + +> The compile goes off OK, but I get this error at link time: +> pm.o(.text+0xa8): undefined reference to `pm virtual table' + +This error comes from that the compiler didnt make virtual function +table for object even though there's implemented functions that use +objects of that type(constructor for example). Probably your pm-class +has all implemented member functions *inline* and you still have +(pure) virtual functions inside the class. + +The creation point of virtual function table usually (dunno if g++ does that) +is at position of first seen noninline function body of that class. +Now if every of your function is inline, there's no place where compiler +could make virtual function table. + +Fix is to move body of for example constructor(any member is fine) to the .cc +file instead of keeping it in .h-file and linking that .o file to your +executable. + +Other sollution is to remove *all* implementations of functions from header +file. If all functions of a class are pure virtual, there's no need for +virtual function table. (Constructor must set pointer to virtual function +table to the object, so, if you have constructor, you'll need virtual +function table too, even in abstract classes...) + +> Can someone help me? Thanks in advance. + +Hope this helps.... + diff --git a/bochs/README-wxWindows b/bochs/README-wxWindows new file mode 100644 index 00000000..19cc91ac --- /dev/null +++ b/bochs/README-wxWindows @@ -0,0 +1,337 @@ +Readme for wxWindows Interface +updated Sat Dec 21 11:09:34 EST 2002 + +Contributors to wxWindows port: + Don Becker (Psyon) + Bryce Denney + Dave Poirier + Volker Ruppert + +wxWindows Configuration Interface + +The wxWindows port began in June 2001 around the time of Bochs 1.2.1. Dave +Poirier and Bryce Denney started adding a wxWindows configuration interface. +We made some progress, but stopped after a while. Then in March/April 2002 +Bryce and Psyon revived the wxWindows branch and turned it into a usable +interface. Psyon did most of the work to get text and graphics working, and +Bryce worked on event passing between threads, and keyboard mapping. +Starting in August 2002, Bryce added lots of dialog boxes to allow you +to set all the bochsrc parameters. At the time of release 2.0, there +are still some bugs but it is pretty stable and usable. + +Bochs should be build with wxWindows 2.3.3 or later. It will probably +not compile with 2.2.x without some work. wxWindows 2.3.3 includes +a patch by Bryce Denney to allow us to get raw keycode data for several +OSes. + +On any UNIX platform with wxWindows installed, configure with +--with-wx to enable the wxWindows display library. + +To build in MS VC++: +- edit .conf.win32-vcpp and add "--with-wx" to the configure line. + If you want different configure options from what you see, change them + too. +- in cygwin, do "sh .conf.win32-vcpp" to run configure +- unzip build/win32/wxworkspace.zip into the main directory. + For cygwin: unzip build/win32/wxworkspace.zip + or use winzip or whatever else. +- open up bochs.dsw, the workspace file +- edit project settings so that VC++ can find the wxWindows include + files and libraries on your system. Bryce installed them in + d:/wx/wx233/include and d:/wx/wx233/lib. Specifically, edit + - Project>Settings>C/C++>Category=Preprocessor: include directories. + - Project>Settings>Link>Category=Input: additional library path. +- build + +Note that the project is set up for wxWindows 2.3.3. To use on other +wxwindows versions, you will have to change some of the names of the libraries +to include. Use the samples that came with that version of wxwindows for +reference. + +To do: +- now that ParamDialog works, I may rewrite some of the other dialogs + as subclasses of ParamDialog. This would lead to more compact code, + and fewer bugs. +- configure time dialog + - need to think about dialog layout + - setting of IPS (controls how much time the PIT associates with each + instruction for purposes of sending timer interrupts). How can we + name this? instructions per simulated second. + - enable realtime pit, realtime pit settings (?) + - enable/disable X windows idle hack + - report instructions per wall clock second in real time +- decide which settings can be adjusted at runtime, and figure out how + to disable the others. Do we need a set_enable() on the parameters + themselves? +- the power button has always "turned off" the power. Make it also + turn ON the power. I think a few little green LEDs are in order. +- floppy config screen: on win32, both not present and ejected are selected + at first. +- log events + - Later: allow viewing of current log messages. Maybe this is a dialog that + we append to, or maybe it should periodically display the last 1K of the + log file (might be faster in high volume situations). + - Later: should we allow multiple log files with different settings? for + example dump cpu events to cpulog.txt and keyboard events to + keyboardlog.txt? +- debugger + - bug: it's possible to make the GUI stop responding to mouse and keyboard + input if you click the continue button in the debugger twice in very + close succession. I don't know why yet. + - probably the layout will be similar to BFE at first + - need to show disassembly of the next instruction to be executed +- clean up the biggest memory leaks and init/cleanup code. The gui allows you + to kill the simulator and restart, but it doesn't do well after the first + time. Valgrind should help with memory leak debugging, though until + recently it couldn't run multithreaded programes. +- disk change dialogs for floppy and cdrom need work. + http://sourceforge.net/tracker/index.php?func=detail&aid=545414&group_id=12580&atid=112580 +------------- + +------------------------------------------------------ + +Random notes follow + +Added some sketches. I'm thinking that the control +panel will be able to basically show one of these screens at a time. When +you first start you would see ChooseConfigScreen which chooses between the +configurations that you have loaded recently (which it would remember +by the pathname of their bochsrc). Whether you choose an existing +configuration to be loaded or a new one, when you click Ok you go to +the first configuration screen, ConfigDiskScreen. + +Each of the configuration screens takes up the whole control panel window. +We could use tabs on the top and/or "<-Prev" and "Next->" buttons to make +it quick to navigate the configuration screens. Each screen should +probably have a Prev, Next, Revert to Saved, and Accept button. +The menu choices like Disk..., VGA..., etc. just switch directly to +that tab. + + +------------------------------------------------------ +Notes: + +events from gui to sim: +- [async] key pressed or released +- [async] mouse motion with button state +- [sync] query parameter +- [sync] change parameter +- [async] start, pause, stop, reset simulation. Can be implemented + as changing a parameter. +- [async] request notification when some param changes + +events from sim to gui: +- [async] log message to be displayed (or not) +- [async] ask user how to proceed (like panic: action=ask) +- [async] param value changed +- make my thread sleep for X microseconds (call wxThread::sleep then return) + +In a synchronous event, the event object will contain space for the entire +response. The sender allocates memory for the event and builds it. The +receiver fills in blanks in the event structure (or could overwrite parts) +and returns the same event pointer as a response. For async events, probably +the sender will allocate and the receiver will have to delete it. + +implement the floppyA and floppyB change buttons using new event +structure. How should it work? + +vga gui detects a click on floppyA bitmap +construct a BxEvent type BX_EVT_ASK_PARAM +post the event to the wxwindows gui thread (somehow) and block for response +when it arrives in the gui thread, show a modal dialog box +get the answer back to the simulator thread + + +right now, this is working ok within the simulator thread using +wxMutexGuiEnter/Leave. Still I'm going to change it so that the +siminterface.cc code builds an event structure and the gui code +fills in the blank in the structure, instead of the stupid +notify_get_int_arg stuff. + + +Starting and Killing Threads + +When a detachable (default) thread finishes (returns from its Entry() +function), wxwindows frees the memory associated with that thread. +Unless the thread is never going to end, it is potentially dangerous to have a +pointer to it at all. Even if you try to "check if it's alive" first, you may +be dereferencing the pointer after it has already been deleted, leading to it +claiming to be alive when it's not, or a segfault. To solve this, the approach +used in the wxwindows threads example is to have code in the thread's OnExit() +method remove the thread's pointer from the list of usable threads. In +addition, any references or changes to the list of threads is controlled by a +critical section to ensure that it stays correct. This post finally +explained what I was seeing. + ++----------------------- +| From: Pieter van der Meulen (pgmvdm@yahoo.com) +| Subject: Re: Thread Sample program - bug +| Newsgroups: comp.soft-sys.wxwindows +| Date: 2001-06-28 17:51:35 PST +| +| +| At 06:24 PM 6/28/2001, you wrote: +| >Hi, +| >I have wxWindows 2.2.7 (wxMSW) installed. +| > +| >I just found in the thread.cpp sample code this section: +| > +| > +| >void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ) +| >{ +| > size_t count = wxGetApp().m_threads.Count(); +| > for ( size_t i = 0; i < count; i++ ) +| > { +| >===> wxGetApp().m_threads[0]->Delete(); <===== +| > } +| > +| > Close(TRUE); +| >} +| > +| >The indecated line should probably rather have a +| >m_threads[i] rather than m_threads[0] . +| +| No, it should not, although it is not immediately obvious. When Delete() is +| called, the thread will eventually delete itself, but not before it calls +| MyThread::Exit(), which will remove itself from m_threads[] using +| wxArray::Remove(this). wxArray::Remove (RemoveAt) will compact the array to +| remove the element, it is now size-1. After this wxThread::Delete() returns. +| +| +| >I have have a further question to this: +| >Does this mean that a detached thread created with new +| >HAS to be deleted manually ? Or is this only in case it might still +| >be running? +| +| Firstly, you must create every detached thread using new since it will +| delete itself, literally calling delete this. +| Calling wxThread::Delete() is a correct way to terminate a thread, but +| manually deleting (using delete) a detached wxThread object is not. +| wxThread::Delete() will ask the thread to exit, the thread should check for +| this in wxThread::Entry() regularly using wxThread::TestDestroy() and exit +| when asked to do so. +| +| >(In general I have a unsatisfied felling about when delete is +| >neccessary and when not -- "I only know, it's not , if the class is +| >derived from wxWindows") +| +| For wxThreads: joinable threads must be deleted (when allocated on the +| heap), detached threads may never be deleted. For other classes, consult +| the documentation ;) +| +| +| >Thanks for some feedback, +| >Sebastian +| +| Regards, +| +| Pieter. ++----------------------- + +tracking some kind of deadlock bug in Linux. + +seems to be in ReadMailcap, src/unix/mimetypes.cpp in wxwindows sources +src/unix/mimetype.cpp:2312 + +SOLUTION: compile with -pthread on every compile and link line. + + + +---------------------------------------------- +Suggested solution for putting sizers inside a scrolled window + +From: Thaddaeus Frogley (codemonkey_uk@users.sourceforge.net) +Subject: RE: Using sizers inside of a scrolled window +Newsgroups: comp.soft-sys.wxwindows +Date: 2001-10-02 02:41:04 PST + +I have solved that same problem (scrolled windows / sizers) like so: + +In the constructor for your wxFrame derived class, + +//create a scrolling window +myScrolledWindow = new wxScrolledWindow(this, -1); + +//in the scolling window, create a panel +myMainPanel = new wxPanel(myScrolledWindow, -1); + +//place controls in the panel, laying them out with sizers + +//... + +myMainPanel->SetAutoLayout( TRUE ); +myMainPanel->SetSizer( sizer ); +sizer->Fit( myMainPanel ); +sizer->SetSizeHints( myMainPanel ); + +//set the scroll bars lengths based on the size of the inner panel +wxSize size = myMainPanel->GetBestSize(); +myScrolledWindow->SetScrollbars( 1, 1, size.GetWidth(), size.GetHeight() ); + +//calculate the size of the window, and set it appropriately +size.Set(size.GetWidth()+16,size.GetHeight()+16); + +//Get the physical size of the display in pixels. +int displaySizeX,displaySizeY; +wxDisplaySize(&displaySizeX,&displaySizeY); + +//clamp window size to % of screen +if (size.GetWidth()>displaySizeX*0.75){ + size.SetWidth(displaySizeX*0.75); +} +if (size.GetHeight()>displaySizeY*0.75){ + size.SetHeight(displaySizeY*0.75); +} + +SetClientSize(size); + + + +----------------- +How to make wxChoice as wide as the longest string in the choice box? + +From: Vadim Zeitlin (Vadim.zeitlin@dptmaths.ens-cachan.fr) +Subject: Re: wxChoice +Newsgroups: comp.soft-sys.wxwindows +Date: 2001-09-18 04:41:07 PST + + +On Sat, 15 Sep 2001 15:39:45 +0200 Merlijn Blaauw wrote: + +MB> Also, I +MB> would like the widget's parent window to change size (width) to fit the +MB> widget's new content aswell. + + You'll have to do it manually by calculating the length of the string you +add to the control (use wxClientDC(combobox) and set correct font before +calling GetTextExtent()!) and resizing the control to be slightly larger +(yes, I know it's not nice at all but I don't see any other way to do it). + + Regards, +VZ + +--------- +Hold on, this is even better! + +From: Yann Rouillard (Y.Rouillard@exeter.ac.uk) +Subject: wxChoice and wxADJUST_MINSIZE +Newsgroups: comp.soft-sys.wxwindows +Date: 2002-07-18 08:28:31 PST + +I am trying to use a wxChoice widget in a little panel. The text length of +the choices in the wxChoice can change so I used the wxADJUST_MINSIZE to +have its width correctly set. + +> the manual for wxSizer::Add() says: +Finally, you can also specify wxADJUST_MINSIZE flag to make the minimal size of +the control dynamically adjust to the value returned by its GetBestSize() +method - this allows, for example, for correct relayouting of a static text +control even if its text is changed during run-time. + +relayouting? sounds like s/size/layout/g gone wrong. + +Call Add() with wxADJUST_MINSIZE flag! +-------------- +mno-cygwin guide on mingw webpage +http://www.xraylith.wisc.edu/~khan/software/gnu-win32/mno-cygwin-howto.txt +www.mingw.org diff --git a/bochs/README.rfb b/bochs/README.rfb new file mode 100644 index 00000000..63d2892e --- /dev/null +++ b/bochs/README.rfb @@ -0,0 +1,3 @@ +The RFB server implementation is still lacking as of now, as a consequence +you should force 8bit mode on the client to use it correctly, i.e. on Linux, +use: "xvncviewer -8bit localhost" or similar. diff --git a/bochs/TESTFORM.txt b/bochs/TESTFORM.txt new file mode 100644 index 00000000..549d2a30 --- /dev/null +++ b/bochs/TESTFORM.txt @@ -0,0 +1,133 @@ +------------------------------------------------------------- +BOCHS TESTING FORM Version 0.5 +------------------------------------------------------------- + +Because of the variety of platforms and configurations that Bochs +supports, it is difficult for any one person to test it thoroughly. +This form is intended to help the Bochs developers keep track of test +results from different sources. To avoid confusion, this form should +be submitted once for each combination of host OS and guest OS you +try. For example: your host OS is Debian Linux and you get both Win95 +and FreeDOS to start up. You would send one form for +Win95-under-Debian and a second form for FreeDOS-under-Debian. In +this case it would save time to fill in the host OS part, copy it a +few times and fill out the guest OS part for each copy. + +To fill in a blank such as [__], replace the underlines and leave +the brackets. Example: [Sun Ultrasparc 10]. To fill in a +multiple-choice, just put an X in the brackets. Example: [X] +Mail completed forms to bochs-developers@lists.sourceforge.net + + +What is the date? +[__] + +What is your name? +[__] + +What is your email address? +[__] + +Do you mind if your name and email address are placed on a testing results +web page so that people with a similar setup can write to you? + [ ] Ok, put it on a web page + [ ] No, keep my address private. + +What type of hardware are you using, e.g. 2400 MHz Intel Pentium 4. +[__] + +What operating system are you using? Please be specific, e.g. +Redhat Linux 6.2 with 2.2.16 kernel. +[__] + +What version of bochs are you using? + [ ] compiled from version 2.4.2 + [ ] compiled from version [_____] + [ ] I compiled it from the CVS sources from date: [__] + [ ] other source distribution from URL: [__] + [ ] binary distribution from URL: [__] + +Please fill in the next few questions only if you compiled Bochs +yourself, as opposed to downloading a binary. + +Did the configure script run ok, and detect your hardware and +operating system? + [ ] Yes + [ ] No, configure crashed. + [ ] No, configure ran ok but produced a bad configuration. + [ ] No, I cannot run configure on my platform (win32 and mac). + +If you used configure, what arguments did you give it? If you used a +.conf.* script, give the name of the .conf script instead. +[__] + +What compiler did you use? (Please include version.) +[__] + +Did Bochs compile clean without any hacking? + [ ] Yes + [ ] No + +If you had to make changes to compile, please summarize the problems you +had or include diffs. +[__] + +End of compile-specific questions! + +What guest operating system are you using inside bochs? +[__] + +Are you booting from a floppy, hard disk or cdrom image ? + [ ] floppy image + [ ] raw floppy drive + [ ] cdrom + [ ] cdrom image + [ ] hard drive image + [ ] raw hard drive (is this even possible?) + [ ] other [__] + +Did the guest operating system boot successfully? + [ ] Yes + [ ] No + +If no, what error messages do you see on the console or in the log file? +[__] + +What applications worked under this guest operating system? +[__] + +What applications failed under this guest operating system? Did the +application function incorrectly, crash Bochs, or what? If you got a +panic, paste in the panic message that you received with some +description of what was happening at the time. +[__] + +The remaining questions are about Bochs features that you may not have +used. If you tried out the feature, move the X to the "works" or +"fails" column. + + Not Works + tested ok Fails Comments? +x86-64 [X] [ ] [ ] [__] +floating point [X] [ ] [ ] [__] +SMP [X] [ ] [ ] [__] +VMX [X] [ ] [ ] [__] +keyboard [X] [ ] [ ] [__] +floppy disk [X] [ ] [ ] [__] +raw floppy disk [X] [ ] [ ] [__] +hard disk [X] [ ] [ ] [__] +mouse [X] [ ] [ ] [__] +cdrom [X] [ ] [ ] [__] +sb16 [X] [ ] [ ] [__] +ne2000 [X] [ ] [ ] [__] +i440FX pci [X] [ ] [ ] [__] +debugger [X] [ ] [ ] [__] +gui debugger [X] [ ] [ ] [__] +external loader [X] [ ] [ ] [__] +save/restore [X] [ ] [ ] [__] +VGA [X] [ ] [ ] [__] +Cirrus Logic SVGA [X] [ ] [ ] [__] +USB [X] [ ] [ ] [__] + +Thank you for your contribution in the Bochs testing effort! Please +mail completed forms to bochs-developers@lists.sourceforge.net diff --git a/bochs/TODO b/bochs/TODO new file mode 100644 index 00000000..47c6837d --- /dev/null +++ b/bochs/TODO @@ -0,0 +1,237 @@ +This is the "roadmap" posted in the mailing list, augmented by +comments from the mailing list and the irc chat. +Anybody is welcome to work on any of these issues. Some of +these items are rather simple and can be implemented by single +individuals. Other items are quite complex and development needs +to be coordonated. So, if you want to contribute, please drop +us a note in the mailing list, so you can get help or exchange +ideas. +Christophe Bothamy. + +0. Donations +Source Forge recently set up a donation system for hosted projects. +Should we accept donations ? What could we do with the money ? +- give to EFF, FSF or other +- fund Kevin to continue the work on plex86 so we can use it +- bounties for somebody write optimized win9x/NT/XFree/linux/*BSD + drivers for our vga/net/ide cards +- other ? +Status in Bochs 2.3: +No decisions about this yet. + +1. Speed +Speed (well lack of) is one of the biggest criticism made by users +who'd like to see Bochs run as fast as Virtual PC. +Paths we can explore to get more speed : +1.1 virtualization : plex86 +1.2 dynamic translation : qemu +Status: +Some work has been done for Bochs 2.3.7 but still long way is ahead. + +2 multithreading. Conn Clark wrote : +Threading might be nice too, for those of us who have SMP/SMT machines. +I have a patch from Mathis (who hangs out on the IRC channel all the +time) that puts the video card interface in its own thread. It has +troubles though that I have not resolved. It may also be easier to debug +a threaded peripheral. +I also think that it might be possible to thread a chunk of the CPU +emulation to improve performance on a SMP/SMT machine. Specificaly +write_virtual_dword, write_virtual_word, write_virtual_byte, etc... +might just be able to be threaded. I think the threading overhead might +be less than the protection and address translation code. We would have +to try it to find out. I'm also sure there can be some nasty hurdles to +overcome. +Status: +Third party group started a para-Bochs project exactly to reach above goals, +some beta version is already released. +The home page of the project: http://grid.hust.edu.cn/cluster/VirtualMachine/main.html + +3. Plugin architecture +3.1 The plugin architecture can be reworked if we want to support +multiple similar devices like seral net or vga cards. +We currently have two "types" of plugins: "core" and "optional". +Maybe we could add "classes" of plugins. The current version of +Bochs supports the classes "display_library" and "io_device". +New classes can be "config_interface", "net_lowlevel" and +"sound_lowlevel" +3.2 Stanislav wrote : +Plugin architecture should be rewritten like real plugin architecture s.t. +Bochs VGA plugin for example will be real plugin. I mean that replacement +of plugin dll in already compiled Bochs will replace Bochs VGA card and +the new card will be detected automatically. +This will allow for example developing of plugins separately from Bochs. +3.3 Michael Brown wrote : +If the configuration interface is to be reworked, could we also make it so +that plugins are self-contained, rather than needing to pollute config.cc +with code for defining and parsing plugin-specific options +Status: +A little bit of the basic work is done now: The config parameter handling has +been rewritten to a parameter tree and user-defined bochsrc options are now +supported. The main plugin architecture rewrite is not done yet. + +4. PCI host<->guest proxy +Being able to use a real pci device from inside Bochs would be a +great feature of Bochs. It would ease reverse engineering of non +documented cards, or one could even use a real spare vga card. +Frank Cornellis has done a great job on this subject, and we began +integrating his changes. +Status: +The pcidev device is present in CVS and it has been updated for the new PCI +infrastructure, but the new code is untested yet. + +5. Subdirectories in iodev +The iodev directory contains the various implemented iodevice. +With the new pci devices, new harddrives and new net access methods, +it could be interesting to add new subdirectories like : +iodev/video/... --> for standard vga and new card emulation +iodev/disks/... --> for the ata/atapi classes, hd/cd classes and host accesses +iodev/net/... --> for ne2k and host net access +isa and pci devices would be mixed in the directories, but this should +be manageable. +Status: +Not done yet. + +6. VGA +For SVGA emulation we have Bochs VBE and the Cirrus adapter. We should have +a look at the voodoo3 (specs http://v3tv.sourceforge.net/docs.php). +Status: +Not done yet. + +7. Random thoughts on disk emulation improvements : +7.1 lba48 support +7.2 autodetection of disk size / geometry +7.3 uml cow disk image support +7.4 compressed disk image support +7.5 extend redolog-disk specification to add coherency check of the flat +image file, by storing its fstat-mtime field in the redolog. +Status: +Autodetection now works for all image types created with bximage and vmware3 +images. LBA48 and vmware4 disk images support was added in Bochs 2.3.5 release. +The other items are not done yet. + +8. net +8.1 bootable ethernet rom ? +see etherboot, Micheal Brown wrote : +This already works; you can build an Etherboot rom image with the pnic +driver, specify it as an option ROM in bochsrc and it will boot. I'm +using this extensively at the moment in Etherboot development. +In the Etherboot project's CVS, in the contrib/bochs directory, you can +find a working bochsrc file and an up-to-date README with step-by-step +instructions on getting this working. +Status: +The pnic device is present in CVS, but the status is unknown. + +9. Bios +9.1 add "jump table placeholder" and log missing function calls in the bios. +Check completness with Ralf Brown interrupt list. +Status: +Not done yet. +9.2 use Coreboot or SeaBios as possible alternatives/extensions to +Bochs Bios ROM we have. +Status: +Not done yet. + +10. LGPL VGABios +11.1 Video parameters table +There is a very nice parameter table in 3dfx banshee document +http://www2.lm-sensors.nu/~lm78/pdfs/Banshee_2d_spec.PDF +see also http://www.xyzzy.claranet.de/dos/vgacrt.c +Status: +The new version 0.6a of the LGPL'd VGABIOS has minimal support for the video +parameter table. + +11. Optimized Guest drivers still needed : VGA, IDE, NET +We have a specific VGA driver for winNT/2K, but still +lack drivers for other OSes. +Status: +Not done yet. + +12. USB support +Ben Lunt has been working on USB support. The USB mouse and keypad code +is present in Bochs and almost stable. USB flash disk support has been +started and the runtime device change support should be completed. +Status: +Under construction. + +13. Config file and dynamic menu +13.1 Benjamen R. Meyer wrote : +I think we should rework the .bochsrc file to be more standard across all +devices. I like how the USB configuration is done in it, and think we should +put something similar together for everything else. In otherwords, create +something that can be easily used for everything, and make it easier to +configure in the process. +From what I can tell right now, most of the configuration lines are randomly +thrown together as each gets implemented or added, instead of having +something that is based on a standard approach to the configuration. +The result should be something that would be able to easily auto-configured +by another program (a configuration editor?) with minimal changes necessary +when new devices/features are added. +13.2 Franck Cornelis wrote : the config system needs some work... +e.g. the main menu is static while it could be generated at run-time... +the main menu text lives somewhere in a file... while it should be generated +at run-time by iterating the main menu objects +Status: +The config options handling has been rewritten to a parameter tree. + +14. lowlevel serial support for Windows. +Volker is currently working on this. +Status: +Not yet complete (transmit works, receive is losing data). + +15. Parallel port +Conn Clark wrote : +I would like to see better parallel port support so I can use a dongle. +This is something I would find very useful as it would mean I wouldn't +have to boot back into windows ever again. I also recognize that this +may require a kernel module be written, which is beyond my current +skills. I know others will find this useful as I have had to tell a +few people that their parallel port driven peripherals that require a +bidirectional parallel port won't work. +Status: +Not done yet. + +16. Guest-To-Host Communication +Try to adapt VirtualBox guest-to-host communication methods into Bochs. +Having VirtualBox Shared Folders or VNAT support in Bochs could very +simplify its usage. + +17. Patches / Bug reports +There are dozens of patches floating around. Some are outdated, +don't apply cleanly, are obsolete/unneeded. We could try to do +some clean-up, and keep only relevent ones. +We should also clean up the SF bug tracker. Some bugreports are +very old and we asked for more information with no response. +Status: +There is some progress, but still a lot of work to do. + +18. Positions +If you want to help without coding, here are available positions : +19.1 Webmaster : update website (Jan Bruun Andersen offered to help) +19.2 patch coordonator : look at incoming patches (sourceforge and +mailing list) and upload / update in the cvs patches directory. +19.3 platform maintainers for macos / win32 +19.4 disk image maintainer : create and maintain our collection +of disk images. Usually, only the configuration file needs to be +updated, and old bios files have to be removed. Some packages +still contain very old bios files, they should definitely have +to be removed. +Status: +More active developers are needed to do the things described above. + +19. Bochs demo cd/dvd +With version 2.1, it is now technically possible to use disk images +on a read-only media, with a journal files on a read/write media. +It would be great to create a demo cd/dvd with executables for +supported platforms, configuration files and read-only disk +images, the journal files would be written in a temporary +directory on the harddisk. +Status: +Not done yet. + +20. Other CPU architectures : arm, ppc +This has been asked in the mailing list. I'm not really +interested, but other people might be. Should we propose to +host the new CPUs code in our source tree, or should we let +people fork ? +Status: +Not done yet. diff --git a/bochs/aclocal.m4 b/bochs/aclocal.m4 new file mode 100644 index 00000000..570ba653 --- /dev/null +++ b/bochs/aclocal.m4 @@ -0,0 +1,6634 @@ +##################################################################### +# $Id$ +##################################################################### + +dnl ------------------------------------------------------------------- +dnl This test for largefile support was written by Vadim Zeitlin for +dnl wxWidgets. He has given permission for Bochs to use it. +dnl ------------------------------------------------------------------- + +dnl WX_SYS_LARGEFILE_TEST +dnl +dnl NB: original autoconf test was checking if compiler supported 6 bit off_t +dnl arithmetic properly but this failed miserably with gcc under Linux +dnl whereas the system still supports 64 bit files, so now simply check +dnl that off_t is big enough +define(WX_SYS_LARGEFILE_TEST, +[typedef struct { + unsigned int field: sizeof(off_t) == 8; +} wxlf; +]) + +dnl WX_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR) +define(WX_SYS_LARGEFILE_MACRO_VALUE, +[ + AC_CACHE_CHECK([for $1 value needed for large files], [$3], + [ + AC_TRY_COMPILE([#define $1 $2 + #include ], + WX_SYS_LARGEFILE_TEST, + [$3=$2], + [$3=no]) + ] + ) + + if test "$$3" != no; then + wx_largefile=yes + AC_DEFINE_UNQUOTED([$1], [$$3]) + fi +]) + +dnl AC_SYS_LARGEFILE +dnl ---------------- +dnl By default, many hosts won't let programs access large files; +dnl one must use special compiler options to get large-file access to work. +dnl For more details about this brain damage please see: +dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html +AC_DEFUN([AC_SYS_LARGEFILE], +[AC_ARG_ENABLE(largefile, + [ --disable-largefile omit support for large files]) +if test "$enable_largefile" != no; then + dnl _FILE_OFFSET_BITS==64 is needed for Linux, Solaris, ... + dnl _LARGE_FILES -- for AIX + wx_largefile=no + WX_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64, ac_cv_sys_file_offset_bits) + if test "x$wx_largefile" != "xyes"; then + WX_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1, ac_cv_sys_large_files) + fi + + AC_MSG_CHECKING(if large file support is available) + if test "x$wx_largefile" = "xyes"; then + AC_DEFINE(HAVE_LARGEFILE_SUPPORT) + fi + AC_MSG_RESULT($wx_largefile) +fi +]) + +dnl ----------end of largefile test------------------------------------ + + + +########################################################################### +# The rest of this file is basically the concatenation of libtool.m4 and +# ltdl.m4 from the libtool 1.4.2 package. Also pkg.m4 from the pkg-config +# 0.20 package. However, to work around a missing AM_CONDITIONAL macro, +# Bryce made the following change: +# +# Change these lines +# AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno) +# AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno) +# to this +# if test x"${enable_ltdl_install-no}" != xno; then +# AC_DEFINE(INSTALL_LTDL) +# fi +# if test x"${enable_ltdl_convenience-no}" != xno; then +# AC_DEFINE(CONVENIENCE_LTDL) +# fi +# +# There is probably some way to get AM_CONDITIONAL defined, which would +# be better. + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 47 AC_PROG_LIBTOOL +# Debian $Rev: 47 $ + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s conftest.err; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + testring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos* | morphos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$testring" 2>/dev/null` \ + = "XX$testring") >/dev/null 2>&1 && + new_result=`expr "X$testring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + testring=$testring$testring + done + testring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + # According to Tom Tromey, Ian Lance Taylor reported there are C compilers + # that will create temporary files in the current directory regardless of + # the output directory. Thus, making CWD read-only will cause this test + # to fail, enabling locking or at least warning the user not to do parallel + # builds. + chmod -w . + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test ! -s out/conftest.err; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && test "X$CXX" != "Xno"; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +#- set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case "$host_cpu" in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + case $host_cpu in + alpha* | hppa* | i*86 | ia64* | m68* | mips* | powerpc* | sparc* | s390* | sh*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/${ac_tool_prefix}nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + esac + fi + done + IFS="$lt_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided and an installed libltdl is not found, it is +# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' +# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single +# quotes!). If your package is not flat and you're not using automake, +# define top_builddir and top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# -------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# +# Check for any special shared library compilation flags. +# +_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= +if test "$GCC" = no; then + case $host_os in + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' + ;; + esac +fi +if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then + AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$]_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) + _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no + fi +fi + + +# +# Check to make sure the static flag actually works. +# +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +# Report which librarie types wil actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + darwin* | rhapsody*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' + ;; + esac + fi + ;; + esac + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cc + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + darwin* | rhapsody*) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' + ;; + esac + fi + ;; + esac + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + dgux*) + case $cc_basename in + ec++) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC) + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case "$host_cpu" in + ia64*|hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc) + # Intel C++ + with_gnu_ld=yes + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + cxx) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + osf3*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sco*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case $cc_basename in + CC) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP="$STRIP" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext='$shrext' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDRT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + cxx) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + sco*) + case $cc_basename in + CC) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + *) + ;; + esac + ;; + solaris*) + case $cc_basename in + CC) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + unixware*) + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + case $CC in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + linux*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds" + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ +cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ +$echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds" + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi4*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + if test "$GXX" = yes ; then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' + ;; + esac + fi + ;; + esac + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4.2uw2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv5*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && break + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +SED=$lt_cv_path_SED +]) +AC_MSG_RESULT([$SED]) +]) + +## ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- +## Copyright (C) 1999-2000 Free Software Foundation, Inc. +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 6 AC_LIB_LTDL +# Debian $Rev: 42 $ + +# AC_WITH_LTDL +# ------------ +# Clients of libltdl can use this macro to allow the installer to +# choose between a shipped copy of the ltdl sources or a preinstalled +# version of the library. +AC_DEFUN([AC_WITH_LTDL], +[AC_REQUIRE([AC_LIB_LTDL]) +AC_SUBST([LIBLTDL]) +AC_SUBST([INCLTDL]) + +# Unless the user asks us to check, assume no installed ltdl exists. +use_installed_libltdl=no + +AC_ARG_WITH([included_ltdl], + [ --with-included-ltdl use the GNU ltdl sources included here]) + +if test "x$with_included_ltdl" != xyes; then + # We are not being forced to use the included libltdl sources, so + # decide whether there is a useful installed version we can use. + AC_CHECK_HEADER([ltdl.h], + [AC_CHECK_LIB([ltdl], [lt_dlcaller_register], + [with_included_ltdl=no], + [with_included_ltdl=yes]) + ]) +fi + +if test "x$enable_ltdl_install" != xyes; then + # If the user did not specify an installable libltdl, then default + # to a convenience lib. + AC_LIBLTDL_CONVENIENCE +fi + +if test "x$with_included_ltdl" = xno; then + # If the included ltdl is not to be used. then Use the + # preinstalled libltdl we found. + AC_DEFINE([HAVE_LTDL], 1, + [Define this if a modern libltdl is already installed]) + LIBLTDL=-lltdl +fi + +# Report our decision... +AC_MSG_CHECKING([whether to use included libltdl]) +AC_MSG_RESULT([$with_included_ltdl]) + +AC_CONFIG_SUBDIRS([libltdl]) +])# AC_WITH_LTDL + + +# AC_LIB_LTDL +# ----------- +# Perform all the checks necessary for compilation of the ltdl objects +# -- including compiler checks and header checks. +AC_DEFUN([AC_LIB_LTDL], +[AC_PREREQ(2.50) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_C_CONST]) +AC_REQUIRE([AC_HEADER_STDC]) +AC_REQUIRE([AC_HEADER_DIRENT]) +AC_REQUIRE([_LT_AC_CHECK_DLFCN]) +AC_REQUIRE([AC_LTDL_ENABLE_INSTALL]) +AC_REQUIRE([AC_LTDL_SHLIBEXT]) +AC_REQUIRE([AC_LTDL_SHLIBPATH]) +AC_REQUIRE([AC_LTDL_SYSSEARCHPATH]) +AC_REQUIRE([AC_LTDL_OBJDIR]) +AC_REQUIRE([AC_LTDL_DLPREOPEN]) +AC_REQUIRE([AC_LTDL_DLLIB]) +AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) +AC_REQUIRE([AC_LTDL_DLSYM_USCORE]) +AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS]) +AC_REQUIRE([AC_LTDL_FUNC_ARGZ]) + +AC_CHECK_HEADERS([assert.h ctype.h errno.h malloc.h memory.h stdlib.h \ + stdio.h unistd.h]) +AC_CHECK_HEADERS([dl.h sys/dl.h dld.h mach-o/dyld.h]) +AC_CHECK_HEADERS([string.h strings.h], [break]) + +AC_CHECK_FUNCS([strchr index], [break]) +AC_CHECK_FUNCS([strrchr rindex], [break]) +AC_CHECK_FUNCS([memcpy bcopy], [break]) +AC_CHECK_FUNCS([memmove strcmp]) +AC_CHECK_FUNCS([closedir opendir readdir]) +])# AC_LIB_LTDL + + +# AC_LTDL_ENABLE_INSTALL +# ---------------------- +AC_DEFUN([AC_LTDL_ENABLE_INSTALL], +[AC_ARG_ENABLE([ltdl-install], + [AC_HELP_STRING([--enable-ltdl-install], [install libltdl])]) + +if test x"${enable_ltdl_install-no}" != xno; then + AC_DEFINE(INSTALL_LTDL) +fi +if test x"${enable_ltdl_convenience-no}" != xno; then + AC_DEFINE(CONVENIENCE_LTDL) +fi +])])# AC_LTDL_ENABLE_INSTALL + + +# AC_LTDL_SYS_DLOPEN_DEPLIBS +# -------------------------- +AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_CACHE_CHECK([whether deplibs are loaded by dlopen], + [libltdl_cv_sys_dlopen_deplibs], + [# PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + libltdl_cv_sys_dlopen_deplibs=unknown + case "$host_os" in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + aix[[45]]*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + libltdl_cv_sys_dlopen_deplibs=yes + ;; + kfreebsd*-gnu) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + gnu*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + irix[[12345]]*|irix6.[[01]]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + linux*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + osf[[1234]]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explictly say `no'. + libltdl_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + ]) +if test "$libltdl_cv_sys_dlopen_deplibs" != yes; then + AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], + [Define if the OS needs help to load dependent libraries for dlopen().]) +fi +])# AC_LTDL_SYS_DLOPEN_DEPLIBS + + +# AC_LTDL_SHLIBEXT +# ---------------- +AC_DEFUN([AC_LTDL_SHLIBEXT], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([which extension is used for loadable modules], + [libltdl_cv_shlibext], +[ +module=yes +eval libltdl_cv_shlibext=$shrext + ]) +if test -n "$libltdl_cv_shlibext"; then + AC_DEFINE_UNQUOTED(LTDL_SHLIB_EXT, "$libltdl_cv_shlibext", + [Define to the extension used for shared libraries, say, ".so".]) +fi +])# AC_LTDL_SHLIBEXT + + +# AC_LTDL_SHLIBPATH +# ----------------- +AC_DEFUN([AC_LTDL_SHLIBPATH], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([which variable specifies run-time library path], + [libltdl_cv_shlibpath_var], [libltdl_cv_shlibpath_var="$shlibpath_var"]) +if test -n "$libltdl_cv_shlibpath_var"; then + AC_DEFINE_UNQUOTED(LTDL_SHLIBPATH_VAR, "$libltdl_cv_shlibpath_var", + [Define to the name of the environment variable that determines the dynamic library search path.]) +fi +])# AC_LTDL_SHLIBPATH + + +# AC_LTDL_SYSSEARCHPATH +# --------------------- +AC_DEFUN([AC_LTDL_SYSSEARCHPATH], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([for the default library search path], + [libltdl_cv_sys_search_path], + [libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec"]) +if test -n "$libltdl_cv_sys_search_path"; then + sys_search_path= + for dir in $libltdl_cv_sys_search_path; do + if test -z "$sys_search_path"; then + sys_search_path="$dir" + else + sys_search_path="$sys_search_path$PATH_SEPARATOR$dir" + fi + done + AC_DEFINE_UNQUOTED(LTDL_SYSSEARCHPATH, "$sys_search_path", + [Define to the system default library search path.]) +fi +])# AC_LTDL_SYSSEARCHPATH + + +# AC_LTDL_OBJDIR +# -------------- +AC_DEFUN([AC_LTDL_OBJDIR], +[AC_CACHE_CHECK([for objdir], + [libltdl_cv_objdir], + [libltdl_cv_objdir="$objdir" + if test -n "$objdir"; then + : + else + rm -f .libs 2>/dev/null + mkdir .libs 2>/dev/null + if test -d .libs; then + libltdl_cv_objdir=.libs + else + # MS-DOS does not allow filenames that begin with a dot. + libltdl_cv_objdir=_libs + fi + rmdir .libs 2>/dev/null + fi + ]) +AC_DEFINE_UNQUOTED(LTDL_OBJDIR, "$libltdl_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# AC_LTDL_OBJDIR + + +# AC_LTDL_DLPREOPEN +# ----------------- +AC_DEFUN([AC_LTDL_DLPREOPEN], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) +AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], + [libltdl_cv_preloaded_symbols], + [if test -n "$lt_cv_sys_global_symbol_pipe"; then + libltdl_cv_preloaded_symbols=yes + else + libltdl_cv_preloaded_symbols=no + fi + ]) +if test x"$libltdl_cv_preloaded_symbols" = xyes; then + AC_DEFINE(HAVE_PRELOADED_SYMBOLS, 1, + [Define if libtool can extract symbol lists from object files.]) +fi +])# AC_LTDL_DLPREOPEN + + +# AC_LTDL_DLLIB +# ------------- +AC_DEFUN([AC_LTDL_DLLIB], +[LIBADD_DL= +AC_SUBST(LIBADD_DL) +AC_LANG_PUSH([C]) + +AC_CHECK_FUNC([shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.])], + [AC_CHECK_LIB([dld], [shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LIBADD_DL="$LIBADD_DL -ldld"], + [AC_CHECK_LIB([dl], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DL="-ldl" libltdl_cv_lib_dl_dlopen="yes"], + [AC_TRY_LINK([#if HAVE_DLFCN_H +# include +#endif + ], + [dlopen(0, 0);], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) libltdl_cv_func_dlopen="yes"], + [AC_CHECK_LIB([svld], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DL="-lsvld" libltdl_cv_func_dlopen="yes"], + [AC_CHECK_LIB([dld], [dld_link], + [AC_DEFINE([HAVE_DLD], [1], + [Define if you have the GNU dld library.]) + LIBADD_DL="$LIBADD_DL -ldld"], + [AC_CHECK_FUNC([_dyld_func_lookup], + [AC_DEFINE([HAVE_DYLD], [1], + [Define if you have the _dyld_func_lookup function.])]) + ]) + ]) + ]) + ]) + ]) +]) + +if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes +then + lt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + AC_CHECK_FUNCS([dlerror]) + LIBS="$lt_save_LIBS" +fi +AC_LANG_POP +])# AC_LTDL_DLLIB + + +# AC_LTDL_SYMBOL_USCORE +# --------------------- +# does the compiler prefix global symbols with an underscore? +AC_DEFUN([AC_LTDL_SYMBOL_USCORE], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) +AC_CACHE_CHECK([for _ prefix in compiled symbols], + [ac_cv_sys_symbol_underscore], + [ac_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext < $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC + fi + rm -rf conftest* + ]) +])# AC_LTDL_SYMBOL_USCORE + + +# AC_LTDL_DLSYM_USCORE +# -------------------- +AC_DEFUN([AC_LTDL_DLSYM_USCORE], +[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) +if test x"$ac_cv_sys_symbol_underscore" = xyes; then + if test x"$libltdl_cv_func_dlopen" = xyes || + test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then + AC_CACHE_CHECK([whether we have to add an underscore for dlsym], + [libltdl_cv_need_uscore], + [libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + _LT_AC_TRY_DLOPEN_SELF( + [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], + [], [libltdl_cv_need_uscore=cross]) + LIBS="$save_LIBS" + ]) + fi +fi + +if test x"$libltdl_cv_need_uscore" = xyes; then + AC_DEFINE(NEED_USCORE, 1, + [Define if dlsym() requires a leading underscore in symbol names.]) +fi +])# AC_LTDL_DLSYM_USCORE + +# AC_LTDL_FUNC_ARGZ +# ----------------- +AC_DEFUN([AC_LTDL_FUNC_ARGZ], +[AC_CHECK_HEADERS([argz.h]) + +AC_CHECK_TYPES([error_t], + [], + [AC_DEFINE([error_t], [int], + [Define to a type to use for `error_t' if it is not otherwise available.])], + [#if HAVE_ARGZ_H +# include +#endif]) + +AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next argz_stringify]) +])# AC_LTDL_FUNC_ARGZ + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant . +# +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT +])], + [$4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/bochs/bios/BIOS-bochs-latest b/bochs/bios/BIOS-bochs-latest new file mode 100644 index 00000000..88771631 Binary files /dev/null and b/bochs/bios/BIOS-bochs-latest differ diff --git a/bochs/bios/BIOS-bochs-legacy b/bochs/bios/BIOS-bochs-legacy new file mode 100644 index 00000000..dc03df3b Binary files /dev/null and b/bochs/bios/BIOS-bochs-legacy differ diff --git a/bochs/bios/Makefile.in b/bochs/bios/Makefile.in new file mode 100644 index 00000000..a0320b8d --- /dev/null +++ b/bochs/bios/Makefile.in @@ -0,0 +1,120 @@ +# Copyright (C) 2001 MandrakeSoft S.A. +# +# MandrakeSoft S.A. +# 43, rue d'Aboukir +# 75002 Paris - France +# http://www.linux-mandrake.com/ +# http://www.mandrakesoft.com/ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +# Makefile for the BIOS component of bochs + + +@SUFFIX_LINE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +SHELL = /bin/sh + +@SET_MAKE@ + +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ + +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +RANLIB = @RANLIB@ + +BCC = bcc +GCC = gcc +GCC32 = gcc -m32 -fno-stack-protector +AS86 = as86 + +BX_INCDIRS = -I.. -I$(srcdir)/.. -I../iodev -I$(srcdir)/../iodev +LOCAL_CXXFLAGS = + +BUILDDATE = `date '+%m/%d/%y'` +BIOS_BUILD_DATE = "-DBIOS_BUILD_DATE=\"$(BUILDDATE)\"" +# +# -------- end configurable options -------------------------- +# + + +.@CPP_SUFFIX@.o: + $(CXX) -c $(BX_INCDIRS) $(CXXFLAGS) $(LOCAL_CXXFLAGS) @CXXFP@$< @OFP@$@ + + +bios: biossums BIOS-bochs-latest BIOS-bochs-legacy + +clean: + @RMCOMMAND@ *.o *.a *.s _rombios*_.c rombios*.txt rombios*.sym + @RMCOMMAND@ usage biossums rombios16.bin + @RMCOMMAND@ rombios32.bin rombios32.out + +dist-clean: clean + @RMCOMMAND@ Makefile + +bios-clean: + @RMCOMMAND@ BIOS-bochs-* + +BIOS-bochs-legacy: rombios.c apmbios.S biossums rombios.h + $(GCC32) $(BIOS_BUILD_DATE) -DLEGACY -E -P $< > _rombiosl_.c + $(BCC) -o rombiosl.s -C-c -D__i86__ -0 -S _rombiosl_.c + sed -e 's/^\.text//' -e 's/^\.data//' rombiosl.s > _rombiosl_.s + $(AS86) _rombiosl_.s -b tmpl.bin -u- -w- -g -0 -j -O -l rombiosl.txt + -perl ${srcdir}/makesym.perl < rombiosl.txt > rombiosl.sym + mv tmpl.bin $@ + ./biossums $@ + @RMCOMMAND@ _rombiosl_.s + + +rombios16.bin: rombios.c apmbios.S biossums rombios.h + $(GCC32) $(BIOS_BUILD_DATE) -E -P $< > _rombios_.c + $(BCC) -o rombios.s -C-c -D__i86__ -0 -S _rombios_.c + sed -e 's/^\.text//' -e 's/^\.data//' rombios.s > _rombios_.s + $(AS86) _rombios_.s -b tmp.bin -u- -w- -g -0 -j -O -l rombios.txt + -perl ${srcdir}/makesym.perl < rombios.txt > rombios.sym + mv tmp.bin rombios16.bin + ./biossums rombios16.bin + @RMCOMMAND@ _rombios_.s + + +rombios32.bin: rombios32.out rombios.h + objcopy -O binary $< $@ + ./biossums -pad $@ + +rombios32.out: rombios32start.o rombios32.o rombios32.ld + ld -o $@ -T $(srcdir)/rombios32.ld rombios32start.o rombios32.o + +rombios32.o: rombios32.c acpi-dsdt.hex rombios.h + $(GCC32) -O2 -Wall -c -o $@ $< + +ifeq ("1", "0") +acpi-dsdt.hex: acpi-dsdt.dsl + cpp -P $< $<.i + iasl -tc -p $@ $<.i + rm $<.i + sed -i -e's/^unsigned/const unsigned/' $@ +endif + +rombios32start.o: rombios32start.S + $(GCC32) -c -o $@ $< + +BIOS-bochs-latest: rombios16.bin rombios32.bin + cat rombios32.bin rombios16.bin > $@ + +biossums: biossums.o diff --git a/bochs/bios/VGABIOS-elpin-2.40 b/bochs/bios/VGABIOS-elpin-2.40 new file mode 100644 index 00000000..fc3d99dc Binary files /dev/null and b/bochs/bios/VGABIOS-elpin-2.40 differ diff --git a/bochs/bios/VGABIOS-elpin-LICENSE b/bochs/bios/VGABIOS-elpin-LICENSE new file mode 100644 index 00000000..0ba5717a --- /dev/null +++ b/bochs/bios/VGABIOS-elpin-LICENSE @@ -0,0 +1,9 @@ +The VGA BIOS from Elpin Systems, Inc. (http://www.elpin.com/) +is now permanently licensed for use with bochs, courtesy +of MandrakeSoft, creators of the leading "Linux-Mandrake" +distribution (http://www.linux-mandrake.com/). You may +freely use/distribute it with bochs, as long as it is used +in bochs for the intended use as a VGA BIOS. + +Please check out Elpin Systems. They make cool software games, +educational software, and VGA development products. diff --git a/bochs/bios/VGABIOS-lgpl-README b/bochs/bios/VGABIOS-lgpl-README new file mode 100644 index 00000000..c68b5734 --- /dev/null +++ b/bochs/bios/VGABIOS-lgpl-README @@ -0,0 +1,226 @@ +Plex86/Bochs VGABios +-------------------- + +The goal of this project is to have a LGPL'd Video Bios in plex86, +Bochs and qemu. +This VGA Bios is very specific to the emulated VGA card. +It is NOT meant to drive a physical vga card. + + +Cirrus SVGA extension +--------------------- + +The Cirrus SVGA extension is designed for the Cirrus emulation in Bochs and +qemu. The initial patch for the Cirrus extension has been written by Makoto +Suzuki (suzu). + + +Install +------- +To compile the VGA Bios you will need : +- gcc +- bcc +- as86 +- ld86 + +Untar the archive, and type make. You should get a "VGABIOS-lgpl-latest.bin" +file. Alternatively, you can use the binary file "VGABIOS-lgpl-latest.bin", +i have compiled for you. + +Edit your plex86/bochs conf file, and modify the load-rom command in the +VGA BIOS section, to point to the new vgabios image file. + + +Debugging +--------- +You can get a very basic debugging system: messages printed by the vgabios. +You have to register the "unmapped" device driver in plex86 or bochs, and make +sure it grabs port 0xfff0. + +Comment the #undef DEBUG at the beginning of vgabios.c. +You can then use the "printf" function in the bios. + + +Testing +------- +Look at the "testvga.c" file in the archive. This is a minimal Turbo C 2.0 +source file that calls a few int10 functions. Feel free to modify it to suit +your needs. + + +Copyright and License +--------------------- +This program has been written by Christophe Bothamy +It is protected by the GNU Lesser Public License, which you should +have received a copy of along with this package. + + +Reverse Engineering +------------------- +The VGA Bios has been written without reverse-engineering any existing Bios. + + +Acknowledgment +-------------- +The source code contains code ripped from rombios.c of plex86, written +by Kevin Lawton + +The source code contains fonts from fntcol16.zip (c) by Joseph Gil avalable at : +ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip +These fonts are public domain + +The source code is based on information taken from : +- Kevin Lawton's vga card emulation for bochs/plex86 +- Ralf Brown's interrupts list avalaible at + http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html +- Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ +- Michael Abrash's Graphics Programming Black Book +- Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" + edited by sybex +- DOSEMU 1.0.1 source code for several tables values and formulas + + +Feedback +-------- +Please report any bugs, comments, patches for this VGA Bios to info@vruppert.de +You can find the latest release at : http://www.nongnu.org/vgabios/ +For any information on bochs, visit the website http://bochs.sourceforge.net/ +For any information on qemu, visit the website http://fabrice.bellard.free.fr/qemu/ + + +History +------- +vgabios-0.6c : Apr 08 2009 + - Volker + . added DPMS support to cirrus vgabios (patch from Gleb Natapov) + . use VBE LFB address from PCI base address if present + . added support for a lot more non-standard VBE modes (e.g. widescreen modes) + . minor bugfixes + +vgabios-0.6b : May 30 2008 + - Volker + . added PCI data structure for the Cirrus VGABIOS images + . minor bugfixes in biossums utility, VBE support and makefile + +vgabios-0.6a : Aug 19 2006 + - Volker + . added minimal support for the video parameter table (VPT) + . Cirrus SVGA now supports the "no clear" bit in Cirrus and VESA mode + . Bochs VBE protected mode interface improved + . save/restore video state support for Bochs VBE and standard VGA added + . generate vbetables.h dynamicly + . VBE video memory increased to 8 MB (VBE dispi ID changed to B0C4) + . lots of 4bpp VBE fixes (all 4bpp VBE modes now enabled) + . VGA compatible setup for VBE modes added + +vgabios-0.5d : Dec 29 2005 + - Volker + . Bochs VBE protected mode interface added (based on a patch by malc@pulsesoft.com) + . biossums utility now supports VGABIOS sizes up to 64 kBytes + . VGA mode 0x11: all color planes must be enabled in this 2-color VGA mode + +vgabios-0.5c : Jul 07 2005 + - Volker + . BIOS configuration word usually reports initial mode 80x25 color text + . vgabios function 0x0e (write teletype): linefeed (0x0a) only increments the + cursor row value + +vgabios-0.5b : May 24 2005 + - Volker + . fixed return value for the default case in the VBE section (non-debug mode) + . removed unused stuff + +vgabios-0.5a : Mar 07 2005 + - Volker + . Cirrus SVGA extension (initial patches from Makoto Suzuki, improvements + from Fabrice Bellard) + . vgabios image size is now exactly 32k with a checksum + . a lot of vgabios and vbe functions rewritten in assembler + . dynamicly generated VBE mode info list + . write character function for CGA and LINEAR8 modes + . read/write graphics pixel for some graphics modes + . text scroll feature for some graphics modes + . VBE 8-bit DAC support + +vgabios-0.4c : Nov 06 2003 + - Christophe + . fix font problem on initial screen of NT4 Loader + +vgabios-0.4b : Nov 04 2003 + - Volker + . fix offset of character tables + . optimizations of CRT controller accesses + . VBE i/o registers changed to 0x01CE/CF + (suggestion from Daniel Gimpelevich) + . "noclear" flag stored in BIOS area + . fix character height returned by get_font_info function + +vgabios-0.4a : Aug 17 2003 + - Volker + . VBE mode search rewritten (VBE modes with LFB bit removed) + . many bugfixes and optimizations + . write character function implemented for graphics modes + . support for 15bpp, 16bpp, 24bpp and 32bpp VBE modes added + . SVGA mode 0x6A added + . VBE modes 0x102, 0x117, 0x118 and 0x142 (Bochs specific) + +vgabios-0.3b : Nov 23 2002 + - Christophe + . added lfb-mode numbers (patch from mathis) + . updated the Makefile + . removed display of copyrights. + . changed the Copyright string to "LGPL VGABios developers" + - Volker + . set the cursor shape depending on the current font height + . clear BL before calling int 0x10 function 0x1103 in vgabios_init_func + . added some text font functions + - Jeroen + . Forced to new DISPI (0xb0c1) interface (requires latest bochs vbe code) + . Added multibuffering support + . Added new DISPI interface for: virt width, height, x offset, y offset + . Added LFB modes (to be used with the vbe-lfb patch in bochs) + see VBE_HAVE_LFB in vbe.c (currently default enabled) + . updated TODO & docs for changes after bochs 1.4 + +vgabios-0.3a : Mar 10 2002 + - Christophe + . Fixed bug in function ah=13 + - Jeroen + . updated vbebios implementation to new api + . added vbe_display_api documentation + . added 640x400x8, 640x480x8, 800x600x8, 1024x768 + (>640x480 needs a special bochs patch atm) + . added 320x200x8 vbe support (uses the standard 320x200x8 vga mode to + display, this allows for testing & having something on screen as well, + at least until bochs host side display is up & running) + . adding lfbprof (vbe) testprogram (+some small fixes to it) + . merging with vbebios 0.2 + +vgabios-0.2b : Nov 19 2001 + - Christophe + . Fixed bug in function ah=13 + +vgabios-0.2a : Nov 09 2001 + - Christophe + . Included bugfix from techt@pikeonline.net about grayscale summing + . Added the "IBM" string at org 0x1e as Bart Oldeman suggested + . Fixed DS and ES that where inverted in the int10 parameters list! + . The following have been implemented : + - function ax=1a00, ax=1a01, ah=1b + - function ax=1130 + . Added debug messages for unimplemented/unknown functions + Must be compiled with DEBUG defined. The output is trapped + by the unknown-ioport driver of plex/bochs (port 0xfff0 is used) + +vgabios-0.1a : May 8 2001 + - Christophe + . First release. The work has been focused only on text mode. + . The following have been implemented : + - inits + - int 10 handler + - functions ah=00, ah=01, ah=02, ah=03, ah=05, ah=06, ah=07, ah=08 + ah=09, ah=0a, ah=0e, ah=0f, ax=1000, ax=1001, ax=1002, ax=1003 + ax=1007, ax=1008, ax=1009, ax=1010, ax=1012, ax=1013, ax=1015 + ax=1017, ax=1018, ax=1019, ax=101a, ax=101b, ah=12 bl=10, + ah=12 bl=30, ah=12 bl=31, ah=12 bl=32, ah=12 bl=33, ah=12 bl=34 + ah=13 diff --git a/bochs/bios/VGABIOS-lgpl-latest b/bochs/bios/VGABIOS-lgpl-latest new file mode 100644 index 00000000..a6c56a56 Binary files /dev/null and b/bochs/bios/VGABIOS-lgpl-latest differ diff --git a/bochs/bios/VGABIOS-lgpl-latest-cirrus b/bochs/bios/VGABIOS-lgpl-latest-cirrus new file mode 100644 index 00000000..60b62874 Binary files /dev/null and b/bochs/bios/VGABIOS-lgpl-latest-cirrus differ diff --git a/bochs/bios/VGABIOS-lgpl-latest-cirrus-debug b/bochs/bios/VGABIOS-lgpl-latest-cirrus-debug new file mode 100644 index 00000000..d321b9c1 Binary files /dev/null and b/bochs/bios/VGABIOS-lgpl-latest-cirrus-debug differ diff --git a/bochs/bios/VGABIOS-lgpl-latest-debug b/bochs/bios/VGABIOS-lgpl-latest-debug new file mode 100644 index 00000000..668f9788 Binary files /dev/null and b/bochs/bios/VGABIOS-lgpl-latest-debug differ diff --git a/bochs/bios/acpi-dsdt.dsl b/bochs/bios/acpi-dsdt.dsl new file mode 100644 index 00000000..9762c2a9 --- /dev/null +++ b/bochs/bios/acpi-dsdt.dsl @@ -0,0 +1,594 @@ +/* + * Bochs/QEMU ACPI DSDT ASL definition + * + * Copyright (c) 2006 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +DefinitionBlock ( + "acpi-dsdt.aml", // Output Filename + "DSDT", // Signature + 0x01, // DSDT Compliance Revision + "BXPC", // OEMID + "BXDSDT", // TABLE ID + 0x1 // OEM Revision + ) +{ + Scope (\) + { + /* Debug Output */ + OperationRegion (DBG, SystemIO, 0xb044, 0x04) + Field (DBG, DWordAcc, NoLock, Preserve) + { + DBGL, 32, + } + } + + + /* PCI Bus definition */ + Scope(\_SB) { + Device(PCI0) { + Name (_HID, EisaId ("PNP0A03")) + Name (_ADR, 0x00) + Name (_UID, 1) + Name(_PRT, Package() { + /* PCI IRQ routing table, example from ACPI 2.0a specification, + section 6.2.8.1 */ + /* Note: we provide the same info as the PCI routing + table of the Bochs BIOS */ + + // PCI Slot 0 + Package() {0x0000ffff, 0, LNKD, 0}, + Package() {0x0000ffff, 1, LNKA, 0}, + Package() {0x0000ffff, 2, LNKB, 0}, + Package() {0x0000ffff, 3, LNKC, 0}, + + // PCI Slot 1 + Package() {0x0001ffff, 0, LNKA, 0}, + Package() {0x0001ffff, 1, LNKB, 0}, + Package() {0x0001ffff, 2, LNKC, 0}, + Package() {0x0001ffff, 3, LNKD, 0}, + + // PCI Slot 2 + Package() {0x0002ffff, 0, LNKB, 0}, + Package() {0x0002ffff, 1, LNKC, 0}, + Package() {0x0002ffff, 2, LNKD, 0}, + Package() {0x0002ffff, 3, LNKA, 0}, + + // PCI Slot 3 + Package() {0x0003ffff, 0, LNKC, 0}, + Package() {0x0003ffff, 1, LNKD, 0}, + Package() {0x0003ffff, 2, LNKA, 0}, + Package() {0x0003ffff, 3, LNKB, 0}, + + // PCI Slot 4 + Package() {0x0004ffff, 0, LNKD, 0}, + Package() {0x0004ffff, 1, LNKA, 0}, + Package() {0x0004ffff, 2, LNKB, 0}, + Package() {0x0004ffff, 3, LNKC, 0}, + + // PCI Slot 5 + Package() {0x0005ffff, 0, LNKA, 0}, + Package() {0x0005ffff, 1, LNKB, 0}, + Package() {0x0005ffff, 2, LNKC, 0}, + Package() {0x0005ffff, 3, LNKD, 0}, + }) + + Name (_CRS, ResourceTemplate () + { + WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, // Address Space Granularity + 0x0000, // Address Range Minimum + 0x00FF, // Address Range Maximum + 0x0000, // Address Translation Offset + 0x0100, // Address Length + ,, ) + IO (Decode16, + 0x0CF8, // Address Range Minimum + 0x0CF8, // Address Range Maximum + 0x01, // Address Alignment + 0x08, // Address Length + ) + WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, // Address Space Granularity + 0x0000, // Address Range Minimum + 0x0CF7, // Address Range Maximum + 0x0000, // Address Translation Offset + 0x0CF8, // Address Length + ,, , TypeStatic) + WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, // Address Space Granularity + 0x0D00, // Address Range Minimum + 0xFFFF, // Address Range Maximum + 0x0000, // Address Translation Offset + 0xF300, // Address Length + ,, , TypeStatic) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, + 0x00000000, // Address Space Granularity + 0x000A0000, // Address Range Minimum + 0x000BFFFF, // Address Range Maximum + 0x00000000, // Address Translation Offset + 0x00020000, // Address Length + ,, , AddressRangeMemory, TypeStatic) + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, + 0x00000000, // Address Space Granularity + 0xC0000000, // Address Range Minimum + 0xFEBFFFFF, // Address Range Maximum + 0x00000000, // Address Translation Offset + 0x3EC00000, // Address Length + ,, , AddressRangeMemory, TypeStatic) + }) + } +#ifdef BX_QEMU + Device(HPET) { + Name(_HID, EISAID("PNP0103")) + Name(_UID, 0) + Method (_STA, 0, NotSerialized) { + Return(0x0F) + } + Name(_CRS, ResourceTemplate() { + DWordMemory( + ResourceConsumer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x00000000, + 0xFED00000, + 0xFED003FF, + 0x00000000, + 0x00000400 /* 1K memory: FED00000 - FED003FF */ + ) + }) + } +#endif + } + + Scope(\_SB.PCI0) { + Device (VGA) { + Name (_ADR, 0x00020000) + Method (_S1D, 0, NotSerialized) + { + Return (0x00) + } + Method (_S2D, 0, NotSerialized) + { + Return (0x00) + } + Method (_S3D, 0, NotSerialized) + { + Return (0x00) + } + } + + /* PIIX3 ISA bridge */ + Device (ISA) { + Name (_ADR, 0x00010000) + + /* PIIX PCI to ISA irq remapping */ + OperationRegion (P40C, PCI_Config, 0x60, 0x04) + + /* Real-time clock */ + Device (RTC) + { + Name (_HID, EisaId ("PNP0B00")) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x0070, 0x0070, 0x10, 0x02) + IRQNoFlags () {8} + IO (Decode16, 0x0072, 0x0072, 0x02, 0x06) + }) + } + + /* Keyboard seems to be important for WinXP install */ + Device (KBD) + { + Name (_HID, EisaId ("PNP0303")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () + { + IO (Decode16, + 0x0060, // Address Range Minimum + 0x0060, // Address Range Maximum + 0x01, // Address Alignment + 0x01, // Address Length + ) + IO (Decode16, + 0x0064, // Address Range Minimum + 0x0064, // Address Range Maximum + 0x01, // Address Alignment + 0x01, // Address Length + ) + IRQNoFlags () + {1} + }) + Return (TMP) + } + } + + /* PS/2 mouse */ + Device (MOU) + { + Name (_HID, EisaId ("PNP0F13")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () + { + IRQNoFlags () {12} + }) + Return (TMP) + } + } + + /* PS/2 floppy controller */ + Device (FDC0) + { + Name (_HID, EisaId ("PNP0700")) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } + Method (_CRS, 0, NotSerialized) + { + Name (BUF0, ResourceTemplate () + { + IO (Decode16, 0x03F2, 0x03F2, 0x00, 0x04) + IO (Decode16, 0x03F7, 0x03F7, 0x00, 0x01) + IRQNoFlags () {6} + DMA (Compatibility, NotBusMaster, Transfer8) {2} + }) + Return (BUF0) + } + } + + /* Parallel port */ + Device (LPT) + { + Name (_HID, EisaId ("PNP0400")) + Method (_STA, 0, NotSerialized) + { + Store (\_SB.PCI0.PX13.DRSA, Local0) + And (Local0, 0x80000000, Local0) + If (LEqual (Local0, 0)) + { + Return (0x00) + } + Else + { + Return (0x0F) + } + } + Method (_CRS, 0, NotSerialized) + { + Name (BUF0, ResourceTemplate () + { + IO (Decode16, 0x0378, 0x0378, 0x08, 0x08) + IRQNoFlags () {7} + }) + Return (BUF0) + } + } + + /* Serial Ports */ + Device (COM1) + { + Name (_HID, EisaId ("PNP0501")) + Name (_UID, 0x01) + Method (_STA, 0, NotSerialized) + { + Store (\_SB.PCI0.PX13.DRSC, Local0) + And (Local0, 0x08000000, Local0) + If (LEqual (Local0, 0)) + { + Return (0x00) + } + Else + { + Return (0x0F) + } + } + Method (_CRS, 0, NotSerialized) + { + Name (BUF0, ResourceTemplate () + { + IO (Decode16, 0x03F8, 0x03F8, 0x00, 0x08) + IRQNoFlags () {4} + }) + Return (BUF0) + } + } + + Device (COM2) + { + Name (_HID, EisaId ("PNP0501")) + Name (_UID, 0x02) + Method (_STA, 0, NotSerialized) + { + Store (\_SB.PCI0.PX13.DRSC, Local0) + And (Local0, 0x80000000, Local0) + If (LEqual (Local0, 0)) + { + Return (0x00) + } + Else + { + Return (0x0F) + } + } + Method (_CRS, 0, NotSerialized) + { + Name (BUF0, ResourceTemplate () + { + IO (Decode16, 0x02F8, 0x02F8, 0x00, 0x08) + IRQNoFlags () {3} + }) + Return (BUF0) + } + } + } + + /* PIIX4 PM */ + Device (PX13) { + Name (_ADR, 0x00010003) + + OperationRegion (P13C, PCI_Config, 0x5c, 0x24) + Field (P13C, DWordAcc, NoLock, Preserve) + { + DRSA, 32, + DRSB, 32, + DRSC, 32, + DRSE, 32, + DRSF, 32, + DRSG, 32, + DRSH, 32, + DRSI, 32, + DRSJ, 32 + } + } + } + + /* PCI IRQs */ + Scope(\_SB) { + Field (\_SB.PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) + { + PRQ0, 8, + PRQ1, 8, + PRQ2, 8, + PRQ3, 8 + } + + Device(LNKA){ + Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link + Name(_UID, 1) + Name(_PRS, ResourceTemplate(){ + IRQ (Level, ActiveLow, Shared) + {3,4,5,6,7,9,10,11,12} + }) + Method (_STA, 0, NotSerialized) + { + Store (0x0B, Local0) + If (And (0x80, PRQ0, Local1)) + { + Store (0x09, Local0) + } + Return (Local0) + } + Method (_DIS, 0, NotSerialized) + { + Or (PRQ0, 0x80, PRQ0) + } + Method (_CRS, 0, NotSerialized) + { + Name (PRR0, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) + {1} + }) + CreateWordField (PRR0, 0x01, TMP) + Store (PRQ0, Local0) + If (LLess (Local0, 0x80)) + { + ShiftLeft (One, Local0, TMP) + } + Else + { + Store (Zero, TMP) + } + Return (PRR0) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, 0x01, TMP) + FindSetRightBit (TMP, Local0) + Decrement (Local0) + Store (Local0, PRQ0) + } + } + Device(LNKB){ + Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link + Name(_UID, 2) + Name(_PRS, ResourceTemplate(){ + IRQ (Level, ActiveLow, Shared) + {3,4,5,6,7,9,10,11,12} + }) + Method (_STA, 0, NotSerialized) + { + Store (0x0B, Local0) + If (And (0x80, PRQ1, Local1)) + { + Store (0x09, Local0) + } + Return (Local0) + } + Method (_DIS, 0, NotSerialized) + { + Or (PRQ1, 0x80, PRQ1) + } + Method (_CRS, 0, NotSerialized) + { + Name (PRR0, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) + {1} + }) + CreateWordField (PRR0, 0x01, TMP) + Store (PRQ1, Local0) + If (LLess (Local0, 0x80)) + { + ShiftLeft (One, Local0, TMP) + } + Else + { + Store (Zero, TMP) + } + Return (PRR0) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, 0x01, TMP) + FindSetRightBit (TMP, Local0) + Decrement (Local0) + Store (Local0, PRQ1) + } + } + Device(LNKC){ + Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link + Name(_UID, 3) + Name(_PRS, ResourceTemplate(){ + IRQ (Level, ActiveLow, Shared) + {3,4,5,6,7,9,10,11,12} + }) + Method (_STA, 0, NotSerialized) + { + Store (0x0B, Local0) + If (And (0x80, PRQ2, Local1)) + { + Store (0x09, Local0) + } + Return (Local0) + } + Method (_DIS, 0, NotSerialized) + { + Or (PRQ2, 0x80, PRQ2) + } + Method (_CRS, 0, NotSerialized) + { + Name (PRR0, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) + {1} + }) + CreateWordField (PRR0, 0x01, TMP) + Store (PRQ2, Local0) + If (LLess (Local0, 0x80)) + { + ShiftLeft (One, Local0, TMP) + } + Else + { + Store (Zero, TMP) + } + Return (PRR0) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, 0x01, TMP) + FindSetRightBit (TMP, Local0) + Decrement (Local0) + Store (Local0, PRQ2) + } + } + Device(LNKD){ + Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link + Name(_UID, 4) + Name(_PRS, ResourceTemplate(){ + IRQ (Level, ActiveLow, Shared) + {3,4,5,6,7,9,10,11,12} + }) + Method (_STA, 0, NotSerialized) + { + Store (0x0B, Local0) + If (And (0x80, PRQ3, Local1)) + { + Store (0x09, Local0) + } + Return (Local0) + } + Method (_DIS, 0, NotSerialized) + { + Or (PRQ3, 0x80, PRQ3) + } + Method (_CRS, 0, NotSerialized) + { + Name (PRR0, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) + {1} + }) + CreateWordField (PRR0, 0x01, TMP) + Store (PRQ3, Local0) + If (LLess (Local0, 0x80)) + { + ShiftLeft (One, Local0, TMP) + } + Else + { + Store (Zero, TMP) + } + Return (PRR0) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, 0x01, TMP) + FindSetRightBit (TMP, Local0) + Decrement (Local0) + Store (Local0, PRQ3) + } + } + } + + /* + * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes: + * must match piix4 emulation. + */ + Name (\_S3, Package (0x04) + { + 0x01, /* PM1a_CNT.SLP_TYP */ + 0x01, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + Name (\_S4, Package (0x04) + { + Zero, /* PM1a_CNT.SLP_TYP */ + Zero, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + Name (\_S5, Package (0x04) + { + Zero, /* PM1a_CNT.SLP_TYP */ + Zero, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) +} diff --git a/bochs/bios/acpi-dsdt.hex b/bochs/bios/acpi-dsdt.hex new file mode 100644 index 00000000..504f6bed --- /dev/null +++ b/bochs/bios/acpi-dsdt.hex @@ -0,0 +1,273 @@ +/* + * + * Intel ACPI Component Architecture + * ASL Optimizing Compiler version 20090320 [Oct 24 2009] + * Copyright (C) 2000 - 2009 Intel Corporation + * Supports ACPI Specification Revision 3.0a + * + * Compilation of "acpi-dsdt.dsl.i" - Sun Dec 20 15:20:28 2009 + * + * C source code output + * + */ +const unsigned char AmlCode[] = +{ + 0x44,0x53,0x44,0x54,0x0D,0x08,0x00,0x00, /* 00000000 "DSDT...." */ + 0x01,0x95,0x42,0x58,0x50,0x43,0x00,0x00, /* 00000008 "..BXPC.." */ + 0x42,0x58,0x44,0x53,0x44,0x54,0x00,0x00, /* 00000010 "BXDSDT.." */ + 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x20,0x03,0x09,0x20,0x10,0x1C,0x5C,0x00, /* 00000020 " .. ..\." */ + 0x5B,0x80,0x44,0x42,0x47,0x5F,0x01,0x0B, /* 00000028 "[.DBG_.." */ + 0x44,0xB0,0x0A,0x04,0x5B,0x81,0x0B,0x44, /* 00000030 "D...[..D" */ + 0x42,0x47,0x5F,0x03,0x44,0x42,0x47,0x4C, /* 00000038 "BG_.DBGL" */ + 0x20,0x10,0x49,0x1F,0x5F,0x53,0x42,0x5F, /* 00000040 " .I._SB_" */ + 0x5B,0x82,0x41,0x1F,0x50,0x43,0x49,0x30, /* 00000048 "[.A.PCI0" */ + 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000050 "._HID.A." */ + 0x0A,0x03,0x08,0x5F,0x41,0x44,0x52,0x00, /* 00000058 "..._ADR." */ + 0x08,0x5F,0x55,0x49,0x44,0x01,0x08,0x5F, /* 00000060 "._UID.._" */ + 0x50,0x52,0x54,0x12,0x47,0x15,0x18,0x12, /* 00000068 "PRT.G..." */ + 0x0B,0x04,0x0B,0xFF,0xFF,0x00,0x4C,0x4E, /* 00000070 "......LN" */ + 0x4B,0x44,0x00,0x12,0x0B,0x04,0x0B,0xFF, /* 00000078 "KD......" */ + 0xFF,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000080 "..LNKA.." */ + 0x0C,0x04,0x0B,0xFF,0xFF,0x0A,0x02,0x4C, /* 00000088 ".......L" */ + 0x4E,0x4B,0x42,0x00,0x12,0x0C,0x04,0x0B, /* 00000090 "NKB....." */ + 0xFF,0xFF,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000098 "....LNKC" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01, /* 000000A0 "........" */ + 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000000A8 "..LNKA.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01, /* 000000B0 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000000B8 "LNKB...." */ + 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x4C, /* 000000C0 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 000000C8 "NKC....." */ + 0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C,0x4E, /* 000000D0 "......LN" */ + 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000000D8 "KD......" */ + 0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 000000E0 "....LNKB" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02, /* 000000E8 "........" */ + 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000000F0 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 000000F8 "........" */ + 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 00000100 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03, /* 00000108 "........" */ + 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000110 "LNKA...." */ + 0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C,0x4E, /* 00000118 "......LN" */ + 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000120 "KC......" */ + 0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 00000128 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 00000130 "........" */ + 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 00000138 "...LNKA." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000140 "........" */ + 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000148 "..LNKB.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00, /* 00000150 "........" */ + 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000158 "LNKD...." */ + 0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C,0x4E, /* 00000160 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000168 "KA......" */ + 0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000170 ".....LNK" */ + 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000178 "B......." */ + 0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000180 "....LNKC" */ + 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05, /* 00000188 "........" */ + 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000190 "..LNKA.." */ + 0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01, /* 00000198 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000001A0 "LNKB...." */ + 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x4C, /* 000001A8 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 000001B0 "NKC....." */ + 0xFF,0xFF,0x05,0x00,0x0A,0x03,0x4C,0x4E, /* 000001B8 "......LN" */ + 0x4B,0x44,0x00,0x08,0x5F,0x43,0x52,0x53, /* 000001C0 "KD.._CRS" */ + 0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00, /* 000001C8 ".B..n..." */ + 0x02,0x0C,0x00,0x00,0x00,0x00,0x00,0xFF, /* 000001D0 "........" */ + 0x00,0x00,0x00,0x00,0x01,0x47,0x01,0xF8, /* 000001D8 ".....G.." */ + 0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00, /* 000001E0 "........" */ + 0x01,0x0C,0x03,0x00,0x00,0x00,0x00,0xF7, /* 000001E8 "........" */ + 0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00, /* 000001F0 "........" */ + 0x01,0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF, /* 000001F8 "........" */ + 0xFF,0x00,0x00,0x00,0xF3,0x87,0x17,0x00, /* 00000200 "........" */ + 0x00,0x0C,0x03,0x00,0x00,0x00,0x00,0x00, /* 00000208 "........" */ + 0x00,0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00, /* 00000210 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x87, /* 00000218 "........" */ + 0x17,0x00,0x00,0x0C,0x01,0x00,0x00,0x00, /* 00000220 "........" */ + 0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xBF, /* 00000228 "........" */ + 0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0xC0, /* 00000230 "........" */ + 0x3E,0x79,0x00,0x10,0x4D,0x2B,0x2E,0x5F, /* 00000238 ">y..M+._" */ + 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x5B, /* 00000240 "SB_PCI0[" */ + 0x82,0x2A,0x56,0x47,0x41,0x5F,0x08,0x5F, /* 00000248 ".*VGA_._" */ + 0x41,0x44,0x52,0x0C,0x00,0x00,0x02,0x00, /* 00000250 "ADR....." */ + 0x14,0x08,0x5F,0x53,0x31,0x44,0x00,0xA4, /* 00000258 ".._S1D.." */ + 0x00,0x14,0x08,0x5F,0x53,0x32,0x44,0x00, /* 00000260 "..._S2D." */ + 0xA4,0x00,0x14,0x08,0x5F,0x53,0x33,0x44, /* 00000268 "...._S3D" */ + 0x00,0xA4,0x00,0x5B,0x82,0x42,0x23,0x49, /* 00000270 "...[.B#I" */ + 0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,0x52, /* 00000278 "SA_._ADR" */ + 0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,0x50, /* 00000280 ".....[.P" */ + 0x34,0x30,0x43,0x02,0x0A,0x60,0x0A,0x04, /* 00000288 "40C..`.." */ + 0x5B,0x82,0x2D,0x52,0x54,0x43,0x5F,0x08, /* 00000290 "[.-RTC_." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B, /* 00000298 "_HID.A.." */ + 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 000002A0 ".._CRS.." */ + 0x0A,0x15,0x47,0x01,0x70,0x00,0x70,0x00, /* 000002A8 "..G.p.p." */ + 0x10,0x02,0x22,0x00,0x01,0x47,0x01,0x72, /* 000002B0 ".."..G.r" */ + 0x00,0x72,0x00,0x02,0x06,0x79,0x00,0x5B, /* 000002B8 ".r...y.[" */ + 0x82,0x44,0x04,0x4B,0x42,0x44,0x5F,0x08, /* 000002C0 ".D.KBD_." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x03, /* 000002C8 "_HID.A.." */ + 0x03,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 000002D0 "..._STA." */ + 0xA4,0x0A,0x0F,0x14,0x29,0x5F,0x43,0x52, /* 000002D8 "....)_CR" */ + 0x53,0x00,0x08,0x54,0x4D,0x50,0x5F,0x11, /* 000002E0 "S..TMP_." */ + 0x18,0x0A,0x15,0x47,0x01,0x60,0x00,0x60, /* 000002E8 "...G.`.`" */ + 0x00,0x01,0x01,0x47,0x01,0x64,0x00,0x64, /* 000002F0 "...G.d.d" */ + 0x00,0x01,0x01,0x22,0x02,0x00,0x79,0x00, /* 000002F8 "..."..y." */ + 0xA4,0x54,0x4D,0x50,0x5F,0x5B,0x82,0x33, /* 00000300 ".TMP_[.3" */ + 0x4D,0x4F,0x55,0x5F,0x08,0x5F,0x48,0x49, /* 00000308 "MOU_._HI" */ + 0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09, /* 00000310 "D.A....." */ + 0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000318 "_STA...." */ + 0x14,0x19,0x5F,0x43,0x52,0x53,0x00,0x08, /* 00000320 ".._CRS.." */ + 0x54,0x4D,0x50,0x5F,0x11,0x08,0x0A,0x05, /* 00000328 "TMP_...." */ + 0x22,0x00,0x10,0x79,0x00,0xA4,0x54,0x4D, /* 00000330 ""..y..TM" */ + 0x50,0x5F,0x5B,0x82,0x47,0x04,0x46,0x44, /* 00000338 "P_[.G.FD" */ + 0x43,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000340 "C0._HID." */ + 0x41,0xD0,0x07,0x00,0x14,0x09,0x5F,0x53, /* 00000348 "A....._S" */ + 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x14,0x2C, /* 00000350 "TA.....," */ + 0x5F,0x43,0x52,0x53,0x00,0x08,0x42,0x55, /* 00000358 "_CRS..BU" */ + 0x46,0x30,0x11,0x1B,0x0A,0x18,0x47,0x01, /* 00000360 "F0....G." */ + 0xF2,0x03,0xF2,0x03,0x00,0x04,0x47,0x01, /* 00000368 "......G." */ + 0xF7,0x03,0xF7,0x03,0x00,0x01,0x22,0x40, /* 00000370 "......"@" */ + 0x00,0x2A,0x04,0x00,0x79,0x00,0xA4,0x42, /* 00000378 ".*..y..B" */ + 0x55,0x46,0x30,0x5B,0x82,0x4B,0x05,0x4C, /* 00000380 "UF0[.K.L" */ + 0x50,0x54,0x5F,0x08,0x5F,0x48,0x49,0x44, /* 00000388 "PT_._HID" */ + 0x0C,0x41,0xD0,0x04,0x00,0x14,0x28,0x5F, /* 00000390 ".A....(_" */ + 0x53,0x54,0x41,0x00,0x70,0x5E,0x5E,0x5E, /* 00000398 "STA.p^^^" */ + 0x2E,0x50,0x58,0x31,0x33,0x44,0x52,0x53, /* 000003A0 ".PX13DRS" */ + 0x41,0x60,0x7B,0x60,0x0C,0x00,0x00,0x00, /* 000003A8 "A`{`...." */ + 0x80,0x60,0xA0,0x06,0x93,0x60,0x00,0xA4, /* 000003B0 ".`...`.." */ + 0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x14,0x21, /* 000003B8 ".......!" */ + 0x5F,0x43,0x52,0x53,0x00,0x08,0x42,0x55, /* 000003C0 "_CRS..BU" */ + 0x46,0x30,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 000003C8 "F0....G." */ + 0x78,0x03,0x78,0x03,0x08,0x08,0x22,0x80, /* 000003D0 "x.x..."." */ + 0x00,0x79,0x00,0xA4,0x42,0x55,0x46,0x30, /* 000003D8 ".y..BUF0" */ + 0x5B,0x82,0x41,0x06,0x43,0x4F,0x4D,0x31, /* 000003E0 "[.A.COM1" */ + 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 000003E8 "._HID.A." */ + 0x05,0x01,0x08,0x5F,0x55,0x49,0x44,0x01, /* 000003F0 "..._UID." */ + 0x14,0x28,0x5F,0x53,0x54,0x41,0x00,0x70, /* 000003F8 ".(_STA.p" */ + 0x5E,0x5E,0x5E,0x2E,0x50,0x58,0x31,0x33, /* 00000400 "^^^.PX13" */ + 0x44,0x52,0x53,0x43,0x60,0x7B,0x60,0x0C, /* 00000408 "DRSC`{`." */ + 0x00,0x00,0x00,0x08,0x60,0xA0,0x06,0x93, /* 00000410 "....`..." */ + 0x60,0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A, /* 00000418 "`......." */ + 0x0F,0x14,0x21,0x5F,0x43,0x52,0x53,0x00, /* 00000420 "..!_CRS." */ + 0x08,0x42,0x55,0x46,0x30,0x11,0x10,0x0A, /* 00000428 ".BUF0..." */ + 0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03,0x00, /* 00000430 ".G......" */ + 0x08,0x22,0x10,0x00,0x79,0x00,0xA4,0x42, /* 00000438 "."..y..B" */ + 0x55,0x46,0x30,0x5B,0x82,0x42,0x06,0x43, /* 00000440 "UF0[.B.C" */ + 0x4F,0x4D,0x32,0x08,0x5F,0x48,0x49,0x44, /* 00000448 "OM2._HID" */ + 0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55, /* 00000450 ".A...._U" */ + 0x49,0x44,0x0A,0x02,0x14,0x28,0x5F,0x53, /* 00000458 "ID...(_S" */ + 0x54,0x41,0x00,0x70,0x5E,0x5E,0x5E,0x2E, /* 00000460 "TA.p^^^." */ + 0x50,0x58,0x31,0x33,0x44,0x52,0x53,0x43, /* 00000468 "PX13DRSC" */ + 0x60,0x7B,0x60,0x0C,0x00,0x00,0x00,0x80, /* 00000470 "`{`....." */ + 0x60,0xA0,0x06,0x93,0x60,0x00,0xA4,0x00, /* 00000478 "`...`..." */ + 0xA1,0x04,0xA4,0x0A,0x0F,0x14,0x21,0x5F, /* 00000480 "......!_" */ + 0x43,0x52,0x53,0x00,0x08,0x42,0x55,0x46, /* 00000488 "CRS..BUF" */ + 0x30,0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8, /* 00000490 "0....G.." */ + 0x02,0xF8,0x02,0x00,0x08,0x22,0x08,0x00, /* 00000498 ".....".." */ + 0x79,0x00,0xA4,0x42,0x55,0x46,0x30,0x5B, /* 000004A0 "y..BUF0[" */ + 0x82,0x40,0x05,0x50,0x58,0x31,0x33,0x08, /* 000004A8 ".@.PX13." */ + 0x5F,0x41,0x44,0x52,0x0C,0x03,0x00,0x01, /* 000004B0 "_ADR...." */ + 0x00,0x5B,0x80,0x50,0x31,0x33,0x43,0x02, /* 000004B8 ".[.P13C." */ + 0x0A,0x5C,0x0A,0x24,0x5B,0x81,0x33,0x50, /* 000004C0 ".\.$[.3P" */ + 0x31,0x33,0x43,0x03,0x44,0x52,0x53,0x41, /* 000004C8 "13C.DRSA" */ + 0x20,0x44,0x52,0x53,0x42,0x20,0x44,0x52, /* 000004D0 " DRSB DR" */ + 0x53,0x43,0x20,0x44,0x52,0x53,0x45,0x20, /* 000004D8 "SC DRSE " */ + 0x44,0x52,0x53,0x46,0x20,0x44,0x52,0x53, /* 000004E0 "DRSF DRS" */ + 0x47,0x20,0x44,0x52,0x53,0x48,0x20,0x44, /* 000004E8 "G DRSH D" */ + 0x52,0x53,0x49,0x20,0x44,0x52,0x53,0x4A, /* 000004F0 "RSI DRSJ" */ + 0x20,0x10,0x4F,0x2E,0x5F,0x53,0x42,0x5F, /* 000004F8 " .O._SB_" */ + 0x5B,0x81,0x24,0x2F,0x03,0x50,0x43,0x49, /* 00000500 "[.$/.PCI" */ + 0x30,0x49,0x53,0x41,0x5F,0x50,0x34,0x30, /* 00000508 "0ISA_P40" */ + 0x43,0x01,0x50,0x52,0x51,0x30,0x08,0x50, /* 00000510 "C.PRQ0.P" */ + 0x52,0x51,0x31,0x08,0x50,0x52,0x51,0x32, /* 00000518 "RQ1.PRQ2" */ + 0x08,0x50,0x52,0x51,0x33,0x08,0x5B,0x82, /* 00000520 ".PRQ3.[." */ + 0x4E,0x0A,0x4C,0x4E,0x4B,0x41,0x08,0x5F, /* 00000528 "N.LNKA._" */ + 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 00000530 "HID.A..." */ + 0x08,0x5F,0x55,0x49,0x44,0x01,0x08,0x5F, /* 00000538 "._UID.._" */ + 0x50,0x52,0x53,0x11,0x09,0x0A,0x06,0x23, /* 00000540 "PRS....#" */ + 0xF8,0x1E,0x18,0x79,0x00,0x14,0x1A,0x5F, /* 00000548 "...y..._" */ + 0x53,0x54,0x41,0x00,0x70,0x0A,0x0B,0x60, /* 00000550 "STA.p..`" */ + 0xA0,0x0D,0x7B,0x0A,0x80,0x50,0x52,0x51, /* 00000558 "..{..PRQ" */ + 0x30,0x61,0x70,0x0A,0x09,0x60,0xA4,0x60, /* 00000560 "0ap..`.`" */ + 0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D, /* 00000568 ".._DIS.}" */ + 0x50,0x52,0x51,0x30,0x0A,0x80,0x50,0x52, /* 00000570 "PRQ0..PR" */ + 0x51,0x30,0x14,0x3F,0x5F,0x43,0x52,0x53, /* 00000578 "Q0.?_CRS" */ + 0x00,0x08,0x50,0x52,0x52,0x30,0x11,0x09, /* 00000580 "..PRR0.." */ + 0x0A,0x06,0x23,0x02,0x00,0x18,0x79,0x00, /* 00000588 "..#...y." */ + 0x8B,0x50,0x52,0x52,0x30,0x01,0x54,0x4D, /* 00000590 ".PRR0.TM" */ + 0x50,0x5F,0x70,0x50,0x52,0x51,0x30,0x60, /* 00000598 "P_pPRQ0`" */ + 0xA0,0x0C,0x95,0x60,0x0A,0x80,0x79,0x01, /* 000005A0 "...`..y." */ + 0x60,0x54,0x4D,0x50,0x5F,0xA1,0x07,0x70, /* 000005A8 "`TMP_..p" */ + 0x00,0x54,0x4D,0x50,0x5F,0xA4,0x50,0x52, /* 000005B0 ".TMP_.PR" */ + 0x52,0x30,0x14,0x1B,0x5F,0x53,0x52,0x53, /* 000005B8 "R0.._SRS" */ + 0x01,0x8B,0x68,0x01,0x54,0x4D,0x50,0x5F, /* 000005C0 "..h.TMP_" */ + 0x82,0x54,0x4D,0x50,0x5F,0x60,0x76,0x60, /* 000005C8 ".TMP_`v`" */ + 0x70,0x60,0x50,0x52,0x51,0x30,0x5B,0x82, /* 000005D0 "p`PRQ0[." */ + 0x4F,0x0A,0x4C,0x4E,0x4B,0x42,0x08,0x5F, /* 000005D8 "O.LNKB._" */ + 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 000005E0 "HID.A..." */ + 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x08, /* 000005E8 "._UID..." */ + 0x5F,0x50,0x52,0x53,0x11,0x09,0x0A,0x06, /* 000005F0 "_PRS...." */ + 0x23,0xF8,0x1E,0x18,0x79,0x00,0x14,0x1A, /* 000005F8 "#...y..." */ + 0x5F,0x53,0x54,0x41,0x00,0x70,0x0A,0x0B, /* 00000600 "_STA.p.." */ + 0x60,0xA0,0x0D,0x7B,0x0A,0x80,0x50,0x52, /* 00000608 "`..{..PR" */ + 0x51,0x31,0x61,0x70,0x0A,0x09,0x60,0xA4, /* 00000610 "Q1ap..`." */ + 0x60,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 00000618 "`.._DIS." */ + 0x7D,0x50,0x52,0x51,0x31,0x0A,0x80,0x50, /* 00000620 "}PRQ1..P" */ + 0x52,0x51,0x31,0x14,0x3F,0x5F,0x43,0x52, /* 00000628 "RQ1.?_CR" */ + 0x53,0x00,0x08,0x50,0x52,0x52,0x30,0x11, /* 00000630 "S..PRR0." */ + 0x09,0x0A,0x06,0x23,0x02,0x00,0x18,0x79, /* 00000638 "...#...y" */ + 0x00,0x8B,0x50,0x52,0x52,0x30,0x01,0x54, /* 00000640 "..PRR0.T" */ + 0x4D,0x50,0x5F,0x70,0x50,0x52,0x51,0x31, /* 00000648 "MP_pPRQ1" */ + 0x60,0xA0,0x0C,0x95,0x60,0x0A,0x80,0x79, /* 00000650 "`...`..y" */ + 0x01,0x60,0x54,0x4D,0x50,0x5F,0xA1,0x07, /* 00000658 ".`TMP_.." */ + 0x70,0x00,0x54,0x4D,0x50,0x5F,0xA4,0x50, /* 00000660 "p.TMP_.P" */ + 0x52,0x52,0x30,0x14,0x1B,0x5F,0x53,0x52, /* 00000668 "RR0.._SR" */ + 0x53,0x01,0x8B,0x68,0x01,0x54,0x4D,0x50, /* 00000670 "S..h.TMP" */ + 0x5F,0x82,0x54,0x4D,0x50,0x5F,0x60,0x76, /* 00000678 "_.TMP_`v" */ + 0x60,0x70,0x60,0x50,0x52,0x51,0x31,0x5B, /* 00000680 "`p`PRQ1[" */ + 0x82,0x4F,0x0A,0x4C,0x4E,0x4B,0x43,0x08, /* 00000688 ".O.LNKC." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000690 "_HID.A.." */ + 0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x03, /* 00000698 ".._UID.." */ + 0x08,0x5F,0x50,0x52,0x53,0x11,0x09,0x0A, /* 000006A0 "._PRS..." */ + 0x06,0x23,0xF8,0x1E,0x18,0x79,0x00,0x14, /* 000006A8 ".#...y.." */ + 0x1A,0x5F,0x53,0x54,0x41,0x00,0x70,0x0A, /* 000006B0 "._STA.p." */ + 0x0B,0x60,0xA0,0x0D,0x7B,0x0A,0x80,0x50, /* 000006B8 ".`..{..P" */ + 0x52,0x51,0x32,0x61,0x70,0x0A,0x09,0x60, /* 000006C0 "RQ2ap..`" */ + 0xA4,0x60,0x14,0x11,0x5F,0x44,0x49,0x53, /* 000006C8 ".`.._DIS" */ + 0x00,0x7D,0x50,0x52,0x51,0x32,0x0A,0x80, /* 000006D0 ".}PRQ2.." */ + 0x50,0x52,0x51,0x32,0x14,0x3F,0x5F,0x43, /* 000006D8 "PRQ2.?_C" */ + 0x52,0x53,0x00,0x08,0x50,0x52,0x52,0x30, /* 000006E0 "RS..PRR0" */ + 0x11,0x09,0x0A,0x06,0x23,0x02,0x00,0x18, /* 000006E8 "....#..." */ + 0x79,0x00,0x8B,0x50,0x52,0x52,0x30,0x01, /* 000006F0 "y..PRR0." */ + 0x54,0x4D,0x50,0x5F,0x70,0x50,0x52,0x51, /* 000006F8 "TMP_pPRQ" */ + 0x32,0x60,0xA0,0x0C,0x95,0x60,0x0A,0x80, /* 00000700 "2`...`.." */ + 0x79,0x01,0x60,0x54,0x4D,0x50,0x5F,0xA1, /* 00000708 "y.`TMP_." */ + 0x07,0x70,0x00,0x54,0x4D,0x50,0x5F,0xA4, /* 00000710 ".p.TMP_." */ + 0x50,0x52,0x52,0x30,0x14,0x1B,0x5F,0x53, /* 00000718 "PRR0.._S" */ + 0x52,0x53,0x01,0x8B,0x68,0x01,0x54,0x4D, /* 00000720 "RS..h.TM" */ + 0x50,0x5F,0x82,0x54,0x4D,0x50,0x5F,0x60, /* 00000728 "P_.TMP_`" */ + 0x76,0x60,0x70,0x60,0x50,0x52,0x51,0x32, /* 00000730 "v`p`PRQ2" */ + 0x5B,0x82,0x4F,0x0A,0x4C,0x4E,0x4B,0x44, /* 00000738 "[.O.LNKD" */ + 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000740 "._HID.A." */ + 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000748 "..._UID." */ + 0x04,0x08,0x5F,0x50,0x52,0x53,0x11,0x09, /* 00000750 ".._PRS.." */ + 0x0A,0x06,0x23,0xF8,0x1E,0x18,0x79,0x00, /* 00000758 "..#...y." */ + 0x14,0x1A,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00000760 ".._STA.p" */ + 0x0A,0x0B,0x60,0xA0,0x0D,0x7B,0x0A,0x80, /* 00000768 "..`..{.." */ + 0x50,0x52,0x51,0x33,0x61,0x70,0x0A,0x09, /* 00000770 "PRQ3ap.." */ + 0x60,0xA4,0x60,0x14,0x11,0x5F,0x44,0x49, /* 00000778 "`.`.._DI" */ + 0x53,0x00,0x7D,0x50,0x52,0x51,0x33,0x0A, /* 00000780 "S.}PRQ3." */ + 0x80,0x50,0x52,0x51,0x33,0x14,0x3F,0x5F, /* 00000788 ".PRQ3.?_" */ + 0x43,0x52,0x53,0x00,0x08,0x50,0x52,0x52, /* 00000790 "CRS..PRR" */ + 0x30,0x11,0x09,0x0A,0x06,0x23,0x02,0x00, /* 00000798 "0....#.." */ + 0x18,0x79,0x00,0x8B,0x50,0x52,0x52,0x30, /* 000007A0 ".y..PRR0" */ + 0x01,0x54,0x4D,0x50,0x5F,0x70,0x50,0x52, /* 000007A8 ".TMP_pPR" */ + 0x51,0x33,0x60,0xA0,0x0C,0x95,0x60,0x0A, /* 000007B0 "Q3`...`." */ + 0x80,0x79,0x01,0x60,0x54,0x4D,0x50,0x5F, /* 000007B8 ".y.`TMP_" */ + 0xA1,0x07,0x70,0x00,0x54,0x4D,0x50,0x5F, /* 000007C0 "..p.TMP_" */ + 0xA4,0x50,0x52,0x52,0x30,0x14,0x1B,0x5F, /* 000007C8 ".PRR0.._" */ + 0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x54, /* 000007D0 "SRS..h.T" */ + 0x4D,0x50,0x5F,0x82,0x54,0x4D,0x50,0x5F, /* 000007D8 "MP_.TMP_" */ + 0x60,0x76,0x60,0x70,0x60,0x50,0x52,0x51, /* 000007E0 "`v`p`PRQ" */ + 0x33,0x08,0x5F,0x53,0x33,0x5F,0x12,0x06, /* 000007E8 "3._S3_.." */ + 0x04,0x01,0x01,0x00,0x00,0x08,0x5F,0x53, /* 000007F0 "......_S" */ + 0x34,0x5F,0x12,0x06,0x04,0x00,0x00,0x00, /* 000007F8 "4_......" */ + 0x00,0x08,0x5F,0x53,0x35,0x5F,0x12,0x06, /* 00000800 ".._S5_.." */ + 0x04,0x00,0x00,0x00,0x00, +}; diff --git a/bochs/bios/apmbios.S b/bochs/bios/apmbios.S new file mode 100644 index 00000000..41c9e7ef --- /dev/null +++ b/bochs/bios/apmbios.S @@ -0,0 +1,365 @@ +// APM BIOS support for the Bochs BIOS +// Copyright (C) 2004 Fabrice Bellard +// +// Debugging extensions, 16-bit interface and extended power options +// Copyright (C) 2005 Struan Bartlett +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#if defined(APM_REAL) +#define APMSYM(s) apmreal_ ## s +#elif defined(APM_PROT16) +#define APMSYM(s) apm16_ ## s +#elif defined(APM_PROT32) +#define APMSYM(s) apm32_ ## s +#else +#error unsupported APM mode +#endif + +APMSYM(out_str): + push eax + push ebx + mov ebx, eax +APMSYM(out_str1): + SEG CS + mov al, byte ptr [bx] + cmp al, #0 + je APMSYM(out_str2) + outb dx, al + inc ebx + jmp APMSYM(out_str1) +APMSYM(out_str2): + pop ebx + pop eax + ret + +APMSYM(07_poweroff_str): + .ascii "Shutdown" + db 0 +APMSYM(07_suspend_str): + .ascii "Suspend" + db 0 +APMSYM(07_standby_str): + .ascii "Standby" + db 0 + +#if DEBUG_APM +APMSYM(put_str): + push edx + mov dx, #INFO_PORT + call APMSYM(out_str) + pop edx + ret + +; print the hex number in eax +APMSYM(put_num): + push eax + push ebx + push ecx + push edx + mov ecx, eax + mov bx, #8 + mov dx, #INFO_PORT +APMSYM(put_num1): + mov eax, ecx + shr eax, #28 + add al, #0x30 + cmp al, #0x39 + jbe APMSYM(put_num2) + add al, #0x27 +APMSYM(put_num2): + outb dx, al + shl ecx, #4 + dec bx + jne APMSYM(put_num1) + pop edx + pop ecx + pop ebx + pop eax + ret + +APMSYM(put_reg): + outb dx, al + shr eax, #8 + outb dx, al + shr eax, #8 + outb dx, al + shr eax, #8 + outb dx, al + + mov eax,ebx + call APMSYM(put_num) + + mov al, #0x3b + outb dx,al + mov al, #0x20 + outb dx,al + ret + +APMSYM(put_regs): + push eax + push edx + push ebx + mov dx, #INFO_PORT + + mov ebx, eax + mov eax, #0x3d584145 // 'EAX=' + call APMSYM(put_reg) + pop ebx + push ebx + mov eax, #0x3d584245 // 'EBX=' + call APMSYM(put_reg) + mov ebx, ecx + mov eax, #0x3d584345 // 'ECX=' + call APMSYM(put_reg) + mov ebx, edx + mov eax, #0x3d584445 // 'EDX=' + call APMSYM(put_reg) + mov ebx, esi + mov eax, #0x3d495345 // 'ESI=' + call APMSYM(put_reg) + mov ebx, edi + mov eax, #0x3d494445 // 'EDI=' + call APMSYM(put_reg) + + mov al, #0x0a + outb dx, al + pop ebx + pop edx + pop eax + ret +#endif + +#if defined(APM_PROT32) +_apm32_entry: +#endif +#if defined(APM_PROT16) +_apm16_entry: +#endif + pushf + +#if defined(APM_REAL) +_apmreal_entry: +#endif + +#if DEBUG_APM + call APMSYM(put_regs) +#endif + +#if defined(APM_REAL) +;----------------- +; APM installation check +APMSYM(00): + cmp al, #0x00 + jne APMSYM(01) + + mov ah, #1 // APM major version + mov al, #2 // APM minor version + + mov bh, #0x50 // 'P' + mov bl, #0x4d // 'M' + + // bit 0 : 16 bit interface supported + // bit 1 : 32 bit interface supported + mov cx, #0x3 + jmp APMSYM(ok) + +;----------------- +; APM real mode interface connect +APMSYM(01): + cmp al, #0x01 + jne APMSYM(02) + jmp APMSYM(ok) + +;----------------- +; APM 16 bit protected mode interface connect +APMSYM(02): + cmp al, #0x02 + jne APMSYM(03) + + mov bx, #_apm16_entry + + mov ax, #0xf000 // 16 bit code segment base + mov si, #0xfff0 // 16 bit code segment size + mov cx, #0xf000 // data segment address + mov di, #0xfff0 // data segment length + jmp APMSYM(ok) + +;----------------- +; APM 32 bit protected mode interface connect +APMSYM(03): + cmp al, #0x03 + jne APMSYM(04) + mov ax, #0xf000 // 32 bit code segment base + mov ebx, #_apm32_entry + mov cx, #0xf000 // 16 bit code segment base + // 32 bit code segment size (low 16 bits) + // 16 bit code segment size (high 16 bits) + mov esi, #0xfff0fff0 + mov dx, #0xf000 // data segment address + mov di, #0xfff0 // data segment length + jmp APMSYM(ok) +#endif + +;----------------- +; APM interface disconnect +APMSYM(04): + cmp al, #0x04 + jne APMSYM(05) + jmp APMSYM(ok) + +;----------------- +; APM cpu idle +APMSYM(05): + cmp al, #0x05 + jne APMSYM(07) + sti + hlt + jmp APMSYM(ok) + +;----------------- +; APM Set Power State +APMSYM(07): + cmp al, #0x07 + jne APMSYM(08) + + cmp bx, #1 + jne APMSYM(ok) + + cmp cx, #3 + je APMSYM(07_poweroff) + + cmp cx, #2 + je APMSYM(07_suspend) + + cmp cx, #1 + je APMSYM(07_standby) + + jne APMSYM(ok) + +APMSYM(07_poweroff): + // send power off event to emulator + cli + mov dx, #0x8900 + mov ax, #APMSYM(07_poweroff_str) + call APMSYM(out_str) + +APMSYM(07_1): + hlt + jmp APMSYM(07_1) + +APMSYM(07_suspend): + push edx + mov dx, #0x8900 + mov ax, #APMSYM(07_suspend_str) + call APMSYM(out_str) + pop edx + jmp APMSYM(ok) + +APMSYM(07_standby): + push edx + mov dx, #0x8900 + mov ax, #APMSYM(07_standby_str) + call APMSYM(out_str) + pop edx + jmp APMSYM(ok) + +;----------------- +; APM Enable / Disable +APMSYM(08): + cmp al, #0x08 + jne APMSYM(0a) + + jmp APMSYM(ok) + +;----------------- +; Get Power Status +APMSYM(0a): + cmp al, #0x0a + jne APMSYM(0b) + mov bh, #0x01 // on line + // mov bh, #0x02 // battery + mov bl, #0xff // unknown battery status + // mov bl, #0x03 // charging + mov ch, #0x80 // no system battery + // mov ch, #0x8 // charging + mov cl, #0xff // unknown remaining time + // mov cl, #50 + mov dx, #0xffff // unknown remaining time + mov si, #0 // zero battery + // mov si, #1 // one battery + jmp APMSYM(ok) + +;----------------- +; Get PM Event +APMSYM(0b): + cmp al, #0x0b + jne APMSYM(0e) + mov ah, #0x80 // no event pending + jmp APMSYM(error) + +;----------------- +; APM Driver Version +APMSYM(0e): + cmp al, #0x0e + jne APMSYM(0f) + + mov ah, #1 + mov al, #2 + + jmp APMSYM(ok) + +;----------------- +; APM Engage / Disengage +APMSYM(0f): + cmp al, #0x0f + jne APMSYM(10) + + jmp APMSYM(ok) + +;----------------- +; APM Get Capabilities +APMSYM(10): + cmp al, #0x10 + jne APMSYM(unimplemented) + + mov bl, #0 + mov cx, #0 + + jmp APMSYM(ok) + +;----------------- +APMSYM(ok): + popf + clc +#if defined(APM_REAL) + jmp iret_modify_cf +#else + retf +#endif +APMSYM(unimplemented): +APMSYM(error): + popf + stc +#if defined(APM_REAL) + jmp iret_modify_cf +#else + retf +#endif + +#undef APM_PROT32 +#undef APM_PROT16 +#undef APM_REAL +#undef APMSYM diff --git a/bochs/bios/bios_usage b/bochs/bios/bios_usage new file mode 100644 index 00000000..8019ef63 --- /dev/null +++ b/bochs/bios/bios_usage @@ -0,0 +1,4 @@ +#!/bin/csh -f +gcc -E rombios.c | grep "^\.org" | sed -e 's/\.org //' | sed -e 's/ .*//' | sort >! temp.usage +usage rombios.bin temp.usage +/bin/rm temp.usage diff --git a/bochs/bios/biossums.c b/bochs/bios/biossums.c new file mode 100644 index 00000000..f6780a39 --- /dev/null +++ b/bochs/bios/biossums.c @@ -0,0 +1,589 @@ +/* + * $Id$ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* biossums.c --- written by Eike W. for the Bochs BIOS */ + +#include +#include +#include + +typedef unsigned char byte; + +void check( int value, char* message ); + +#define LEN_BIOS_DATA 0x10000 +#define MAX_OFFSET (LEN_BIOS_DATA - 1) + + +#define BIOS_OFFSET 0xFFFF + +long chksum_bios_get_offset( byte* data, long offset ); +byte chksum_bios_calc_value( byte* data, long offset ); +byte chksum_bios_get_value( byte* data, long offset ); +void chksum_bios_set_value( byte* data, long offset, byte value ); + + +#define _32__LEN 9 +#define _32__CHKSUM 10 + +#define _32__MINHDR 16 + +long chksum__32__get_offset( byte* data, long offset ); +byte chksum__32__calc_value( byte* data, long offset ); +byte chksum__32__get_value( byte* data, long offset ); +void chksum__32__set_value( byte* data, long offset, byte value ); + + +#define _MP__LEN 8 +#define _MP__CHKSUM 10 + +#define _MP__MINHDR 16 + +long chksum__mp__get_offset( byte* data, long offset ); +byte chksum__mp__calc_value( byte* data, long offset ); +byte chksum__mp__get_value( byte* data, long offset ); +void chksum__mp__set_value( byte* data, long offset, byte value ); + + +#define PCMP_BASELEN 4 +#define PCMP_CHKSUM 7 +#define PCMP_EXT_LEN 40 +#define PCMP_EXT_CHKSUM 42 + +#define PCMP_MINHDR 42 + +long chksum_pcmp_get_offset( byte* data, long offset ); +byte chksum_pcmp_calc_value( byte* data, long offset ); +byte chksum_pcmp_get_value( byte* data, long offset ); +void chksum_pcmp_set_value( byte* data, long offset, byte value ); + + +#define _PIR_LEN 6 +#define _PIR_CHKSUM 31 + +#define _PIR_MINHDR 32 + +long chksum__pir_get_offset( byte *data, long offset ); +byte chksum__pir_calc_value( byte* data, long offset ); +byte chksum__pir_get_value( byte* data, long offset ); +void chksum__pir_set_value( byte* data, long offset, byte value ); + +#define _PNP_LEN 5 +#define _PNP_CHKSUM 8 + +#define _PNP_MINHDR 32 + +long chksum__pnp_get_offset( byte *data, long offset ); +byte chksum__pnp_calc_value( byte* data, long offset ); +byte chksum__pnp_get_value( byte* data, long offset ); +void chksum__pnp_set_value( byte* data, long offset, byte value ); + +byte bios_data[LEN_BIOS_DATA]; +long bios_len; + + +int main(int argc, char* argv[]) { + + FILE* stream; + long offset, tmp_offset; + byte cur_val = 0, new_val = 0; + int arg = 1, hits, pad = 0; + + + if ((argc == 3) && (!strcmp(argv[1], "-pad"))) { + pad = 1; + arg = 2; + } else if (argc != 2) { + printf("Error. Need a file-name as an argument.\n"); + exit(EXIT_FAILURE); + } + memset(bios_data, 0xff, LEN_BIOS_DATA); + + if ((stream = fopen(argv[arg], "rb")) == NULL) { + printf("Error opening %s for reading.\n", argv[arg]); + exit(EXIT_FAILURE); + } + bios_len = fread(bios_data, 1, LEN_BIOS_DATA, stream); + if ((bios_len < LEN_BIOS_DATA) && (pad == 0)) { + printf("Error reading 64KBytes from %s.\n", argv[arg]); + fclose(stream); + exit(EXIT_FAILURE); + } + fclose(stream); + if (pad == 1) goto write_bios; + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum__32__get_value( bios_data, offset ); + new_val = chksum__32__calc_value( bios_data, offset ); + printf( "\n\nPCI-Bios header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum__32__set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Multiple PCI headers! No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum__mp__get_value( bios_data, offset ); + new_val = chksum__mp__calc_value( bios_data, offset ); + printf( "\n\nMP header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum__mp__set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Warning! Multiple MP headers. No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum_pcmp_get_value( bios_data, offset ); + new_val = chksum_pcmp_calc_value( bios_data, offset ); + printf( "\n\nPCMP header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum_pcmp_set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Warning! Multiple PCMP headers. No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum__pir_get_value( bios_data, offset ); + new_val = chksum__pir_calc_value( bios_data, offset ); + printf( "\n\n$PIR header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X\n ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum__pir_set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Warning! Multiple $PIR headers. No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum__pnp_get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum__pnp_get_value( bios_data, offset ); + new_val = chksum__pnp_calc_value( bios_data, offset ); + printf( "\n\n$PnP header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X\n ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum__pnp_set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Warning! Multiple $PnP headers. No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + offset = 0L; + offset = chksum_bios_get_offset( bios_data, offset ); + cur_val = chksum_bios_get_value( bios_data, offset ); + new_val = chksum_bios_calc_value( bios_data, offset ); + printf( "\n\nBios checksum at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + if( cur_val != new_val ) { + printf( "Setting checksum." ); + chksum_bios_set_value( bios_data, offset, new_val ); + } + printf( "\n" ); + +write_bios: + if ((stream = fopen(argv[arg], "wb")) == NULL) { + printf("Error opening %s for writing.\n", argv[arg]); + exit(EXIT_FAILURE); + } + if (fwrite(bios_data, 1, LEN_BIOS_DATA, stream) < LEN_BIOS_DATA) { + printf("Error writing 64KBytes to %s.\n", argv[arg]); + fclose(stream); + exit(EXIT_FAILURE); + } + fclose(stream); + + return(EXIT_SUCCESS); +} + + +void check(int okay, char* message) { + + if (!okay) { + printf("\n\nError. %s.\n", message); + exit(EXIT_FAILURE); + } +} + + +long chksum_bios_get_offset( byte* data, long offset ) { + + return( BIOS_OFFSET ); +} + + +byte chksum_bios_calc_value( byte* data, long offset ) { + + int i; + byte sum; + + sum = 0; + for( i = 0; i < MAX_OFFSET; i++ ) { + sum = sum + *( data + i ); + } + sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ + return( sum ); +} + + +byte chksum_bios_get_value( byte* data, long offset ) { + + return( *( data + BIOS_OFFSET ) ); +} + + +void chksum_bios_set_value( byte* data, long offset, byte value ) { + + *( data + BIOS_OFFSET ) = value; +} + + +byte chksum__32__calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" ); + len = *( data + offset + _32__LEN ) << 4; + check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != _32__CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum__32__get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == '_' && \ + *( data + offset + 1 ) == '3' && \ + *( data + offset + 2 ) == '2' && \ + *( data + offset + 3 ) == '_' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum__32__get_value( byte* data, long offset ) { + + check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" ); + return( *( data + offset + _32__CHKSUM ) ); +} + + +void chksum__32__set_value( byte* data, long offset, byte value ) { + + check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" ); + *( data + offset + _32__CHKSUM ) = value; +} + + +byte chksum__mp__calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" ); + len = *( data + offset + _MP__LEN ) << 4; + check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != _MP__CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum__mp__get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == '_' && \ + *( data + offset + 1 ) == 'M' && \ + *( data + offset + 2 ) == 'P' && \ + *( data + offset + 3 ) == '_' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum__mp__get_value( byte* data, long offset ) { + + check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" ); + return( *( data + offset + _MP__CHKSUM ) ); +} + + +void chksum__mp__set_value( byte* data, long offset, byte value ) { + + check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" ); + *( data + offset + _MP__CHKSUM ) = value; +} + + +byte chksum_pcmp_calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" ); + len = *( data + offset + PCMP_BASELEN ) + \ + ( *( data + offset + PCMP_BASELEN + 1 ) << 8 ); + check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" ); + if( *( data + offset + PCMP_EXT_LEN ) | \ + *( data + offset + PCMP_EXT_LEN + 1 ) | \ + *( data + offset + PCMP_EXT_CHKSUM ) ) { + check( 0, "PCMP header indicates extended tables (unsupported)" ); + } + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != PCMP_CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum_pcmp_get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == 'P' && \ + *( data + offset + 1 ) == 'C' && \ + *( data + offset + 2 ) == 'M' && \ + *( data + offset + 3 ) == 'P' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum_pcmp_get_value( byte* data, long offset ) { + + check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" ); + return( *( data + offset + PCMP_CHKSUM ) ); +} + + +void chksum_pcmp_set_value( byte* data, long offset, byte value ) { + + check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" ); + *( data + offset + PCMP_CHKSUM ) = value; +} + + +byte chksum__pir_calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" ); + len = *( data + offset + _PIR_LEN ) + \ + ( *( data + offset + _PIR_LEN + 1 ) << 8 ); + check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != _PIR_CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum__pir_get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == '$' && \ + *( data + offset + 1 ) == 'P' && \ + *( data + offset + 2 ) == 'I' && \ + *( data + offset + 3 ) == 'R' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum__pir_get_value( byte* data, long offset ) { + + check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" ); + return( *( data + offset + _PIR_CHKSUM ) ); +} + + +void chksum__pir_set_value( byte* data, long offset, byte value ) { + + check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" ); + *( data + offset + _PIR_CHKSUM ) = value; +} + + +byte chksum__pnp_calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + _PNP_MINHDR <= MAX_OFFSET, "$PnP header out of bounds" ); + len = *( data + offset + _PNP_LEN ); + check( offset + len <= MAX_OFFSET, "$PnP header-length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != _PNP_CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum__pnp_get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == '$' && \ + *( data + offset + 1 ) == 'P' && \ + *( data + offset + 2 ) == 'n' && \ + *( data + offset + 3 ) == 'P' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum__pnp_get_value( byte* data, long offset ) { + + check( offset + _PNP_CHKSUM <= MAX_OFFSET, "$PnP checksum out of bounds" ); + return( *( data + offset + _PNP_CHKSUM ) ); +} + + +void chksum__pnp_set_value( byte* data, long offset, byte value ) { + + check( offset + _PNP_CHKSUM <= MAX_OFFSET, "$PnP checksum out of bounds" ); + *( data + offset + _PNP_CHKSUM ) = value; +} + diff --git a/bochs/bios/makesym.perl b/bochs/bios/makesym.perl new file mode 100755 index 00000000..da9cacb5 --- /dev/null +++ b/bochs/bios/makesym.perl @@ -0,0 +1,43 @@ +#!/usr/bin/perl +# +# $Id$ +# +# Read output file from as86 (e.g. rombios.txt) and write out a symbol +# table suitable for the Bochs debugger. +# + +use strict; +use warnings; + +my $WHERE_BEFORE_SYM_TABLE = 0; +my $WHERE_IN_SYM_TABLE = 1; +my $WHERE_AFTER_SYM_TABLE = 2; + +my $where = $WHERE_BEFORE_SYM_TABLE; +while () { + chop; + if ($where == $WHERE_BEFORE_SYM_TABLE && /^Symbols:/) { + $where = $WHERE_IN_SYM_TABLE; + } elsif ($where == $WHERE_IN_SYM_TABLE && /^$/) { + $where = $WHERE_AFTER_SYM_TABLE; + } + if ($where == $WHERE_IN_SYM_TABLE) { + my $name; + my $junk; + foreach my $f (split(/\s+/)) { + if ($f =~ /^[[:xdigit:]]{4,}$/) { + if (defined($name)) { + print '000f', lc($f), ' ', $name, "\n"; + undef($name); + undef($junk); + next; + } + } + $name = $junk + if (defined($junk)); + $junk = $f; + } + } +} + +exit(0); diff --git a/bochs/bios/notes b/bochs/bios/notes new file mode 100644 index 00000000..ae1073e9 --- /dev/null +++ b/bochs/bios/notes @@ -0,0 +1,44 @@ +#################### +# Read Disk Sector # +#################### + +System programming: +------------------- + +(Int 13h, ah=2) +in 1f7 until BSY cleared +out 1f2, AL # number of sectors +out 1f3, cl (bits 0-5) # starting sector number +out 1f4, ch # cylinder number bits 0..7, 0 based +out 1f5, cl (bits 6,7) & dh (bits 6,7) # cyl, bits 8..9, 10..11 +out 1f6, dh (bits 0..3) --> bits 0..3 # head number + dh (bits 4..5) --> ??? # head number + dl (bit 0) --> bit 4 # drive number +out 1f7, 0x20 # read sectors command normal + + + +Drive response: +--------------- + +* drive sets the busy bit in Status Reg to 1 +* if command parameters are wrong: + > drive sets the aborted-command bit in the Error register and + error bit in the Status register to 1. + > Drive also sets the busy bit in the Status register to 0. + > Drive then generates an interrupt to the system. +* else: + > drive executes an implied seek to desired track and + reads sectors into sector buffer + > when sector buffer is filled and the data is ready to be + transferred, the drive sets the data-request bit to 1, sets + the busy bit to 0, and generates an interrupt. + > on a single-sector transfer, after the system has transferred + the data, the drive sets the data-request bit and the busy bit to 0. + > on a multiple-sector transfer, after the system has transferred + the first sector of data, the drive sets the data-request bit to 0, + and the busy bit to 1. When each subsequent sector is ready to be + transferred, the drive sets the data-request bit to 1, the busy bit to 0, + and generates an interrupt. When the system has tranferred the last sector, + the drive sets the data-request bit and busy bit to 0. + diff --git a/bochs/bios/rombios.c b/bochs/bios/rombios.c new file mode 100644 index 00000000..29d7797c --- /dev/null +++ b/bochs/bios/rombios.c @@ -0,0 +1,11498 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2002 MandrakeSoft S.A. +// +// MandrakeSoft S.A. +// 43, rue d'Aboukir +// 75002 Paris - France +// http://www.linux-mandrake.com/ +// http://www.mandrakesoft.com/ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +// ROM BIOS for use with Bochs/Plex86/QEMU emulation environment + + +// ROM BIOS compatibility entry points: +// =================================== +// $e05b ; POST Entry Point +// $e2c3 ; NMI Handler Entry Point +// $e3fe ; INT 13h Fixed Disk Services Entry Point +// $e401 ; Fixed Disk Parameter Table +// $e6f2 ; INT 19h Boot Load Service Entry Point +// $e6f5 ; Configuration Data Table +// $e729 ; Baud Rate Generator Table +// $e739 ; INT 14h Serial Communications Service Entry Point +// $e82e ; INT 16h Keyboard Service Entry Point +// $e987 ; INT 09h Keyboard Service Entry Point +// $ec59 ; INT 13h Diskette Service Entry Point +// $ef57 ; INT 0Eh Diskette Hardware ISR Entry Point +// $efc7 ; Diskette Controller Parameter Table +// $efd2 ; INT 17h Printer Service Entry Point +// $f045 ; INT 10 Functions 0-Fh Entry Point +// $f065 ; INT 10h Video Support Service Entry Point +// $f0a4 ; MDA/CGA Video Parameter Table (INT 1Dh) +// $f841 ; INT 12h Memory Size Service Entry Point +// $f84d ; INT 11h Equipment List Service Entry Point +// $f859 ; INT 15h System Services Entry Point +// $fa6e ; Character Font for 320x200 & 640x200 Graphics (lower 128 characters) +// $fe6e ; INT 1Ah Time-of-day Service Entry Point +// $fea5 ; INT 08h System Timer ISR Entry Point +// $fef3 ; Initial Interrupt Vector Offsets Loaded by POST +// $ff53 ; IRET Instruction for Dummy Interrupt Handler +// $ff54 ; INT 05h Print Screen Service Entry Point +// $fff0 ; Power-up Entry Point +// $fff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY +// $fffe ; System Model ID + +// NOTES for ATA/ATAPI driver (cbbochs@free.fr) +// Features +// - supports up to 4 ATA interfaces +// - device/geometry detection +// - 16bits/32bits device access +// - pchs/lba access +// - datain/dataout/packet command support +// +// NOTES for El-Torito Boot (cbbochs@free.fr) +// - CD-ROM booting is only available if ATA/ATAPI Driver is available +// - Current code is only able to boot mono-session cds +// - Current code can not boot and emulate a hard-disk +// the bios will panic otherwise +// - Current code also use memory in EBDA segment. +// - I used cmos byte 0x3D to store extended information on boot-device +// - Code has to be modified modified to handle multiple cdrom drives +// - Here are the cdrom boot failure codes: +// 1 : no atapi device found +// 2 : no atapi cdrom found +// 3 : can not read cd - BRVD +// 4 : cd is not eltorito (BRVD) +// 5 : cd is not eltorito (ISO TAG) +// 6 : cd is not eltorito (ELTORITO TAG) +// 7 : can not read cd - boot catalog +// 8 : boot catalog : bad header +// 9 : boot catalog : bad platform +// 10 : boot catalog : bad signature +// 11 : boot catalog : bootable flag not set +// 12 : can not read cd - boot image +// +// ATA driver +// - EBDA segment. +// I used memory starting at 0x121 in the segment +// - the translation policy is defined in cmos regs 0x39 & 0x3a +// +// TODO : +// +// int74 +// - needs to be reworked. Uses direct [bp] offsets. (?) +// +// int13: +// - f04 (verify sectors) isn't complete (?) +// - f02/03/04 should set current cyl,etc in BDA (?) +// - rewrite int13_relocated & clean up int13 entry code +// +// NOTES: +// - NMI access (bit7 of addr written to 70h) +// +// ATA driver +// - should handle the "don't detect" bit (cmos regs 0x3b & 0x3c) +// - could send the multiple-sector read/write commands +// +// El-Torito +// - Emulate a Hard-disk (currently only diskette can be emulated) see "FIXME ElTorito Harddisk" +// - Implement remaining int13_cdemu functions (as defined by El-Torito specs) +// - cdrom drive is hardcoded to ide 0 device 1 in several places. see "FIXME ElTorito Hardcoded" +// - int13 Fix DL when emulating a cd. In that case DL is decremented before calling real int13. +// This is ok. But DL should be reincremented afterwards. +// - Fix all "FIXME ElTorito Various" +// - should be able to boot any cdrom instead of the first one +// +// BCC Bug: find a generic way to handle the bug of #asm after an "if" (fixed in 0.16.7) + +#include "rombios.h" + + // Sanity Checks +#if BX_CPU<3 +# error Only 386+ cpu supported +#endif +#if BX_USE_ATADRV && !BX_USE_EBDA +# error ATA/ATAPI Driver can only be used if EBDA is available +#endif +#if BX_ELTORITO_BOOT && !BX_USE_ATADRV +# error El-Torito Boot can only be use if ATA/ATAPI Driver is available +#endif + +// define this if you want to make PCIBIOS working on a specific bridge only +// undef enables PCIBIOS when at least one PCI device is found +// i440FX is emulated by Bochs and QEMU +#define PCI_FIXED_HOST_BRIDGE 0x12378086 ;; i440FX PCI bridge + +// #20 is dec 20 +// #$20 is hex 20 = 32 +// #0x20 is hex 20 = 32 +// LDA #$20 +// JSR $E820 +// LDD .i,S +// JSR $C682 +// mov al, #$20 + +// all hex literals should be prefixed with '0x' +// grep "#[0-9a-fA-F][0-9a-fA-F]" rombios.c +// no mov SEG-REG, #value, must mov register into seg-reg +// grep -i "mov[ ]*.s" rombios.c + +// This is for compiling with gcc2 and gcc3 +#define ASM_START #asm +#define ASM_END #endasm + +ASM_START +.rom + +.org 0x0000 + +use16 386 + +MACRO HALT + ;; the HALT macro is called with the line number of the HALT call. + ;; The line number is then sent to the PANIC_PORT, causing Bochs/Plex + ;; to print a BX_PANIC message. This will normally halt the simulation + ;; with a message such as "BIOS panic at rombios.c, line 4091". + ;; However, users can choose to make panics non-fatal and continue. +#if BX_VIRTUAL_PORTS + mov dx,#PANIC_PORT + mov ax,#?1 + out dx,ax +#else + mov dx,#0x80 + mov ax,#?1 + out dx,al +#endif +MEND + +MACRO JMP_AP + db 0xea + dw ?2 + dw ?1 +MEND + +MACRO SET_INT_VECTOR + mov ax, ?3 + mov ?1*4, ax + mov ax, ?2 + mov ?1*4+2, ax +MEND + +ASM_END + +typedef unsigned char Bit8u; +typedef unsigned short Bit16u; +typedef unsigned short bx_bool; +typedef unsigned long Bit32u; + + + void memsetb(seg,offset,value,count); + void memcpyb(dseg,doffset,sseg,soffset,count); + void memcpyd(dseg,doffset,sseg,soffset,count); + + // memset of count bytes + void + memsetb(seg,offset,value,count) + Bit16u seg; + Bit16u offset; + Bit16u value; + Bit16u count; + { + ASM_START + push bp + mov bp, sp + + push ax + push cx + push es + push di + + mov cx, 10[bp] ; count + test cx, cx + je memsetb_end + mov ax, 4[bp] ; segment + mov es, ax + mov ax, 6[bp] ; offset + mov di, ax + mov al, 8[bp] ; value + cld + rep + stosb + + memsetb_end: + pop di + pop es + pop cx + pop ax + + pop bp + ASM_END + } + + // memcpy of count bytes + void + memcpyb(dseg,doffset,sseg,soffset,count) + Bit16u dseg; + Bit16u doffset; + Bit16u sseg; + Bit16u soffset; + Bit16u count; + { + ASM_START + push bp + mov bp, sp + + push ax + push cx + push es + push di + push ds + push si + + mov cx, 12[bp] ; count + test cx, cx + je memcpyb_end + mov ax, 4[bp] ; dsegment + mov es, ax + mov ax, 6[bp] ; doffset + mov di, ax + mov ax, 8[bp] ; ssegment + mov ds, ax + mov ax, 10[bp] ; soffset + mov si, ax + cld + rep + movsb + + memcpyb_end: + pop si + pop ds + pop di + pop es + pop cx + pop ax + + pop bp + ASM_END + } + + // memcpy of count dword + void + memcpyd(dseg,doffset,sseg,soffset,count) + Bit16u dseg; + Bit16u doffset; + Bit16u sseg; + Bit16u soffset; + Bit16u count; + { + ASM_START + push bp + mov bp, sp + + push ax + push cx + push es + push di + push ds + push si + + mov cx, 12[bp] ; count + test cx, cx + je memcpyd_end + mov ax, 4[bp] ; dsegment + mov es, ax + mov ax, 6[bp] ; doffset + mov di, ax + mov ax, 8[bp] ; ssegment + mov ds, ax + mov ax, 10[bp] ; soffset + mov si, ax + cld + rep + movsd + + memcpyd_end: + pop si + pop ds + pop di + pop es + pop cx + pop ax + + pop bp + ASM_END + } + + // read_dword and write_dword functions + static Bit32u read_dword(); + static void write_dword(); + + Bit32u + read_dword(seg, offset) + Bit16u seg; + Bit16u offset; + { + ASM_START + push bp + mov bp, sp + + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov ax, [bx] + add bx, #2 + mov dx, [bx] + ;; ax = return value (word) + ;; dx = return value (word) + pop ds + pop bx + + pop bp + ASM_END + } + + void + write_dword(seg, offset, data) + Bit16u seg; + Bit16u offset; + Bit32u data; + { + ASM_START + push bp + mov bp, sp + + push ax + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov ax, 8[bp] ; data word + mov [bx], ax ; write data word + add bx, #2 + mov ax, 10[bp] ; data word + mov [bx], ax ; write data word + pop ds + pop bx + pop ax + + pop bp + ASM_END + } + + // Bit32u (unsigned long) and long helper functions + ASM_START + + ;; and function + landl: + landul: + SEG SS + and ax,[di] + SEG SS + and bx,2[di] + ret + + ;; add function + laddl: + laddul: + SEG SS + add ax,[di] + SEG SS + adc bx,2[di] + ret + + ;; cmp function + lcmpl: + lcmpul: + and eax, #0x0000FFFF + shl ebx, #16 + or eax, ebx + shr ebx, #16 + SEG SS + cmp eax, dword ptr [di] + ret + + ;; sub function + lsubl: + lsubul: + SEG SS + sub ax,[di] + SEG SS + sbb bx,2[di] + ret + + ;; mul function + lmull: + lmulul: + and eax, #0x0000FFFF + shl ebx, #16 + or eax, ebx + SEG SS + mul eax, dword ptr [di] + mov ebx, eax + shr ebx, #16 + ret + + ;; dec function + ldecl: + ldecul: + SEG SS + dec dword ptr [bx] + ret + + ;; or function + lorl: + lorul: + SEG SS + or ax,[di] + SEG SS + or bx,2[di] + ret + + ;; inc function + lincl: + lincul: + SEG SS + inc dword ptr [bx] + ret + + ;; tst function + ltstl: + ltstul: + and eax, #0x0000FFFF + shl ebx, #16 + or eax, ebx + shr ebx, #16 + test eax, eax + ret + + ;; sr function + lsrul: + mov cx,di + jcxz lsr_exit + and eax, #0x0000FFFF + shl ebx, #16 + or eax, ebx + lsr_loop: + shr eax, #1 + loop lsr_loop + mov ebx, eax + shr ebx, #16 + lsr_exit: + ret + + ;; sl function + lsll: + lslul: + mov cx,di + jcxz lsl_exit + and eax, #0x0000FFFF + shl ebx, #16 + or eax, ebx + lsl_loop: + shl eax, #1 + loop lsl_loop + mov ebx, eax + shr ebx, #16 + lsl_exit: + ret + + idiv_: + cwd + idiv bx + ret + + idiv_u: + xor dx,dx + div bx + ret + + ldivul: + and eax, #0x0000FFFF + shl ebx, #16 + or eax, ebx + xor edx, edx + SEG SS + mov bx, 2[di] + shl ebx, #16 + SEG SS + mov bx, [di] + div ebx + mov ebx, eax + shr ebx, #16 + ret + + ASM_END + +// for access to RAM area which is used by interrupt vectors +// and BIOS Data Area + +typedef struct { + unsigned char filler1[0x400]; + unsigned char filler2[0x6c]; + Bit16u ticks_low; + Bit16u ticks_high; + Bit8u midnight_flag; +} bios_data_t; + +#define BiosData ((bios_data_t *) 0) + +#if BX_USE_ATADRV + typedef struct { + Bit16u heads; // # heads + Bit16u cylinders; // # cylinders + Bit16u spt; // # sectors / track + } chs_t; + + // DPTE definition + typedef struct { + Bit16u iobase1; + Bit16u iobase2; + Bit8u prefix; + Bit8u unused; + Bit8u irq; + Bit8u blkcount; + Bit8u dma; + Bit8u pio; + Bit16u options; + Bit16u reserved; + Bit8u revision; + Bit8u checksum; + } dpte_t; + + typedef struct { + Bit8u iface; // ISA or PCI + Bit16u iobase1; // IO Base 1 + Bit16u iobase2; // IO Base 2 + Bit8u irq; // IRQ + } ata_channel_t; + + typedef struct { + Bit8u type; // Detected type of ata (ata/atapi/none/unknown) + Bit8u device; // Detected type of attached devices (hd/cd/none) + Bit8u removable; // Removable device flag + Bit8u lock; // Locks for removable devices + Bit8u mode; // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA + Bit16u blksize; // block size + + Bit8u translation; // type of translation + chs_t lchs; // Logical CHS + chs_t pchs; // Physical CHS + + Bit32u sectors_low; // Total sectors count + Bit32u sectors_high; + } ata_device_t; + + typedef struct { + // ATA channels info + ata_channel_t channels[BX_MAX_ATA_INTERFACES]; + + // ATA devices info + ata_device_t devices[BX_MAX_ATA_DEVICES]; + // + // map between (bios hd id - 0x80) and ata channels + Bit8u hdcount, hdidmap[BX_MAX_ATA_DEVICES]; + + // map between (bios cd id - 0xE0) and ata channels + Bit8u cdcount, cdidmap[BX_MAX_ATA_DEVICES]; + + // Buffer for DPTE table + dpte_t dpte; + + // Count of transferred sectors and bytes + Bit16u trsfsectors; + Bit32u trsfbytes; + } ata_t; + +#if BX_ELTORITO_BOOT + // ElTorito Device Emulation data + typedef struct { + Bit8u active; + Bit8u media; + Bit8u emulated_drive; + Bit8u controller_index; + Bit16u device_spec; + Bit32u ilba; + Bit16u buffer_segment; + Bit16u load_segment; + Bit16u sector_count; + + // Virtual device + chs_t vdevice; + } cdemu_t; +#endif // BX_ELTORITO_BOOT + + // for access to EBDA area + // The EBDA structure should conform to + // http://www.frontiernet.net/~fys/rombios.htm document + // I made the ata and cdemu structs begin at 0x121 in the EBDA seg + // EBDA must be at most 768 bytes; it lives at EBDA_SEG, and the boot + // device tables are at IPL_SEG + typedef struct { + Bit8u size; + unsigned char filler0[0x21]; + Bit16u mouse_driver_offset; + Bit16u mouse_driver_seg; + Bit8u mouse_flag1; + Bit8u mouse_flag2; + Bit8u mouse_data[0x08]; + unsigned char filler1[0x0D]; + + // FDPT - Can be split into data members if needed + unsigned char fdpt0[0x10]; + unsigned char fdpt1[0x10]; + + unsigned char filler2[0xC4]; + + // ATA Driver data + ata_t ata; + +#if BX_ELTORITO_BOOT + // El Torito Emulation data + cdemu_t cdemu; +#endif // BX_ELTORITO_BOOT + } ebda_data_t; + + #define EbdaData ((ebda_data_t *) 0) + + // for access to the int13ext structure + typedef struct { + Bit8u size; + Bit8u reserved; + Bit16u count; + Bit16u offset; + Bit16u segment; + Bit32u lba1; + Bit32u lba2; + } int13ext_t; + + #define Int13Ext ((int13ext_t *) 0) + + // Disk Physical Table definition + typedef struct { + Bit16u size; + Bit16u infos; + Bit32u cylinders; + Bit32u heads; + Bit32u spt; + Bit32u sector_count1; + Bit32u sector_count2; + Bit16u blksize; + Bit16u dpte_offset; + Bit16u dpte_segment; + union { + struct { + Bit16u key; + Bit8u dpi_length; + Bit8u reserved1; + Bit16u reserved2; + Bit8u host_bus[4]; + Bit8u iface_type[8]; + Bit8u iface_path[8]; + Bit8u device_path[8]; + Bit8u reserved3; + Bit8u checksum; + } phoenix; + struct { + Bit16u key; + Bit8u dpi_length; + Bit8u reserved1; + Bit16u reserved2; + Bit8u host_bus[4]; + Bit8u iface_type[8]; + Bit8u iface_path[8]; + Bit8u device_path[16]; + Bit8u reserved3; + Bit8u checksum; + } t13; + } dpi; + } dpt_t; + + #define Int13DPT ((dpt_t *) 0) + +#endif // BX_USE_ATADRV + +typedef struct { + union { + struct { + Bit16u di, si, bp, sp; + Bit16u bx, dx, cx, ax; + } r16; + struct { + Bit16u filler[4]; + Bit8u bl, bh, dl, dh, cl, ch, al, ah; + } r8; + } u; +} pusha_regs_t; + +typedef struct { + union { + struct { + Bit32u edi, esi, ebp, esp; + Bit32u ebx, edx, ecx, eax; + } r32; + struct { + Bit16u di, filler1, si, filler2, bp, filler3, sp, filler4; + Bit16u bx, filler5, dx, filler6, cx, filler7, ax, filler8; + } r16; + struct { + Bit32u filler[4]; + Bit8u bl, bh; + Bit16u filler1; + Bit8u dl, dh; + Bit16u filler2; + Bit8u cl, ch; + Bit16u filler3; + Bit8u al, ah; + Bit16u filler4; + } r8; + } u; +} pushad_regs_t; + +typedef struct { + union { + struct { + Bit16u flags; + } r16; + struct { + Bit8u flagsl; + Bit8u flagsh; + } r8; + } u; +} flags_t; + +#define SetCF(x) x.u.r8.flagsl |= 0x01 +#define SetZF(x) x.u.r8.flagsl |= 0x40 +#define ClearCF(x) x.u.r8.flagsl &= 0xfe +#define ClearZF(x) x.u.r8.flagsl &= 0xbf +#define GetCF(x) (x.u.r8.flagsl & 0x01) + +typedef struct { + Bit16u ip; + Bit16u cs; + flags_t flags; +} iret_addr_t; + +typedef struct { + Bit16u type; + Bit16u flags; + Bit32u vector; + Bit32u description; + Bit32u reserved; +} ipl_entry_t; + + +static Bit8u inb(); +static Bit8u inb_cmos(); +static void outb(); +static void outb_cmos(); +static Bit16u inw(); +static void outw(); +static void init_rtc(); +static bx_bool rtc_updating(); + +static Bit8u read_byte(); +static Bit16u read_word(); +static void write_byte(); +static void write_word(); +static void bios_printf(); + +static Bit8u inhibit_mouse_int_and_events(); +static void enable_mouse_int_and_events(); +static Bit8u send_to_mouse_ctrl(); +static Bit8u get_mouse_data(); +static void set_kbd_command_byte(); + +static void int09_function(); +static void int13_harddisk(); +static void int13_cdrom(); +static void int13_cdemu(); +static void int13_eltorito(); +static void int13_diskette_function(); +static void int14_function(); +static void int15_function(); +static void int16_function(); +static void int17_function(); +static void int19_function(); +static void int1a_function(); +static void int70_function(); +static void int74_function(); +static Bit16u get_CS(); +static Bit16u get_SS(); +static unsigned int enqueue_key(); +static unsigned int dequeue_key(); +static void get_hd_geometry(); +static void set_diskette_ret_status(); +static void set_diskette_current_cyl(); +static void determine_floppy_media(); +static bx_bool floppy_drive_exists(); +static bx_bool floppy_drive_recal(); +static bx_bool floppy_media_known(); +static bx_bool floppy_media_sense(); +static bx_bool set_enable_a20(); +static void debugger_on(); +static void debugger_off(); +static void keyboard_init(); +static void keyboard_panic(); +static void shutdown_status_panic(); +static void nmi_handler_msg(); +static void delay_ticks(); +static void delay_ticks_and_check_for_keystroke(); + +static void interactive_bootkey(); +static void print_bios_banner(); +static void print_boot_device(); +static void print_boot_failure(); +static void print_cdromboot_failure(); + +# if BX_USE_ATADRV + +// ATA / ATAPI driver +void ata_init(); +void ata_detect(); +void ata_reset(); + +Bit16u ata_cmd_non_data(); +Bit16u ata_cmd_data_in(); +Bit16u ata_cmd_data_out(); +Bit16u ata_cmd_packet(); + +Bit16u atapi_get_sense(); +Bit16u atapi_is_ready(); +Bit16u atapi_is_cdrom(); + +#endif // BX_USE_ATADRV + +#if BX_ELTORITO_BOOT + +void cdemu_init(); +Bit8u cdemu_isactive(); +Bit8u cdemu_emulated_drive(); + +Bit16u cdrom_boot(); + +#endif // BX_ELTORITO_BOOT + +static char bios_cvs_version_string[] = "$Revision: 1.257 $ $Date: 2011-01-26 09:52:02 $"; + +#define BIOS_COPYRIGHT_STRING "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team." + +#if DEBUG_ATA +# define BX_DEBUG_ATA(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_ATA(a...) +#endif +#if DEBUG_INT13_HD +# define BX_DEBUG_INT13_HD(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT13_HD(a...) +#endif +#if DEBUG_INT13_CD +# define BX_DEBUG_INT13_CD(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT13_CD(a...) +#endif +#if DEBUG_INT13_ET +# define BX_DEBUG_INT13_ET(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT13_ET(a...) +#endif +#if DEBUG_INT13_FL +# define BX_DEBUG_INT13_FL(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT13_FL(a...) +#endif +#if DEBUG_INT15 +# define BX_DEBUG_INT15(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT15(a...) +#endif +#if DEBUG_INT16 +# define BX_DEBUG_INT16(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT16(a...) +#endif +#if DEBUG_INT1A +# define BX_DEBUG_INT1A(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT1A(a...) +#endif +#if DEBUG_INT74 +# define BX_DEBUG_INT74(a...) BX_DEBUG(a) +#else +# define BX_DEBUG_INT74(a...) +#endif + +#define SET_AL(val8) AX = ((AX & 0xff00) | (val8)) +#define SET_BL(val8) BX = ((BX & 0xff00) | (val8)) +#define SET_CL(val8) CX = ((CX & 0xff00) | (val8)) +#define SET_DL(val8) DX = ((DX & 0xff00) | (val8)) +#define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8)) +#define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8)) +#define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8)) +#define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8)) + +#define GET_AL() ( AX & 0x00ff ) +#define GET_BL() ( BX & 0x00ff ) +#define GET_CL() ( CX & 0x00ff ) +#define GET_DL() ( DX & 0x00ff ) +#define GET_AH() ( AX >> 8 ) +#define GET_BH() ( BX >> 8 ) +#define GET_CH() ( CX >> 8 ) +#define GET_DH() ( DX >> 8 ) + +#define GET_ELDL() ( ELDX & 0x00ff ) +#define GET_ELDH() ( ELDX >> 8 ) + +#define SET_CF() FLAGS |= 0x0001 +#define CLEAR_CF() FLAGS &= 0xfffe +#define GET_CF() (FLAGS & 0x0001) + +#define SET_ZF() FLAGS |= 0x0040 +#define CLEAR_ZF() FLAGS &= 0xffbf +#define GET_ZF() (FLAGS & 0x0040) + +#define UNSUPPORTED_FUNCTION 0x86 + +#define none 0 +#define MAX_SCAN_CODE 0x58 + +static struct { + Bit16u normal; + Bit16u shift; + Bit16u control; + Bit16u alt; + Bit8u lock_flags; + } scan_to_scanascii[MAX_SCAN_CODE + 1] = { + { none, none, none, none, none }, + { 0x011b, 0x011b, 0x011b, 0x0100, none }, /* escape */ + { 0x0231, 0x0221, none, 0x7800, none }, /* 1! */ + { 0x0332, 0x0340, 0x0300, 0x7900, none }, /* 2@ */ + { 0x0433, 0x0423, none, 0x7a00, none }, /* 3# */ + { 0x0534, 0x0524, none, 0x7b00, none }, /* 4$ */ + { 0x0635, 0x0625, none, 0x7c00, none }, /* 5% */ + { 0x0736, 0x075e, 0x071e, 0x7d00, none }, /* 6^ */ + { 0x0837, 0x0826, none, 0x7e00, none }, /* 7& */ + { 0x0938, 0x092a, none, 0x7f00, none }, /* 8* */ + { 0x0a39, 0x0a28, none, 0x8000, none }, /* 9( */ + { 0x0b30, 0x0b29, none, 0x8100, none }, /* 0) */ + { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200, none }, /* -_ */ + { 0x0d3d, 0x0d2b, none, 0x8300, none }, /* =+ */ + { 0x0e08, 0x0e08, 0x0e7f, none, none }, /* backspace */ + { 0x0f09, 0x0f00, none, none, none }, /* tab */ + { 0x1071, 0x1051, 0x1011, 0x1000, 0x40 }, /* Q */ + { 0x1177, 0x1157, 0x1117, 0x1100, 0x40 }, /* W */ + { 0x1265, 0x1245, 0x1205, 0x1200, 0x40 }, /* E */ + { 0x1372, 0x1352, 0x1312, 0x1300, 0x40 }, /* R */ + { 0x1474, 0x1454, 0x1414, 0x1400, 0x40 }, /* T */ + { 0x1579, 0x1559, 0x1519, 0x1500, 0x40 }, /* Y */ + { 0x1675, 0x1655, 0x1615, 0x1600, 0x40 }, /* U */ + { 0x1769, 0x1749, 0x1709, 0x1700, 0x40 }, /* I */ + { 0x186f, 0x184f, 0x180f, 0x1800, 0x40 }, /* O */ + { 0x1970, 0x1950, 0x1910, 0x1900, 0x40 }, /* P */ + { 0x1a5b, 0x1a7b, 0x1a1b, none, none }, /* [{ */ + { 0x1b5d, 0x1b7d, 0x1b1d, none, none }, /* ]} */ + { 0x1c0d, 0x1c0d, 0x1c0a, none, none }, /* Enter */ + { none, none, none, none, none }, /* L Ctrl */ + { 0x1e61, 0x1e41, 0x1e01, 0x1e00, 0x40 }, /* A */ + { 0x1f73, 0x1f53, 0x1f13, 0x1f00, 0x40 }, /* S */ + { 0x2064, 0x2044, 0x2004, 0x2000, 0x40 }, /* D */ + { 0x2166, 0x2146, 0x2106, 0x2100, 0x40 }, /* F */ + { 0x2267, 0x2247, 0x2207, 0x2200, 0x40 }, /* G */ + { 0x2368, 0x2348, 0x2308, 0x2300, 0x40 }, /* H */ + { 0x246a, 0x244a, 0x240a, 0x2400, 0x40 }, /* J */ + { 0x256b, 0x254b, 0x250b, 0x2500, 0x40 }, /* K */ + { 0x266c, 0x264c, 0x260c, 0x2600, 0x40 }, /* L */ + { 0x273b, 0x273a, none, none, none }, /* ;: */ + { 0x2827, 0x2822, none, none, none }, /* '" */ + { 0x2960, 0x297e, none, none, none }, /* `~ */ + { none, none, none, none, none }, /* L shift */ + { 0x2b5c, 0x2b7c, 0x2b1c, none, none }, /* |\ */ + { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00, 0x40 }, /* Z */ + { 0x2d78, 0x2d58, 0x2d18, 0x2d00, 0x40 }, /* X */ + { 0x2e63, 0x2e43, 0x2e03, 0x2e00, 0x40 }, /* C */ + { 0x2f76, 0x2f56, 0x2f16, 0x2f00, 0x40 }, /* V */ + { 0x3062, 0x3042, 0x3002, 0x3000, 0x40 }, /* B */ + { 0x316e, 0x314e, 0x310e, 0x3100, 0x40 }, /* N */ + { 0x326d, 0x324d, 0x320d, 0x3200, 0x40 }, /* M */ + { 0x332c, 0x333c, none, none, none }, /* ,< */ + { 0x342e, 0x343e, none, none, none }, /* .> */ + { 0x352f, 0x353f, none, none, none }, /* /? */ + { none, none, none, none, none }, /* R Shift */ + { 0x372a, 0x372a, none, none, none }, /* * */ + { none, none, none, none, none }, /* L Alt */ + { 0x3920, 0x3920, 0x3920, 0x3920, none }, /* space */ + { none, none, none, none, none }, /* caps lock */ + { 0x3b00, 0x5400, 0x5e00, 0x6800, none }, /* F1 */ + { 0x3c00, 0x5500, 0x5f00, 0x6900, none }, /* F2 */ + { 0x3d00, 0x5600, 0x6000, 0x6a00, none }, /* F3 */ + { 0x3e00, 0x5700, 0x6100, 0x6b00, none }, /* F4 */ + { 0x3f00, 0x5800, 0x6200, 0x6c00, none }, /* F5 */ + { 0x4000, 0x5900, 0x6300, 0x6d00, none }, /* F6 */ + { 0x4100, 0x5a00, 0x6400, 0x6e00, none }, /* F7 */ + { 0x4200, 0x5b00, 0x6500, 0x6f00, none }, /* F8 */ + { 0x4300, 0x5c00, 0x6600, 0x7000, none }, /* F9 */ + { 0x4400, 0x5d00, 0x6700, 0x7100, none }, /* F10 */ + { none, none, none, none, none }, /* Num Lock */ + { none, none, none, none, none }, /* Scroll Lock */ + { 0x4700, 0x4737, 0x7700, none, 0x20 }, /* 7 Home */ + { 0x4800, 0x4838, none, none, 0x20 }, /* 8 UP */ + { 0x4900, 0x4939, 0x8400, none, 0x20 }, /* 9 PgUp */ + { 0x4a2d, 0x4a2d, none, none, none }, /* - */ + { 0x4b00, 0x4b34, 0x7300, none, 0x20 }, /* 4 Left */ + { 0x4c00, 0x4c35, none, none, 0x20 }, /* 5 */ + { 0x4d00, 0x4d36, 0x7400, none, 0x20 }, /* 6 Right */ + { 0x4e2b, 0x4e2b, none, none, none }, /* + */ + { 0x4f00, 0x4f31, 0x7500, none, 0x20 }, /* 1 End */ + { 0x5000, 0x5032, none, none, 0x20 }, /* 2 Down */ + { 0x5100, 0x5133, 0x7600, none, 0x20 }, /* 3 PgDn */ + { 0x5200, 0x5230, none, none, 0x20 }, /* 0 Ins */ + { 0x5300, 0x532e, none, none, 0x20 }, /* Del */ + { none, none, none, none, none }, + { none, none, none, none, none }, + { 0x565c, 0x567c, none, none, none }, /* \| */ + { 0x8500, 0x8700, 0x8900, 0x8b00, none }, /* F11 */ + { 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */ + }; + + Bit8u +inb(port) + Bit16u port; +{ +ASM_START + push bp + mov bp, sp + + push dx + mov dx, 4[bp] + in al, dx + pop dx + + pop bp +ASM_END +} + +#if BX_USE_ATADRV + Bit16u +inw(port) + Bit16u port; +{ +ASM_START + push bp + mov bp, sp + + push dx + mov dx, 4[bp] + in ax, dx + pop dx + + pop bp +ASM_END +} +#endif + + void +outb(port, val) + Bit16u port; + Bit8u val; +{ +ASM_START + push bp + mov bp, sp + + push ax + push dx + mov dx, 4[bp] + mov al, 6[bp] + out dx, al + pop dx + pop ax + + pop bp +ASM_END +} + +#if BX_USE_ATADRV + void +outw(port, val) + Bit16u port; + Bit16u val; +{ +ASM_START + push bp + mov bp, sp + + push ax + push dx + mov dx, 4[bp] + mov ax, 6[bp] + out dx, ax + pop dx + pop ax + + pop bp +ASM_END +} +#endif + + void +outb_cmos(cmos_reg, val) + Bit8u cmos_reg; + Bit8u val; +{ +ASM_START + push bp + mov bp, sp + + mov al, 4[bp] ;; cmos_reg + out PORT_CMOS_INDEX, al + mov al, 6[bp] ;; val + out PORT_CMOS_DATA, al + + pop bp +ASM_END +} + + Bit8u +inb_cmos(cmos_reg) + Bit8u cmos_reg; +{ +ASM_START + push bp + mov bp, sp + + mov al, 4[bp] ;; cmos_reg + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + + pop bp +ASM_END +} + + void +init_rtc() +{ + outb_cmos(0x0a, 0x26); + outb_cmos(0x0b, 0x02); + inb_cmos(0x0c); + inb_cmos(0x0d); +} + + bx_bool +rtc_updating() +{ + // This function checks to see if the update-in-progress bit + // is set in CMOS Status Register A. If not, it returns 0. + // If it is set, it tries to wait until there is a transition + // to 0, and will return 0 if such a transition occurs. A 1 + // is returned only after timing out. The maximum period + // that this bit should be set is constrained to 244useconds. + // The count I use below guarantees coverage or more than + // this time, with any reasonable IPS setting. + + Bit16u count; + + count = 25000; + while (--count != 0) { + if ( (inb_cmos(0x0a) & 0x80) == 0 ) + return(0); + } + return(1); // update-in-progress never transitioned to 0 +} + + + Bit8u +read_byte(seg, offset) + Bit16u seg; + Bit16u offset; +{ +ASM_START + push bp + mov bp, sp + + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov al, [bx] + ;; al = return value (byte) + pop ds + pop bx + + pop bp +ASM_END +} + + Bit16u +read_word(seg, offset) + Bit16u seg; + Bit16u offset; +{ +ASM_START + push bp + mov bp, sp + + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov ax, [bx] + ;; ax = return value (word) + pop ds + pop bx + + pop bp +ASM_END +} + + void +write_byte(seg, offset, data) + Bit16u seg; + Bit16u offset; + Bit8u data; +{ +ASM_START + push bp + mov bp, sp + + push ax + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov al, 8[bp] ; data byte + mov [bx], al ; write data byte + pop ds + pop bx + pop ax + + pop bp +ASM_END +} + + void +write_word(seg, offset, data) + Bit16u seg; + Bit16u offset; + Bit16u data; +{ +ASM_START + push bp + mov bp, sp + + push ax + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov ax, 8[bp] ; data word + mov [bx], ax ; write data word + pop ds + pop bx + pop ax + + pop bp +ASM_END +} + + Bit16u +get_CS() +{ +ASM_START + mov ax, cs +ASM_END +} + + Bit16u +get_SS() +{ +ASM_START + mov ax, ss +ASM_END +} + +#if BX_DEBUG_SERIAL +/* serial debug port*/ +#define BX_DEBUG_PORT 0x03f8 + +/* data */ +#define UART_RBR 0x00 +#define UART_THR 0x00 + +/* control */ +#define UART_IER 0x01 +#define UART_IIR 0x02 +#define UART_FCR 0x02 +#define UART_LCR 0x03 +#define UART_MCR 0x04 +#define UART_DLL 0x00 +#define UART_DLM 0x01 + +/* status */ +#define UART_LSR 0x05 +#define UART_MSR 0x06 +#define UART_SCR 0x07 + +int uart_can_tx_byte(base_port) + Bit16u base_port; +{ + return inb(base_port + UART_LSR) & 0x20; +} + +void uart_wait_to_tx_byte(base_port) + Bit16u base_port; +{ + while (!uart_can_tx_byte(base_port)); +} + +void uart_wait_until_sent(base_port) + Bit16u base_port; +{ + while (!(inb(base_port + UART_LSR) & 0x40)); +} + +void uart_tx_byte(base_port, data) + Bit16u base_port; + Bit8u data; +{ + uart_wait_to_tx_byte(base_port); + outb(base_port + UART_THR, data); + uart_wait_until_sent(base_port); +} +#endif + + void +wrch(c) + Bit8u c; +{ + ASM_START + push bp + mov bp, sp + + push bx + mov ah, #0x0e + mov al, 4[bp] + xor bx,bx + int #0x10 + pop bx + + pop bp + ASM_END +} + + void +send(action, c) + Bit16u action; + Bit8u c; +{ +#if BX_DEBUG_SERIAL + if (c == '\n') uart_tx_byte(BX_DEBUG_PORT, '\r'); + uart_tx_byte(BX_DEBUG_PORT, c); +#endif +#if BX_VIRTUAL_PORTS + if (action & BIOS_PRINTF_DEBUG) outb(DEBUG_PORT, c); + if (action & BIOS_PRINTF_INFO) outb(INFO_PORT, c); +#endif + if (action & BIOS_PRINTF_SCREEN) { + if (c == '\n') wrch('\r'); + wrch(c); + } +} + + void +put_int(action, val, width, neg) + Bit16u action; + short val, width; + bx_bool neg; +{ + short nval = val / 10; + if (nval) + put_int(action, nval, width - 1, neg); + else { + while (--width > 0) send(action, ' '); + if (neg) send(action, '-'); + } + send(action, val - (nval * 10) + '0'); +} + + void +put_uint(action, val, width, neg) + Bit16u action; + unsigned short val; + short width; + bx_bool neg; +{ + unsigned short nval = val / 10; + if (nval) + put_uint(action, nval, width - 1, neg); + else { + while (--width > 0) send(action, ' '); + if (neg) send(action, '-'); + } + send(action, val - (nval * 10) + '0'); +} + + void +put_luint(action, val, width, neg) + Bit16u action; + unsigned long val; + short width; + bx_bool neg; +{ + unsigned long nval = val / 10; + if (nval) + put_luint(action, nval, width - 1, neg); + else { + while (--width > 0) send(action, ' '); + if (neg) send(action, '-'); + } + send(action, val - (nval * 10) + '0'); +} + +void put_str(action, segment, offset) + Bit16u action; + Bit16u segment; + Bit16u offset; +{ + Bit8u c; + + while (c = read_byte(segment, offset)) { + send(action, c); + offset++; + } +} + + void +delay_ticks(ticks) + Bit16u ticks; +{ + long ticks_to_wait, delta; + Bit32u prev_ticks, t; + + /* + * The 0:046c wraps around at 'midnight' according to a 18.2Hz clock. + * We also have to be careful about interrupt storms. + */ +ASM_START + pushf + sti +ASM_END + ticks_to_wait = ticks; + prev_ticks = read_dword(0x0, 0x46c); + do + { +ASM_START + hlt +ASM_END + t = read_dword(0x0, 0x46c); + if (t > prev_ticks) + { + delta = t - prev_ticks; /* The temp var is required or bcc screws up. */ + ticks_to_wait -= delta; + } + else if (t < prev_ticks) + { + ticks_to_wait -= t; /* wrapped */ + } + + prev_ticks = t; + } while (ticks_to_wait > 0); +ASM_START + cli + popf +ASM_END +} + + Bit8u +check_for_keystroke() +{ +ASM_START + mov ax, #0x100 + int #0x16 + jz no_key + mov al, #1 + jmp done +no_key: + xor al, al +done: +ASM_END +} + + Bit8u +get_keystroke() +{ +ASM_START + mov ax, #0x0 + int #0x16 + xchg ah, al +ASM_END +} + + void +delay_ticks_and_check_for_keystroke(ticks, count) + Bit16u ticks, count; +{ + Bit16u i; + for (i = 1; i <= count; i++) { + delay_ticks(ticks); + if (check_for_keystroke()) + break; + } +} + +//-------------------------------------------------------------------------- +// bios_printf() +// A compact variable argument printf function. +// +// Supports %[format_width][length]format +// where format can be x,X,u,d,s,S,c +// and the optional length modifier is l (ell) +//-------------------------------------------------------------------------- + void +bios_printf(action, s) + Bit16u action; + Bit8u *s; +{ + Bit8u c, format_char; + bx_bool in_format; + short i; + Bit16u *arg_ptr; + Bit16u arg_seg, arg, nibble, hibyte, shift_count, format_width, hexadd; + + arg_ptr = &s; + arg_seg = get_SS(); + + in_format = 0; + format_width = 0; + + if ((action & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT) { +#if BX_VIRTUAL_PORTS + outb(PANIC_PORT2, 0x00); +#endif + bios_printf (BIOS_PRINTF_SCREEN, "FATAL: "); + } + + while (c = read_byte(get_CS(), s)) { + if ( c == '%' ) { + in_format = 1; + format_width = 0; + } + else if (in_format) { + if ( (c>='0') && (c<='9') ) { + format_width = (format_width * 10) + (c - '0'); + } + else { + arg_ptr++; // increment to next arg + arg = read_word(arg_seg, arg_ptr); + if (c == 'x' || c == 'X') { + if (format_width == 0) + format_width = 4; + if (c == 'x') + hexadd = 'a'; + else + hexadd = 'A'; + for (i=format_width-1; i>=0; i--) { + nibble = (arg >> (4 * i)) & 0x000f; + send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd)); + } + } + else if (c == 'u') { + put_uint(action, arg, format_width, 0); + } + else if (c == 'l') { + s++; + c = read_byte(get_CS(), s); /* is it ld,lx,lu? */ + arg_ptr++; /* increment to next arg */ + hibyte = read_word(arg_seg, arg_ptr); + if (c == 'd') { + if (hibyte & 0x8000) + put_luint(action, 0L-(((Bit32u) hibyte << 16) | arg), format_width-1, 1); + else + put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0); + } + else if (c == 'u') { + put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0); + } + else if (c == 'x' || c == 'X') + { + if (format_width == 0) + format_width = 8; + if (c == 'x') + hexadd = 'a'; + else + hexadd = 'A'; + for (i=format_width-1; i>=0; i--) { + nibble = ((((Bit32u) hibyte <<16) | arg) >> (4 * i)) & 0x000f; + send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd)); + } + } + } + else if (c == 'd') { + if (arg & 0x8000) + put_int(action, -arg, format_width - 1, 1); + else + put_int(action, arg, format_width, 0); + } + else if (c == 's') { + put_str(action, get_CS(), arg); + } + else if (c == 'S') { + hibyte = arg; + arg_ptr++; + arg = read_word(arg_seg, arg_ptr); + put_str(action, hibyte, arg); + } + else if (c == 'c') { + send(action, arg); + } + else + BX_PANIC("bios_printf: unknown format\n"); + in_format = 0; + } + } + else { + send(action, c); + } + s ++; + } + + if (action & BIOS_PRINTF_HALT) { + // freeze in a busy loop. +ASM_START + cli + halt2_loop: + hlt + jmp halt2_loop +ASM_END + } +} + +//-------------------------------------------------------------------------- +// keyboard_init +//-------------------------------------------------------------------------- +// this file is based on LinuxBIOS implementation of keyboard.c +// could convert to #asm to gain space + void +keyboard_init() +{ + Bit16u max; + + /* ------------------- Flush buffers ------------------------*/ + /* Wait until buffer is empty */ + max=0xffff; + while ( (inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x00); + + /* flush incoming keys */ + max=0x2000; + while (--max > 0) { + outb(PORT_DIAG, 0x00); + if (inb(PORT_PS2_STATUS) & 0x01) { + inb(PORT_PS2_DATA); + max = 0x2000; + } + } + + // Due to timer issues, and if the IPS setting is > 15000000, + // the incoming keys might not be flushed here. That will + // cause a panic a few lines below. See sourceforge bug report : + // [ 642031 ] FATAL: Keyboard RESET error:993 + + /* ------------------- controller side ----------------------*/ + /* send cmd = 0xAA, self test 8042 */ + outb(PORT_PS2_STATUS, 0xaa); + + /* Wait until buffer is empty */ + max=0xffff; + while ( (inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x00); + if (max==0x0) keyboard_panic(00); + + /* Wait for data */ + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x01); + if (max==0x0) keyboard_panic(01); + + /* read self-test result, 0x55 should be returned from 0x60 */ + if ((inb(PORT_PS2_DATA) != 0x55)){ + keyboard_panic(991); + } + + /* send cmd = 0xAB, keyboard interface test */ + outb(PORT_PS2_STATUS,0xab); + + /* Wait until buffer is empty */ + max=0xffff; + while ((inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x10); + if (max==0x0) keyboard_panic(10); + + /* Wait for data */ + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x11); + if (max==0x0) keyboard_panic(11); + + /* read keyboard interface test result, */ + /* 0x00 should be returned form 0x60 */ + if ((inb(PORT_PS2_DATA) != 0x00)) { + keyboard_panic(992); + } + + /* Enable Keyboard clock */ + outb(PORT_PS2_STATUS,0xae); + outb(PORT_PS2_STATUS,0xa8); + + /* ------------------- keyboard side ------------------------*/ + /* reset keyboard and self test (keyboard side) */ + outb(PORT_PS2_DATA, 0xff); + + /* Wait until buffer is empty */ + max=0xffff; + while ((inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x20); + if (max==0x0) keyboard_panic(20); + + /* Wait for data */ + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x21); + if (max==0x0) keyboard_panic(21); + + /* keyboard should return ACK */ + if ((inb(PORT_PS2_DATA) != 0xfa)) { + keyboard_panic(993); + } + + /* Wait for data */ + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x31); + if (max==0x0) keyboard_panic(31); + + if ((inb(PORT_PS2_DATA) != 0xaa)) { + keyboard_panic(994); + } + + /* Disable keyboard */ + outb(PORT_PS2_DATA, 0xf5); + + /* Wait until buffer is empty */ + max=0xffff; + while ((inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x40); + if (max==0x0) keyboard_panic(40); + + /* Wait for data */ + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x41); + if (max==0x0) keyboard_panic(41); + + /* keyboard should return ACK */ + if ((inb(PORT_PS2_DATA) != 0xfa)) { + keyboard_panic(995); + } + + /* Write Keyboard Mode */ + outb(PORT_PS2_STATUS, 0x60); + + /* Wait until buffer is empty */ + max=0xffff; + while ((inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x50); + if (max==0x0) keyboard_panic(50); + + /* send cmd: scan code convert, disable mouse, enable IRQ 1 */ + outb(PORT_PS2_DATA, 0x61); + + /* Wait until buffer is empty */ + max=0xffff; + while ((inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x60); + if (max==0x0) keyboard_panic(60); + + /* Enable keyboard */ + outb(PORT_PS2_DATA, 0xf4); + + /* Wait until buffer is empty */ + max=0xffff; + while ((inb(PORT_PS2_STATUS) & 0x02) && (--max>0)) outb(PORT_DIAG, 0x70); + if (max==0x0) keyboard_panic(70); + + /* Wait for data */ + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x71); + if (max==0x0) keyboard_panic(70); + + /* keyboard should return ACK */ + if ((inb(PORT_PS2_DATA) != 0xfa)) { + keyboard_panic(996); + } + + outb(PORT_DIAG, 0x77); +} + +//-------------------------------------------------------------------------- +// keyboard_panic +//-------------------------------------------------------------------------- + void +keyboard_panic(status) + Bit16u status; +{ + // If you're getting a 993 keyboard panic here, + // please see the comment in keyboard_init + + BX_PANIC("Keyboard error:%u\n",status); +} + +//-------------------------------------------------------------------------- +// shutdown_status_panic +// called when the shutdown status is not implemented, displays the status +//-------------------------------------------------------------------------- + void +shutdown_status_panic(status) + Bit16u status; +{ + BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status); +} + +void s3_resume_panic() +{ + BX_PANIC("Returned from s3_resume.\n"); +} + +//-------------------------------------------------------------------------- +// print_bios_banner +// displays a the bios version +//-------------------------------------------------------------------------- +void +print_bios_banner() +{ + printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ", + BIOS_BUILD_DATE, bios_cvs_version_string); + printf( +#if BX_APM + "apmbios " +#endif +#if BX_PCIBIOS + "pcibios " +#endif +#if BX_PNPBIOS + "pnpbios " +#endif +#if BX_ELTORITO_BOOT + "eltorito " +#endif +#if BX_ROMBIOS32 + "rombios32 " +#endif + "\n\n"); +} + +//-------------------------------------------------------------------------- +// BIOS Boot Specification 1.0.1 compatibility +// +// Very basic support for the BIOS Boot Specification, which allows expansion +// ROMs to register themselves as boot devices, instead of just stealing the +// INT 19h boot vector. +// +// This is a hack: to do it properly requires a proper PnP BIOS and we aren't +// one; we just lie to the option ROMs to make them behave correctly. +// We also don't support letting option ROMs register as bootable disk +// drives (BCVs), only as bootable devices (BEVs). +// +// http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm +//-------------------------------------------------------------------------- + +static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"}; + +static void +init_boot_vectors() +{ + ipl_entry_t e; + Bit16u count = 0; + Bit16u ss = get_SS(); + + /* Clear out the IPL table. */ + memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, IPL_SIZE); + + /* User selected device not set */ + write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF); + + /* Floppy drive */ + e.type = IPL_TYPE_FLOPPY; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; + memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); + count++; + + /* First HDD */ + e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; + memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); + count++; + +#if BX_ELTORITO_BOOT + /* CDROM */ + e.type = IPL_TYPE_CDROM; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; + memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); + count++; +#endif + + /* Remember how many devices we have */ + write_word(IPL_SEG, IPL_COUNT_OFFSET, count); + /* Not tried booting anything yet */ + write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff); +} + +static Bit8u +get_boot_vector(i, e) +Bit16u i; ipl_entry_t *e; +{ + Bit16u count; + Bit16u ss = get_SS(); + /* Get the count of boot devices, and refuse to overrun the array */ + count = read_word(IPL_SEG, IPL_COUNT_OFFSET); + if (i >= count) return 0; + /* OK to read this device */ + memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e)); + return 1; +} + +#if BX_ELTORITO_BOOT + void +interactive_bootkey() +{ + ipl_entry_t e; + Bit16u count; + char description[33]; + Bit8u scan_code; + Bit8u i; + Bit16u ss = get_SS(); + Bit16u valid_choice = 0; + + while (check_for_keystroke()) + get_keystroke(); + + printf("Press F12 for boot menu.\n\n"); + + delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */ + if (check_for_keystroke()) + { + scan_code = get_keystroke(); + if (scan_code == 0x86) /* F12 */ + { + while (check_for_keystroke()) + get_keystroke(); + + printf("Select boot device:\n\n"); + + count = read_word(IPL_SEG, IPL_COUNT_OFFSET); + for (i = 0; i < count; i++) + { + memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e)); + printf("%d. ", i+1); + switch(e.type) + { + case IPL_TYPE_FLOPPY: + case IPL_TYPE_HARDDISK: + case IPL_TYPE_CDROM: + printf("%s\n", drivetypes[e.type]); + break; + case IPL_TYPE_BEV: + printf("%s", drivetypes[4]); + if (e.description != 0) + { + memcpyb(ss, &description, (Bit16u)(e.description >> 16), (Bit16u)(e.description & 0xffff), 32); + description[32] = 0; + printf(" [%S]", ss, description); + } + printf("\n"); + break; + } + } + + count++; + while (!valid_choice) { + scan_code = get_keystroke(); + if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */ + { + valid_choice = 1; + } + else if (scan_code <= count) + { + valid_choice = 1; + scan_code -= 1; + /* Set user selected device */ + write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code); + } + } + + printf("\n"); + } + } +} +#endif // BX_ELTORITO_BOOT + +//-------------------------------------------------------------------------- +// print_boot_device +// displays the boot device +//-------------------------------------------------------------------------- + +void +print_boot_device(e) + ipl_entry_t *e; +{ + Bit16u type; + char description[33]; + Bit16u ss = get_SS(); + type = e->type; + /* NIC appears as type 0x80 */ + if (type == IPL_TYPE_BEV) type = 0x4; + if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n"); + printf("Booting from %s", drivetypes[type]); + /* print product string if BEV */ + if (type == 4 && e->description != 0) { + /* first 32 bytes are significant */ + memcpyb(ss, &description, (Bit16u)(e->description >> 16), (Bit16u)(e->description & 0xffff), 32); + /* terminate string */ + description[32] = 0; + printf(" [%S]", ss, description); + } + printf("...\n"); +} + +//-------------------------------------------------------------------------- +// print_boot_failure +// displays the reason why boot failed +//-------------------------------------------------------------------------- + void +print_boot_failure(type, reason) + Bit16u type; Bit8u reason; +{ + if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n"); + + printf("Boot failed"); + if (type < 4) { + /* Report the reason too */ + if (reason==0) + printf(": not a bootable disk"); + else + printf(": could not read the boot disk"); + } + printf("\n\n"); +} + +//-------------------------------------------------------------------------- +// print_cdromboot_failure +// displays the reason why boot failed +//-------------------------------------------------------------------------- + void +print_cdromboot_failure( code ) + Bit16u code; +{ + bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "CDROM boot failure code : %04x\n",code); + + return; +} + +void +nmi_handler_msg() +{ + BX_PANIC("NMI Handler called\n"); +} + +void +int18_panic_msg() +{ + BX_PANIC("INT18: BOOT FAILURE\n"); +} + +void +log_bios_start() +{ +#if BX_DEBUG_SERIAL + outb(BX_DEBUG_PORT+UART_LCR, 0x03); /* setup for serial logging: 8N1 */ +#endif + BX_INFO("%s\n", bios_cvs_version_string); +} + + bx_bool +set_enable_a20(val) + bx_bool val; +{ + Bit8u oldval; + + // Use PS2 System Control port A to set A20 enable + + // get current setting first + oldval = inb(PORT_A20); + + // change A20 status + if (val) + outb(PORT_A20, oldval | 0x02); + else + outb(PORT_A20, oldval & 0xfd); + + return((oldval & 0x02) != 0); +} + + void +debugger_on() +{ + outb(0xfedc, 0x01); +} + + void +debugger_off() +{ + outb(0xfedc, 0x00); +} + +int +s3_resume() +{ + Bit32u s3_wakeup_vector; + Bit8u s3_resume_flag; + + s3_resume_flag = read_byte(0x40, 0xb0); + s3_wakeup_vector = read_dword(0x40, 0xb2); + + BX_INFO("S3 resume called %x 0x%lx\n", s3_resume_flag, s3_wakeup_vector); + if (s3_resume_flag != 0xFE || !s3_wakeup_vector) + return 0; + + write_byte(0x40, 0xb0, 0); + + /* setup wakeup vector */ + write_word(0x40, 0xb6, (s3_wakeup_vector & 0xF)); /* IP */ + write_word(0x40, 0xb8, (s3_wakeup_vector >> 4)); /* CS */ + + BX_INFO("S3 resume jump to %x:%x\n", (s3_wakeup_vector >> 4), + (s3_wakeup_vector & 0xF)); +ASM_START + jmpf [0x04b6] +ASM_END + return 1; +} + +#if BX_USE_ATADRV + +// --------------------------------------------------------------------------- +// Start of ATA/ATAPI Driver +// --------------------------------------------------------------------------- + +// Global defines -- ATA register and register bits. +// command block & control block regs +#define ATA_CB_DATA 0 // data reg in/out pio_base_addr1+0 +#define ATA_CB_ERR 1 // error in pio_base_addr1+1 +#define ATA_CB_FR 1 // feature reg out pio_base_addr1+1 +#define ATA_CB_SC 2 // sector count in/out pio_base_addr1+2 +#define ATA_CB_SN 3 // sector number in/out pio_base_addr1+3 +#define ATA_CB_CL 4 // cylinder low in/out pio_base_addr1+4 +#define ATA_CB_CH 5 // cylinder high in/out pio_base_addr1+5 +#define ATA_CB_DH 6 // device head in/out pio_base_addr1+6 +#define ATA_CB_STAT 7 // primary status in pio_base_addr1+7 +#define ATA_CB_CMD 7 // command out pio_base_addr1+7 +#define ATA_CB_ASTAT 6 // alternate status in pio_base_addr2+6 +#define ATA_CB_DC 6 // device control out pio_base_addr2+6 +#define ATA_CB_DA 7 // device address in pio_base_addr2+7 + +#define ATA_CB_ER_ICRC 0x80 // ATA Ultra DMA bad CRC +#define ATA_CB_ER_BBK 0x80 // ATA bad block +#define ATA_CB_ER_UNC 0x40 // ATA uncorrected error +#define ATA_CB_ER_MC 0x20 // ATA media change +#define ATA_CB_ER_IDNF 0x10 // ATA id not found +#define ATA_CB_ER_MCR 0x08 // ATA media change request +#define ATA_CB_ER_ABRT 0x04 // ATA command aborted +#define ATA_CB_ER_NTK0 0x02 // ATA track 0 not found +#define ATA_CB_ER_NDAM 0x01 // ATA address mark not found + +#define ATA_CB_ER_P_SNSKEY 0xf0 // ATAPI sense key (mask) +#define ATA_CB_ER_P_MCR 0x08 // ATAPI Media Change Request +#define ATA_CB_ER_P_ABRT 0x04 // ATAPI command abort +#define ATA_CB_ER_P_EOM 0x02 // ATAPI End of Media +#define ATA_CB_ER_P_ILI 0x01 // ATAPI Illegal Length Indication + +// ATAPI Interrupt Reason bits in the Sector Count reg (CB_SC) +#define ATA_CB_SC_P_TAG 0xf8 // ATAPI tag (mask) +#define ATA_CB_SC_P_REL 0x04 // ATAPI release +#define ATA_CB_SC_P_IO 0x02 // ATAPI I/O +#define ATA_CB_SC_P_CD 0x01 // ATAPI C/D + +// bits 7-4 of the device/head (CB_DH) reg +#define ATA_CB_DH_DEV0 0xa0 // select device 0 +#define ATA_CB_DH_DEV1 0xb0 // select device 1 +#define ATA_CB_DH_LBA 0x40 // use LBA + +// status reg (CB_STAT and CB_ASTAT) bits +#define ATA_CB_STAT_BSY 0x80 // busy +#define ATA_CB_STAT_RDY 0x40 // ready +#define ATA_CB_STAT_DF 0x20 // device fault +#define ATA_CB_STAT_WFT 0x20 // write fault (old name) +#define ATA_CB_STAT_SKC 0x10 // seek complete +#define ATA_CB_STAT_SERV 0x10 // service +#define ATA_CB_STAT_DRQ 0x08 // data request +#define ATA_CB_STAT_CORR 0x04 // corrected +#define ATA_CB_STAT_IDX 0x02 // index +#define ATA_CB_STAT_ERR 0x01 // error (ATA) +#define ATA_CB_STAT_CHK 0x01 // check (ATAPI) + +// device control reg (CB_DC) bits +#define ATA_CB_DC_HD15 0x08 // bit should always be set to one +#define ATA_CB_DC_SRST 0x04 // soft reset +#define ATA_CB_DC_NIEN 0x02 // disable interrupts + +// Most mandatory and optional ATA commands (from ATA-3), +#define ATA_CMD_CFA_ERASE_SECTORS 0xC0 +#define ATA_CMD_CFA_REQUEST_EXT_ERR_CODE 0x03 +#define ATA_CMD_CFA_TRANSLATE_SECTOR 0x87 +#define ATA_CMD_CFA_WRITE_MULTIPLE_WO_ERASE 0xCD +#define ATA_CMD_CFA_WRITE_SECTORS_WO_ERASE 0x38 +#define ATA_CMD_CHECK_POWER_MODE1 0xE5 +#define ATA_CMD_CHECK_POWER_MODE2 0x98 +#define ATA_CMD_DEVICE_RESET 0x08 +#define ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC 0x90 +#define ATA_CMD_FLUSH_CACHE 0xE7 +#define ATA_CMD_FORMAT_TRACK 0x50 +#define ATA_CMD_IDENTIFY_DEVICE 0xEC +#define ATA_CMD_IDENTIFY_DEVICE_PACKET 0xA1 +#define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1 +#define ATA_CMD_IDLE1 0xE3 +#define ATA_CMD_IDLE2 0x97 +#define ATA_CMD_IDLE_IMMEDIATE1 0xE1 +#define ATA_CMD_IDLE_IMMEDIATE2 0x95 +#define ATA_CMD_INITIALIZE_DRIVE_PARAMETERS 0x91 +#define ATA_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91 +#define ATA_CMD_NOP 0x00 +#define ATA_CMD_PACKET 0xA0 +#define ATA_CMD_READ_BUFFER 0xE4 +#define ATA_CMD_READ_DMA 0xC8 +#define ATA_CMD_READ_DMA_QUEUED 0xC7 +#define ATA_CMD_READ_MULTIPLE 0xC4 +#define ATA_CMD_READ_SECTORS 0x20 +#define ATA_CMD_READ_VERIFY_SECTORS 0x40 +#define ATA_CMD_RECALIBRATE 0x10 +#define ATA_CMD_REQUEST_SENSE 0x03 +#define ATA_CMD_SEEK 0x70 +#define ATA_CMD_SET_FEATURES 0xEF +#define ATA_CMD_SET_MULTIPLE_MODE 0xC6 +#define ATA_CMD_SLEEP1 0xE6 +#define ATA_CMD_SLEEP2 0x99 +#define ATA_CMD_STANDBY1 0xE2 +#define ATA_CMD_STANDBY2 0x96 +#define ATA_CMD_STANDBY_IMMEDIATE1 0xE0 +#define ATA_CMD_STANDBY_IMMEDIATE2 0x94 +#define ATA_CMD_WRITE_BUFFER 0xE8 +#define ATA_CMD_WRITE_DMA 0xCA +#define ATA_CMD_WRITE_DMA_QUEUED 0xCC +#define ATA_CMD_WRITE_MULTIPLE 0xC5 +#define ATA_CMD_WRITE_SECTORS 0x30 +#define ATA_CMD_WRITE_VERIFY 0x3C + +#define ATA_IFACE_NONE 0x00 +#define ATA_IFACE_ISA 0x00 +#define ATA_IFACE_PCI 0x01 + +#define ATA_TYPE_NONE 0x00 +#define ATA_TYPE_UNKNOWN 0x01 +#define ATA_TYPE_ATA 0x02 +#define ATA_TYPE_ATAPI 0x03 + +#define ATA_DEVICE_NONE 0x00 +#define ATA_DEVICE_HD 0xFF +#define ATA_DEVICE_CDROM 0x05 + +#define ATA_MODE_NONE 0x00 +#define ATA_MODE_PIO16 0x00 +#define ATA_MODE_PIO32 0x01 +#define ATA_MODE_ISADMA 0x02 +#define ATA_MODE_PCIDMA 0x03 +#define ATA_MODE_USEIRQ 0x10 + +#define ATA_TRANSLATION_NONE 0 +#define ATA_TRANSLATION_LBA 1 +#define ATA_TRANSLATION_LARGE 2 +#define ATA_TRANSLATION_RECHS 3 + +#define ATA_DATA_NO 0x00 +#define ATA_DATA_IN 0x01 +#define ATA_DATA_OUT 0x02 + +// --------------------------------------------------------------------------- +// ATA/ATAPI driver : initialization +// --------------------------------------------------------------------------- +void ata_init( ) +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u channel, device; + + // Channels info init. + for (channel=0; channelata.channels[channel].iface,ATA_IFACE_NONE); + write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1,0x0); + write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2,0x0); + write_byte(ebda_seg,&EbdaData->ata.channels[channel].irq,0); + } + + // Devices info init. + for (device=0; deviceata.devices[device].type,ATA_TYPE_NONE); + write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_NONE); + write_byte(ebda_seg,&EbdaData->ata.devices[device].removable,0); + write_byte(ebda_seg,&EbdaData->ata.devices[device].lock,0); + write_byte(ebda_seg,&EbdaData->ata.devices[device].mode,ATA_MODE_NONE); + write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,0); + write_byte(ebda_seg,&EbdaData->ata.devices[device].translation,ATA_TRANSLATION_NONE); + write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads,0); + write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders,0); + write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt,0); + write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads,0); + write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders,0); + write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt,0); + + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low,0L); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high,0L); + } + + // hdidmap and cdidmap init. + for (device=0; deviceata.hdidmap[device],BX_MAX_ATA_DEVICES); + write_byte(ebda_seg,&EbdaData->ata.cdidmap[device],BX_MAX_ATA_DEVICES); + } + + write_byte(ebda_seg,&EbdaData->ata.hdcount,0); + write_byte(ebda_seg,&EbdaData->ata.cdcount,0); +} + +#define TIMEOUT 0 +#define BSY 1 +#define NOT_BSY 2 +#define NOT_BSY_DRQ 3 +#define NOT_BSY_NOT_DRQ 4 +#define NOT_BSY_RDY 5 + +#define IDE_TIMEOUT 32000u //32 seconds max for IDE ops + +int await_ide(); +static int await_ide(when_done,base,timeout) + Bit8u when_done; + Bit16u base; + Bit16u timeout; +{ + Bit32u time=0,last=0; + Bit16u status; + Bit8u result; + status = inb(base + ATA_CB_STAT); // for the times you're supposed to throw one away + for(;;) { + status = inb(base+ATA_CB_STAT); + time++; + if (when_done == BSY) + result = status & ATA_CB_STAT_BSY; + else if (when_done == NOT_BSY) + result = !(status & ATA_CB_STAT_BSY); + else if (when_done == NOT_BSY_DRQ) + result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_DRQ); + else if (when_done == NOT_BSY_NOT_DRQ) + result = !(status & ATA_CB_STAT_BSY) && !(status & ATA_CB_STAT_DRQ); + else if (when_done == NOT_BSY_RDY) + result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_RDY); + else if (when_done == TIMEOUT) + result = 0; + + if (result) return 0; + if (time>>16 != last) // mod 2048 each 16 ms + { + last = time >>16; + BX_DEBUG_ATA("await_ide: (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout); + } + if (status & ATA_CB_STAT_ERR) + { + BX_DEBUG_ATA("await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout); + return -1; + } + if ((timeout == 0) || ((time>>11) > timeout)) break; + } + BX_INFO("IDE time out\n"); + return -1; +} + +// --------------------------------------------------------------------------- +// ATA/ATAPI driver : device detection +// --------------------------------------------------------------------------- + +void ata_detect( ) +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u hdcount, cdcount, device, type; + Bit8u buffer[0x0200]; + +#if BX_MAX_ATA_INTERFACES > 0 + write_byte(ebda_seg,&EbdaData->ata.channels[0].iface,ATA_IFACE_ISA); + write_word(ebda_seg,&EbdaData->ata.channels[0].iobase1,PORT_ATA1_CMD_BASE); + write_word(ebda_seg,&EbdaData->ata.channels[0].iobase2,0x3f0); + write_byte(ebda_seg,&EbdaData->ata.channels[0].irq,14); +#endif +#if BX_MAX_ATA_INTERFACES > 1 + write_byte(ebda_seg,&EbdaData->ata.channels[1].iface,ATA_IFACE_ISA); + write_word(ebda_seg,&EbdaData->ata.channels[1].iobase1,PORT_ATA2_CMD_BASE); + write_word(ebda_seg,&EbdaData->ata.channels[1].iobase2,0x370); + write_byte(ebda_seg,&EbdaData->ata.channels[1].irq,15); +#endif +#if BX_MAX_ATA_INTERFACES > 2 + write_byte(ebda_seg,&EbdaData->ata.channels[2].iface,ATA_IFACE_ISA); + write_word(ebda_seg,&EbdaData->ata.channels[2].iobase1,0x1e8); + write_word(ebda_seg,&EbdaData->ata.channels[2].iobase2,0x3e0); + write_byte(ebda_seg,&EbdaData->ata.channels[2].irq,12); +#endif +#if BX_MAX_ATA_INTERFACES > 3 + write_byte(ebda_seg,&EbdaData->ata.channels[3].iface,ATA_IFACE_ISA); + write_word(ebda_seg,&EbdaData->ata.channels[3].iobase1,0x168); + write_word(ebda_seg,&EbdaData->ata.channels[3].iobase2,0x360); + write_byte(ebda_seg,&EbdaData->ata.channels[3].irq,11); +#endif +#if BX_MAX_ATA_INTERFACES > 4 +#error Please fill the ATA interface informations +#endif + + // Device detection + hdcount=cdcount=0; + + for(device=0; deviceata.channels[channel].iobase1); + iobase2 =read_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2); + + // Disable interrupts + outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); + + // Look for device + outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); + outb(iobase1+ATA_CB_SC, 0x55); + outb(iobase1+ATA_CB_SN, 0xaa); + outb(iobase1+ATA_CB_SC, 0xaa); + outb(iobase1+ATA_CB_SN, 0x55); + outb(iobase1+ATA_CB_SC, 0x55); + outb(iobase1+ATA_CB_SN, 0xaa); + + // If we found something + sc = inb(iobase1+ATA_CB_SC); + sn = inb(iobase1+ATA_CB_SN); + + if ( (sc == 0x55) && (sn == 0xaa) ) { + write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_UNKNOWN); + + // reset the channel + ata_reset(device); + + // check for ATA or ATAPI + outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); + sc = inb(iobase1+ATA_CB_SC); + sn = inb(iobase1+ATA_CB_SN); + if ((sc==0x01) && (sn==0x01)) { + cl = inb(iobase1+ATA_CB_CL); + ch = inb(iobase1+ATA_CB_CH); + st = inb(iobase1+ATA_CB_STAT); + + if ((cl==0x14) && (ch==0xeb)) { + write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATAPI); + } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) { + write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATA); + } else if ((cl==0xff) && (ch==0xff)) { + write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_NONE); + } + } + } + + type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type); + + // Now we send a IDENTIFY command to ATA device + if(type == ATA_TYPE_ATA) { + Bit32u sectors_low, sectors_high; + Bit16u cylinders, heads, spt, blksize; + Bit8u translation, removable, mode; + + //Temporary values to do the transfer + write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); + write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16); + + if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) !=0 ) + BX_PANIC("ata-detect: Failed to detect ATA device\n"); + + removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0; + mode = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16; + blksize = read_word(get_SS(),buffer+10); + + cylinders = read_word(get_SS(),buffer+(1*2)); // word 1 + heads = read_word(get_SS(),buffer+(3*2)); // word 3 + spt = read_word(get_SS(),buffer+(6*2)); // word 6 + + if (read_word(get_SS(),buffer+(83*2)) & (1 << 10)) { // word 83 - lba48 support + sectors_low = read_dword(get_SS(),buffer+(100*2)); // word 100 and word 101 + sectors_high = read_dword(get_SS(),buffer+(102*2)); // word 102 and word 103 + } else { + sectors_low = read_dword(get_SS(),buffer+(60*2)); // word 60 and word 61 + sectors_high = 0; + } + + write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); + write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable); + write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, mode); + write_word(ebda_seg,&EbdaData->ata.devices[device].blksize, blksize); + write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads, heads); + write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders, cylinders); + write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt, spt); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low, sectors_low); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high, sectors_high); + BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation=", channel, slave,cylinders, heads, spt); + + translation = inb_cmos(0x39 + channel/2); + for (shift=device%4; shift>0; shift--) translation >>= 2; + translation &= 0x03; + + write_byte(ebda_seg,&EbdaData->ata.devices[device].translation, translation); + + switch (translation) { + case ATA_TRANSLATION_NONE: + BX_INFO("none"); + break; + case ATA_TRANSLATION_LBA: + BX_INFO("lba"); + break; + case ATA_TRANSLATION_LARGE: + BX_INFO("large"); + break; + case ATA_TRANSLATION_RECHS: + BX_INFO("r-echs"); + break; + } + + switch (translation) { + case ATA_TRANSLATION_NONE: + break; + case ATA_TRANSLATION_LBA: + spt = 63; + sectors_low /= 63; + heads = sectors_low / 1024; + if (heads>128) heads = 255; + else if (heads>64) heads = 128; + else if (heads>32) heads = 64; + else if (heads>16) heads = 32; + else heads=16; + cylinders = sectors_low / heads; + break; + case ATA_TRANSLATION_RECHS: + // Take care not to overflow + if (heads==16) { + if(cylinders>61439) cylinders=61439; + heads=15; + cylinders = (Bit16u)((Bit32u)(cylinders)*16/15); + } + // then go through the large bitshift process + case ATA_TRANSLATION_LARGE: + while(cylinders > 1024) { + cylinders >>= 1; + heads <<= 1; + + // If we max out the head count + if (heads > 127) break; + } + break; + } + + // clip to 1024 cylinders in lchs + if (cylinders > 1024) cylinders=1024; + BX_INFO(" LCHS=%d/%d/%d\n", cylinders, heads, spt); + + write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads, heads); + write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders, cylinders); + write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt, spt); + + // fill hdidmap + write_byte(ebda_seg,&EbdaData->ata.hdidmap[hdcount], device); + hdcount++; + } + + // Now we send a IDENTIFY command to ATAPI device + if(type == ATA_TYPE_ATAPI) { + + Bit8u type, removable, mode; + Bit16u blksize; + + //Temporary values to do the transfer + write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_CDROM); + write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16); + + if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE_PACKET, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) != 0) + BX_PANIC("ata-detect: Failed to detect ATAPI device\n"); + + type = read_byte(get_SS(),buffer+1) & 0x1f; + removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0; + mode = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16; + blksize = 2048; + + write_byte(ebda_seg,&EbdaData->ata.devices[device].device, type); + write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable); + write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, mode); + write_word(ebda_seg,&EbdaData->ata.devices[device].blksize, blksize); + + // fill cdidmap + write_byte(ebda_seg,&EbdaData->ata.cdidmap[cdcount], device); + cdcount++; + } + + { + Bit32u sizeinmb; + Bit16u ataversion; + Bit8u c, i, version, model[41]; + + switch (type) { + case ATA_TYPE_ATA: + sizeinmb = (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high) << 21) + | (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low) >> 11); + case ATA_TYPE_ATAPI: + // Read ATA/ATAPI version + ataversion=((Bit16u)(read_byte(get_SS(),buffer+161))<<8)|read_byte(get_SS(),buffer+160); + for(version=15;version>0;version--) { + if((ataversion&(1<0;i--){ + if(read_byte(get_SS(),model+i)==0x20) + write_byte(get_SS(),model+i,0x00); + else break; + } + if (i>36) { + write_byte(get_SS(),model+36,0x00); + for(i=35;i>32;i--){ + write_byte(get_SS(),model+i,0x2E); + } + } + break; + } + + switch (type) { + case ATA_TYPE_ATA: + printf("ata%d %s: ",channel,slave?" slave":"master"); + i=0; + while(c=read_byte(get_SS(),model+i++)) + printf("%c",c); + if (sizeinmb < (1UL<<16)) + printf(" ATA-%d Hard-Disk (%4u MBytes)\n", version, (Bit16u)sizeinmb); + else + printf(" ATA-%d Hard-Disk (%4u GBytes)\n", version, (Bit16u)(sizeinmb>>10)); + break; + case ATA_TYPE_ATAPI: + printf("ata%d %s: ",channel,slave?" slave":"master"); + i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c); + if(read_byte(ebda_seg,&EbdaData->ata.devices[device].device)==ATA_DEVICE_CDROM) + printf(" ATAPI-%d CD-Rom/DVD-Rom\n",version); + else + printf(" ATAPI-%d Device\n",version); + break; + case ATA_TYPE_UNKNOWN: + printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master"); + break; + } + } + } + + // Store the devices counts + write_byte(ebda_seg,&EbdaData->ata.hdcount, hdcount); + write_byte(ebda_seg,&EbdaData->ata.cdcount, cdcount); + write_byte(0x40,0x75, hdcount); + + printf("\n"); + + // FIXME : should use bios=cmos|auto|disable bits + // FIXME : should know about translation bits + // FIXME : move hard_drive_post here + +} + +// --------------------------------------------------------------------------- +// ATA/ATAPI driver : software reset +// --------------------------------------------------------------------------- +// ATA-3 +// 8.2.1 Software reset - Device 0 + +void ata_reset(device) +Bit16u device; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit16u iobase1, iobase2; + Bit8u channel, slave, sn, sc; + Bit8u type; + Bit16u max; + + channel = device / 2; + slave = device % 2; + + iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); + iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); + + // Reset + +// 8.2.1 (a) -- set SRST in DC + outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST); + +// 8.2.1 (b) -- wait for BSY + await_ide(BSY, iobase1, 20); + +// 8.2.1 (f) -- clear SRST + outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); + + type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type); + if (type != ATA_TYPE_NONE) { + +// 8.2.1 (g) -- check for sc==sn==0x01 + // select device + outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0); + sc = inb(iobase1+ATA_CB_SC); + sn = inb(iobase1+ATA_CB_SN); + + if ( (sc==0x01) && (sn==0x01) ) { + if (type == ATA_TYPE_ATA) //ATA + await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT); + else //ATAPI + await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); + } + +// 8.2.1 (h) -- wait for not BSY + await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); + } + + // Enable interrupts + outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); +} + +// --------------------------------------------------------------------------- +// ATA/ATAPI driver : execute a non data command +// --------------------------------------------------------------------------- + +Bit16u ata_cmd_non_data() +{return 0;} + +// --------------------------------------------------------------------------- +// ATA/ATAPI driver : execute a data-in command +// --------------------------------------------------------------------------- + // returns + // 0 : no error + // 1 : BUSY bit set + // 2 : read error + // 3 : expected DRQ=1 + // 4 : no sectors left to read/verify + // 5 : more sectors to read/verify + // 6 : no sectors left to write + // 7 : more sectors to write +Bit16u ata_cmd_data_in(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset) +Bit16u device, command, count, cylinder, head, sector, segment, offset; +Bit32u lba_low, lba_high; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit16u iobase1, iobase2, blksize; + Bit8u channel, slave; + Bit8u status, current, mode; + + channel = device / 2; + slave = device % 2; + + iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); + iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); + mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode); + blksize = 0x200; // was = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize); + if (mode == ATA_MODE_PIO32) blksize>>=2; + else blksize>>=1; + + // Reset count of transferred data + write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); + write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); + current = 0; + + status = inb(iobase1 + ATA_CB_STAT); + if (status & ATA_CB_STAT_BSY) return 1; + + outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); + + // sector will be 0 only on lba access. Convert to lba-chs + if (sector == 0) { + if ((count >= 1 << 8) || lba_high || (lba_low + count >= 1UL << 28)) { + outb(iobase1 + ATA_CB_FR, 0x00); + outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff); + outb(iobase1 + ATA_CB_SN, lba_low >> 24); + outb(iobase1 + ATA_CB_CL, lba_high & 0xff); + outb(iobase1 + ATA_CB_CH, lba_high >> 8); + command |= 0x04; + count &= (1UL << 8) - 1; + lba_low &= (1UL << 24) - 1; + } + sector = (Bit16u) (lba_low & 0x000000ffL); + cylinder = (Bit16u) ((lba_low>>8) & 0x0000ffffL); + head = ((Bit16u) ((lba_low>>24) & 0x0000000fL)) | ATA_CB_DH_LBA; + } + + outb(iobase1 + ATA_CB_FR, 0x00); + outb(iobase1 + ATA_CB_SC, count); + outb(iobase1 + ATA_CB_SN, sector); + outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff); + outb(iobase1 + ATA_CB_CH, cylinder >> 8); + outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head ); + outb(iobase1 + ATA_CB_CMD, command); + + await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); + status = inb(iobase1 + ATA_CB_STAT); + + if (status & ATA_CB_STAT_ERR) { + BX_DEBUG_ATA("ata_cmd_data_in : read error\n"); + return 2; + } else if ( !(status & ATA_CB_STAT_DRQ) ) { + BX_DEBUG_ATA("ata_cmd_data_in : DRQ not set (status %02x)\n", (unsigned) status); + return 3; + } + + // FIXME : move seg/off translation here + +ASM_START + sti ;; enable higher priority interrupts +ASM_END + + while (1) { + +ASM_START + push bp + mov bp, sp + mov di, _ata_cmd_data_in.offset + 2[bp] + mov ax, _ata_cmd_data_in.segment + 2[bp] + mov cx, _ata_cmd_data_in.blksize + 2[bp] + + ;; adjust if there will be an overrun. 2K max sector size + cmp di, #0xf800 ;; + jbe ata_in_no_adjust + +ata_in_adjust: + sub di, #0x0800 ;; sub 2 kbytes from offset + add ax, #0x0080 ;; add 2 Kbytes to segment + +ata_in_no_adjust: + mov es, ax ;; segment in es + + mov dx, _ata_cmd_data_in.iobase1 + 2[bp] ;; ATA data read port + + mov ah, _ata_cmd_data_in.mode + 2[bp] + cmp ah, #ATA_MODE_PIO32 + je ata_in_32 + +ata_in_16: + rep + insw ;; CX words transferred from port(DX) to ES:[DI] + jmp ata_in_done + +ata_in_32: + rep + insd ;; CX dwords transferred from port(DX) to ES:[DI] + +ata_in_done: + mov _ata_cmd_data_in.offset + 2[bp], di + mov _ata_cmd_data_in.segment + 2[bp], es + pop bp +ASM_END + + current++; + write_word(ebda_seg, &EbdaData->ata.trsfsectors,current); + count--; + await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); + status = inb(iobase1 + ATA_CB_STAT); + if (count == 0) { + if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) + != ATA_CB_STAT_RDY ) { + BX_DEBUG_ATA("ata_cmd_data_in : no sectors left (status %02x)\n", (unsigned) status); + return 4; + } + break; + } + else { + if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) + != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) { + BX_DEBUG_ATA("ata_cmd_data_in : more sectors left (status %02x)\n", (unsigned) status); + return 5; + } + continue; + } + } + // Enable interrupts + outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); + return 0; +} + +// --------------------------------------------------------------------------- +// ATA/ATAPI driver : execute a data-out command +// --------------------------------------------------------------------------- + // returns + // 0 : no error + // 1 : BUSY bit set + // 2 : read error + // 3 : expected DRQ=1 + // 4 : no sectors left to read/verify + // 5 : more sectors to read/verify + // 6 : no sectors left to write + // 7 : more sectors to write +Bit16u ata_cmd_data_out(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset) +Bit16u device, command, count, cylinder, head, sector, segment, offset; +Bit32u lba_low, lba_high; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit16u iobase1, iobase2, blksize; + Bit8u channel, slave; + Bit8u status, current, mode; + + channel = device / 2; + slave = device % 2; + + iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); + iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); + mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode); + blksize = 0x200; // was = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize); + if (mode == ATA_MODE_PIO32) blksize>>=2; + else blksize>>=1; + + // Reset count of transferred data + write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); + write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); + current = 0; + + status = inb(iobase1 + ATA_CB_STAT); + if (status & ATA_CB_STAT_BSY) return 1; + + outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); + + // sector will be 0 only on lba access. Convert to lba-chs + if (sector == 0) { + if ((count >= 1 << 8) || lba_high || (lba_low + count >= 1UL << 28)) { + outb(iobase1 + ATA_CB_FR, 0x00); + outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff); + outb(iobase1 + ATA_CB_SN, lba_low >> 24); + outb(iobase1 + ATA_CB_CL, lba_high & 0xff); + outb(iobase1 + ATA_CB_CH, lba_high >> 8); + command |= 0x04; + count &= (1UL << 8) - 1; + lba_low &= (1UL << 24) - 1; + } + sector = (Bit16u) (lba_low & 0x000000ffL); + cylinder = (Bit16u) ((lba_low>>8) & 0x0000ffffL); + head = ((Bit16u) ((lba_low>>24) & 0x0000000fL)) | ATA_CB_DH_LBA; + } + + outb(iobase1 + ATA_CB_FR, 0x00); + outb(iobase1 + ATA_CB_SC, count); + outb(iobase1 + ATA_CB_SN, sector); + outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff); + outb(iobase1 + ATA_CB_CH, cylinder >> 8); + outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head ); + outb(iobase1 + ATA_CB_CMD, command); + + await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); + status = inb(iobase1 + ATA_CB_STAT); + + if (status & ATA_CB_STAT_ERR) { + BX_DEBUG_ATA("ata_cmd_data_out : read error\n"); + return 2; + } else if ( !(status & ATA_CB_STAT_DRQ) ) { + BX_DEBUG_ATA("ata_cmd_data_out : DRQ not set (status %02x)\n", (unsigned) status); + return 3; + } + + // FIXME : move seg/off translation here + +ASM_START + sti ;; enable higher priority interrupts +ASM_END + + while (1) { + +ASM_START + push bp + mov bp, sp + mov si, _ata_cmd_data_out.offset + 2[bp] + mov ax, _ata_cmd_data_out.segment + 2[bp] + mov cx, _ata_cmd_data_out.blksize + 2[bp] + + ;; adjust if there will be an overrun. 2K max sector size + cmp si, #0xf800 ;; + jbe ata_out_no_adjust + +ata_out_adjust: + sub si, #0x0800 ;; sub 2 kbytes from offset + add ax, #0x0080 ;; add 2 Kbytes to segment + +ata_out_no_adjust: + mov es, ax ;; segment in es + + mov dx, _ata_cmd_data_out.iobase1 + 2[bp] ;; ATA data write port + + mov ah, _ata_cmd_data_out.mode + 2[bp] + cmp ah, #ATA_MODE_PIO32 + je ata_out_32 + +ata_out_16: + seg ES + rep + outsw ;; CX words transferred from port(DX) to ES:[SI] + jmp ata_out_done + +ata_out_32: + seg ES + rep + outsd ;; CX dwords transferred from port(DX) to ES:[SI] + +ata_out_done: + mov _ata_cmd_data_out.offset + 2[bp], si + mov _ata_cmd_data_out.segment + 2[bp], es + pop bp +ASM_END + + current++; + write_word(ebda_seg, &EbdaData->ata.trsfsectors,current); + count--; + status = inb(iobase1 + ATA_CB_STAT); + if (count == 0) { + if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) + != ATA_CB_STAT_RDY ) { + BX_DEBUG_ATA("ata_cmd_data_out : no sectors left (status %02x)\n", (unsigned) status); + return 6; + } + break; + } + else { + if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) + != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) { + BX_DEBUG_ATA("ata_cmd_data_out : more sectors left (status %02x)\n", (unsigned) status); + return 7; + } + continue; + } + } + // Enable interrupts + outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); + return 0; +} + +// --------------------------------------------------------------------------- +// ATA/ATAPI driver : execute a packet command +// --------------------------------------------------------------------------- + // returns + // 0 : no error + // 1 : error in parameters + // 2 : BUSY bit set + // 3 : error + // 4 : not ready +Bit16u ata_cmd_packet(device, cmdlen, cmdseg, cmdoff, header, length, inout, bufseg, bufoff) +Bit8u cmdlen,inout; +Bit16u device,cmdseg, cmdoff, bufseg, bufoff; +Bit16u header; +Bit32u length; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit16u iobase1, iobase2; + Bit16u lcount, lbefore, lafter, count; + Bit8u channel, slave; + Bit8u status, mode, lmode; + Bit32u total, transfer; + + channel = device / 2; + slave = device % 2; + + // Data out is not supported yet + if (inout == ATA_DATA_OUT) { + BX_INFO("ata_cmd_packet: DATA_OUT not supported yet\n"); + return 1; + } + + // The header length must be even + if (header & 1) { + BX_DEBUG_ATA("ata_cmd_packet : header must be even (%04x)\n",header); + return 1; + } + + iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); + iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); + mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode); + transfer= 0L; + + if (cmdlen < 12) cmdlen=12; + if (cmdlen > 12) cmdlen=16; + cmdlen>>=1; + + // Reset count of transferred data + write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); + write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); + + status = inb(iobase1 + ATA_CB_STAT); + if (status & ATA_CB_STAT_BSY) return 2; + + outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); + outb(iobase1 + ATA_CB_FR, 0x00); + outb(iobase1 + ATA_CB_SC, 0x00); + outb(iobase1 + ATA_CB_SN, 0x00); + outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff); + outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8); + outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); + outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET); + + // Device should ok to receive command + await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); + status = inb(iobase1 + ATA_CB_STAT); + + if (status & ATA_CB_STAT_ERR) { + BX_DEBUG_ATA("ata_cmd_packet : error, status is %02x\n",status); + return 3; + } else if ( !(status & ATA_CB_STAT_DRQ) ) { + BX_DEBUG_ATA("ata_cmd_packet : DRQ not set (status %02x)\n", (unsigned) status); + return 4; + } + + // Normalize address + cmdseg += (cmdoff / 16); + cmdoff %= 16; + + // Send command to device +ASM_START + sti ;; enable higher priority interrupts + + push bp + mov bp, sp + + mov si, _ata_cmd_packet.cmdoff + 2[bp] + mov ax, _ata_cmd_packet.cmdseg + 2[bp] + mov cx, _ata_cmd_packet.cmdlen + 2[bp] + mov es, ax ;; segment in es + + mov dx, _ata_cmd_packet.iobase1 + 2[bp] ;; ATA data write port + + seg ES + rep + outsw ;; CX words transferred from port(DX) to ES:[SI] + + pop bp +ASM_END + + if (inout == ATA_DATA_NO) { + await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); + status = inb(iobase1 + ATA_CB_STAT); + } + else { + Bit16u loops = 0; + Bit8u sc; + + while (1) { + + if (loops == 0) {//first time through + status = inb(iobase2 + ATA_CB_ASTAT); + await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); + } + else + await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); + loops++; + + status = inb(iobase1 + ATA_CB_STAT); + sc = inb(iobase1 + ATA_CB_SC); + + // Check if command completed + if(((inb(iobase1 + ATA_CB_SC)&0x7)==0x3) && + ((status & (ATA_CB_STAT_RDY | ATA_CB_STAT_ERR)) == ATA_CB_STAT_RDY)) break; + + if (status & ATA_CB_STAT_ERR) { + BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status); + return 3; + } + + // Normalize address + bufseg += (bufoff / 16); + bufoff %= 16; + + // Get the byte count + lcount = ((Bit16u)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL); + + // adjust to read what we want + if(header>lcount) { + lbefore=lcount; + header-=lcount; + lcount=0; + } + else { + lbefore=header; + header=0; + lcount-=lbefore; + } + + if(lcount>length) { + lafter=lcount-length; + lcount=length; + length=0; + } + else { + lafter=0; + length-=lcount; + } + + // Save byte count + count = lcount; + + BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter); + BX_DEBUG_ATA("to 0x%04x:0x%04x\n",bufseg,bufoff); + + // If counts not dividable by 4, use 16bits mode + lmode = mode; + if (lbefore & 0x03) lmode=ATA_MODE_PIO16; + if (lcount & 0x03) lmode=ATA_MODE_PIO16; + if (lafter & 0x03) lmode=ATA_MODE_PIO16; + + // adds an extra byte if count are odd. before is always even + if (lcount & 0x01) { + lcount+=1; + if ((lafter > 0) && (lafter & 0x01)) { + lafter-=1; + } + } + + if (lmode == ATA_MODE_PIO32) { + lcount>>=2; lbefore>>=2; lafter>>=2; + } + else { + lcount>>=1; lbefore>>=1; lafter>>=1; + } + + ; // FIXME bcc bug + +ASM_START + push bp + mov bp, sp + + mov dx, _ata_cmd_packet.iobase1 + 2[bp] ;; ATA data read port + + mov cx, _ata_cmd_packet.lbefore + 2[bp] + jcxz ata_packet_no_before + + mov ah, _ata_cmd_packet.lmode + 2[bp] + cmp ah, #ATA_MODE_PIO32 + je ata_packet_in_before_32 + +ata_packet_in_before_16: + in ax, dx + loop ata_packet_in_before_16 + jmp ata_packet_no_before + +ata_packet_in_before_32: + push eax +ata_packet_in_before_32_loop: + in eax, dx + loop ata_packet_in_before_32_loop + pop eax + +ata_packet_no_before: + mov cx, _ata_cmd_packet.lcount + 2[bp] + jcxz ata_packet_after + + mov di, _ata_cmd_packet.bufoff + 2[bp] + mov ax, _ata_cmd_packet.bufseg + 2[bp] + mov es, ax + + mov ah, _ata_cmd_packet.lmode + 2[bp] + cmp ah, #ATA_MODE_PIO32 + je ata_packet_in_32 + +ata_packet_in_16: + rep + insw ;; CX words transferred to port(DX) to ES:[DI] + jmp ata_packet_after + +ata_packet_in_32: + rep + insd ;; CX dwords transferred to port(DX) to ES:[DI] + +ata_packet_after: + mov cx, _ata_cmd_packet.lafter + 2[bp] + jcxz ata_packet_done + + mov ah, _ata_cmd_packet.lmode + 2[bp] + cmp ah, #ATA_MODE_PIO32 + je ata_packet_in_after_32 + +ata_packet_in_after_16: + in ax, dx + loop ata_packet_in_after_16 + jmp ata_packet_done + +ata_packet_in_after_32: + push eax +ata_packet_in_after_32_loop: + in eax, dx + loop ata_packet_in_after_32_loop + pop eax + +ata_packet_done: + pop bp +ASM_END + + // Compute new buffer address + bufoff += count; + + // Save transferred bytes count + transfer += count; + write_dword(ebda_seg, &EbdaData->ata.trsfbytes,transfer); + } + } + + // Final check, device must be ready + if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) + != ATA_CB_STAT_RDY ) { + BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", (unsigned) status); + return 4; + } + + // Enable interrupts + outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); + return 0; +} + +// --------------------------------------------------------------------------- +// End of ATA/ATAPI Driver +// --------------------------------------------------------------------------- + +// --------------------------------------------------------------------------- +// Start of ATA/ATAPI generic functions +// --------------------------------------------------------------------------- + + Bit16u +atapi_get_sense(device, seg, asc, ascq) + Bit16u device; +{ + Bit8u atacmd[12]; + Bit8u buffer[18]; + Bit8u i; + + memsetb(get_SS(),atacmd,0,12); + + // Request SENSE + atacmd[0]=ATA_CMD_REQUEST_SENSE; + atacmd[4]=sizeof(buffer); + if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 18L, ATA_DATA_IN, get_SS(), buffer) != 0) + return 0x0002; + + write_byte(seg,asc,buffer[12]); + write_byte(seg,ascq,buffer[13]); + + return 0; +} + + Bit16u +atapi_is_ready(device) + Bit16u device; +{ + Bit8u packet[12]; + Bit8u buf[8]; + Bit32u block_len; + Bit32u sectors; + Bit32u timeout; //measured in ms + Bit32u time; + Bit8u asc, ascq; + Bit8u in_progress; + Bit16u ebda_seg = read_word(0x0040,0x000E); + if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) { + printf("not implemented for non-ATAPI device\n"); + return -1; + } + + BX_DEBUG_ATA("ata_detect_medium: begin\n"); + memsetb(get_SS(),packet, 0, sizeof packet); + packet[0] = 0x25; /* READ CAPACITY */ + + /* Retry READ CAPACITY 50 times unless MEDIUM NOT PRESENT + * is reported by the device. If the device reports "IN PROGRESS", + * 30 seconds is added. */ + timeout = 5000; + time = 0; + in_progress = 0; + while (time < timeout) { + if (ata_cmd_packet(device, sizeof(packet), get_SS(), packet, 0, 8L, ATA_DATA_IN, get_SS(), buf) == 0) + goto ok; + + if (atapi_get_sense(device, get_SS(), &asc, &ascq) == 0) { + if (asc == 0x3a) { /* MEDIUM NOT PRESENT */ + BX_DEBUG_ATA("Device reports MEDIUM NOT PRESENT\n"); + return -1; + } + + if (asc == 0x04 && ascq == 0x01 && !in_progress) { + /* IN PROGRESS OF BECOMING READY */ + printf("Waiting for device to detect medium... "); + /* Allow 30 seconds more */ + timeout = 30000; + in_progress = 1; + } + } + time += 100; + } + BX_DEBUG_ATA("read capacity failed\n"); + return -1; +ok: + + block_len = (Bit32u) buf[4] << 24 + | (Bit32u) buf[5] << 16 + | (Bit32u) buf[6] << 8 + | (Bit32u) buf[7] << 0; + BX_DEBUG_ATA("block_len=%u\n", block_len); + + if (block_len!= 2048 && block_len!= 512) + { + printf("Unsupported sector size %u\n", block_len); + return -1; + } + write_dword(ebda_seg,&EbdaData->ata.devices[device].blksize, block_len); + + sectors = (Bit32u) buf[0] << 24 + | (Bit32u) buf[1] << 16 + | (Bit32u) buf[2] << 8 + | (Bit32u) buf[3] << 0; + + BX_DEBUG_ATA("sectors=%u\n", sectors); + if (block_len == 2048) + sectors <<= 2; /* # of sectors in 512-byte "soft" sector */ + if (sectors != read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low)) + printf("%dMB medium detected\n", sectors>>(20-9)); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low, sectors); + return 0; +} + + Bit16u +atapi_is_cdrom(device) + Bit8u device; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + + if (device >= BX_MAX_ATA_DEVICES) + return 0; + + if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) + return 0; + + if (read_byte(ebda_seg,&EbdaData->ata.devices[device].device) != ATA_DEVICE_CDROM) + return 0; + + return 1; +} + +// --------------------------------------------------------------------------- +// End of ATA/ATAPI generic functions +// --------------------------------------------------------------------------- + +#endif // BX_USE_ATADRV + +#if BX_ELTORITO_BOOT + +// --------------------------------------------------------------------------- +// Start of El-Torito boot functions +// --------------------------------------------------------------------------- + + void +cdemu_init() +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + + // the only important data is this one for now + write_byte(ebda_seg,&EbdaData->cdemu.active,0x00); +} + + Bit8u +cdemu_isactive() +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + + return(read_byte(ebda_seg,&EbdaData->cdemu.active)); +} + + Bit8u +cdemu_emulated_drive() +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + + return(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)); +} + +static char isotag[6]="CD001"; +static char eltorito[24]="EL TORITO SPECIFICATION"; +// +// Returns ah: emulated drive, al: error code +// + Bit16u +cdrom_boot() +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u atacmd[12], buffer[2048]; + Bit32u lba; + Bit16u boot_segment, nbsectors, i, error; + Bit8u device; + + // Find out the first cdrom + for (device=0; device= BX_MAX_ATA_DEVICES) return 2; + + if(error = atapi_is_ready(device) != 0) + BX_INFO("ata_is_ready returned %d\n",error); + + // Read the Boot Record Volume Descriptor + memsetb(get_SS(),atacmd,0,12); + atacmd[0]=0x28; // READ command + atacmd[7]=(0x01 & 0xff00) >> 8; // Sectors + atacmd[8]=(0x01 & 0x00ff); // Sectors + atacmd[2]=(0x11 & 0xff000000) >> 24; // LBA + atacmd[3]=(0x11 & 0x00ff0000) >> 16; + atacmd[4]=(0x11 & 0x0000ff00) >> 8; + atacmd[5]=(0x11 & 0x000000ff); + if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) + return 3; + + // Validity checks + if(buffer[0]!=0) return 4; + for(i=0;i<5;i++){ + if(buffer[1+i]!=read_byte(0xf000,&isotag[i])) return 5; + } + for(i=0;i<23;i++) + if(buffer[7+i]!=read_byte(0xf000,&eltorito[i])) return 6; + + // ok, now we calculate the Boot catalog address + lba=buffer[0x4A]*0x1000000+buffer[0x49]*0x10000+buffer[0x48]*0x100+buffer[0x47]; + + // And we read the Boot Catalog + memsetb(get_SS(),atacmd,0,12); + atacmd[0]=0x28; // READ command + atacmd[7]=(0x01 & 0xff00) >> 8; // Sectors + atacmd[8]=(0x01 & 0x00ff); // Sectors + atacmd[2]=(lba & 0xff000000) >> 24; // LBA + atacmd[3]=(lba & 0x00ff0000) >> 16; + atacmd[4]=(lba & 0x0000ff00) >> 8; + atacmd[5]=(lba & 0x000000ff); + if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) + return 7; + + // Validation entry + if(buffer[0x00]!=0x01)return 8; // Header + if(buffer[0x01]!=0x00)return 9; // Platform + if(buffer[0x1E]!=0x55)return 10; // key 1 + if(buffer[0x1F]!=0xAA)return 10; // key 2 + + // Initial/Default Entry + if(buffer[0x20]!=0x88)return 11; // Bootable + + write_byte(ebda_seg,&EbdaData->cdemu.media,buffer[0x21]); + if(buffer[0x21]==0){ + // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0. + // Win2000 cd boot needs to know it booted from cd + write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0xE0); + } + else if(buffer[0x21]<4) + write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0x00); + else + write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0x80); + + write_byte(ebda_seg,&EbdaData->cdemu.controller_index,device/2); + write_byte(ebda_seg,&EbdaData->cdemu.device_spec,device%2); + + boot_segment=buffer[0x23]*0x100+buffer[0x22]; + if(boot_segment==0x0000)boot_segment=0x07C0; + + write_word(ebda_seg,&EbdaData->cdemu.load_segment,boot_segment); + write_word(ebda_seg,&EbdaData->cdemu.buffer_segment,0x0000); + + nbsectors=buffer[0x27]*0x100+buffer[0x26]; + write_word(ebda_seg,&EbdaData->cdemu.sector_count,nbsectors); + + lba=buffer[0x2B]*0x1000000+buffer[0x2A]*0x10000+buffer[0x29]*0x100+buffer[0x28]; + write_dword(ebda_seg,&EbdaData->cdemu.ilba,lba); + + // And we read the image in memory + memsetb(get_SS(),atacmd,0,12); + atacmd[0]=0x28; // READ command + atacmd[7]=((1+(nbsectors-1)/4) & 0xff00) >> 8; // Sectors + atacmd[8]=((1+(nbsectors-1)/4) & 0x00ff); // Sectors + atacmd[2]=(lba & 0xff000000) >> 24; // LBA + atacmd[3]=(lba & 0x00ff0000) >> 16; + atacmd[4]=(lba & 0x0000ff00) >> 8; + atacmd[5]=(lba & 0x000000ff); + if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0) + return 12; + + // Remember the media type + switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) { + case 0x01: // 1.2M floppy + write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,15); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2); + break; + case 0x02: // 1.44M floppy + write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,18); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2); + break; + case 0x03: // 2.88M floppy + write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,36); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2); + break; + case 0x04: // Harddrive + write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,read_byte(boot_segment,446+6)&0x3f); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders, + (read_byte(boot_segment,446+6)<<2) + read_byte(boot_segment,446+7) + 1); + write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,read_byte(boot_segment,446+5) + 1); + break; + } + + if(read_byte(ebda_seg,&EbdaData->cdemu.media)!=0) { + // Increase bios installed hardware number of devices + if(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)==0x00) + write_byte(0x40,0x10,read_byte(0x40,0x10)|0x41); + else + write_byte(ebda_seg, &EbdaData->ata.hdcount, read_byte(ebda_seg, &EbdaData->ata.hdcount) + 1); + } + + // everything is ok, so from now on, the emulation is active + if(read_byte(ebda_seg,&EbdaData->cdemu.media)!=0) + write_byte(ebda_seg,&EbdaData->cdemu.active,0x01); + + // return the boot drive + no error + return (read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)*0x100)+0; +} + +// --------------------------------------------------------------------------- +// End of El-Torito boot functions +// --------------------------------------------------------------------------- +#endif // BX_ELTORITO_BOOT + +void int14_function(regs, ds, iret_addr) + pusha_regs_t regs; // regs pushed from PUSHA instruction + Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper + iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call +{ + Bit16u addr,timer,val16; + Bit8u counter; + + ASM_START + sti + ASM_END + + addr = read_word(0x0040, (regs.u.r16.dx << 1)); + counter = read_byte(0x0040, 0x007C + regs.u.r16.dx); + if ((regs.u.r16.dx < 4) && (addr > 0)) { + switch (regs.u.r8.ah) { + case 0: + outb(addr+3, inb(addr+3) | 0x80); + if (regs.u.r8.al & 0xE0 == 0) { + outb(addr, 0x17); + outb(addr+1, 0x04); + } else { + val16 = 0x600 >> ((regs.u.r8.al & 0xE0) >> 5); + outb(addr, val16 & 0xFF); + outb(addr+1, val16 >> 8); + } + outb(addr+3, regs.u.r8.al & 0x1F); + regs.u.r8.ah = inb(addr+5); + regs.u.r8.al = inb(addr+6); + ClearCF(iret_addr.flags); + break; + case 1: + timer = read_word(0x0040, 0x006C); + while (((inb(addr+5) & 0x60) != 0x60) && (counter)) { + val16 = read_word(0x0040, 0x006C); + if (val16 != timer) { + timer = val16; + counter--; + } + } + if (counter > 0) { + outb(addr, regs.u.r8.al); + regs.u.r8.ah = inb(addr+5); + } else { + regs.u.r8.ah = 0x80; + } + ClearCF(iret_addr.flags); + break; + case 2: + timer = read_word(0x0040, 0x006C); + while (((inb(addr+5) & 0x01) == 0) && (counter)) { + val16 = read_word(0x0040, 0x006C); + if (val16 != timer) { + timer = val16; + counter--; + } + } + if (counter > 0) { + regs.u.r8.ah = inb(addr+5); + regs.u.r8.al = inb(addr); + } else { + regs.u.r8.ah = 0x80; + } + ClearCF(iret_addr.flags); + break; + case 3: + regs.u.r8.ah = inb(addr+5); + regs.u.r8.al = inb(addr+6); + ClearCF(iret_addr.flags); + break; + default: + SetCF(iret_addr.flags); // Unsupported + } + } else { + SetCF(iret_addr.flags); // Unsupported + } +} + + void +int15_function(regs, ES, DS, FLAGS) + pusha_regs_t regs; // REGS pushed via pusha + Bit16u ES, DS, FLAGS; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + bx_bool prev_a20_enable; + Bit16u base15_00; + Bit8u base23_16; + Bit16u ss; + Bit16u BX,CX,DX; + + Bit16u bRegister; + Bit8u irqDisable; + +BX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax); + + switch (regs.u.r8.ah) { + case 0x24: /* A20 Control */ + switch (regs.u.r8.al) { + case 0x00: + set_enable_a20(0); + CLEAR_CF(); + regs.u.r8.ah = 0; + break; + case 0x01: + set_enable_a20(1); + CLEAR_CF(); + regs.u.r8.ah = 0; + break; + case 0x02: + regs.u.r8.al = (inb(PORT_A20) >> 1) & 0x01; + CLEAR_CF(); + regs.u.r8.ah = 0; + break; + case 0x03: + CLEAR_CF(); + regs.u.r8.ah = 0; + regs.u.r16.bx = 3; + break; + default: + BX_INFO("int15: Func 24h, subfunc %02xh, A20 gate control not supported\n", (unsigned) regs.u.r8.al); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + break; + + case 0x41: + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + break; + + case 0x4f: + /* keyboard intercept */ + // nop + SET_CF(); + break; + + case 0x52: // removable media eject + CLEAR_CF(); + regs.u.r8.ah = 0; // "ok ejection may proceed" + break; + + case 0x83: { + if( regs.u.r8.al == 0 ) { + // Set Interval requested. + if( ( read_byte( 0x40, 0xA0 ) & 1 ) == 0 ) { + // Interval not already set. + write_byte( 0x40, 0xA0, 1 ); // Set status byte. + write_word( 0x40, 0x98, ES ); // Byte location, segment + write_word( 0x40, 0x9A, regs.u.r16.bx ); // Byte location, offset + write_word( 0x40, 0x9C, regs.u.r16.dx ); // Low word, delay + write_word( 0x40, 0x9E, regs.u.r16.cx ); // High word, delay. + CLEAR_CF( ); + irqDisable = inb( PORT_PIC2_DATA ); + outb( PORT_PIC2_DATA, irqDisable & 0xFE ); + bRegister = inb_cmos( 0xB ); // Unmask IRQ8 so INT70 will get through. + outb_cmos( 0xB, bRegister | 0x40 ); // Turn on the Periodic Interrupt timer + } else { + // Interval already set. + BX_DEBUG_INT15("int15: Func 83h, failed, already waiting.\n" ); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + } else if( regs.u.r8.al == 1 ) { + // Clear Interval requested + write_byte( 0x40, 0xA0, 0 ); // Clear status byte + CLEAR_CF( ); + bRegister = inb_cmos( 0xB ); + outb_cmos( 0xB, bRegister & ~0x40 ); // Turn off the Periodic Interrupt timer + } else { + BX_DEBUG_INT15("int15: Func 83h, failed.\n" ); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + regs.u.r8.al--; + } + + break; + } + + case 0x87: + // +++ should probably have descriptor checks + // +++ should have exception handlers + + // turn off interrupts +ASM_START + cli +ASM_END + + prev_a20_enable = set_enable_a20(1); // enable A20 line + + // 128K max of transfer on 386+ ??? + // source == destination ??? + + // ES:SI points to descriptor table + // offset use initially comments + // ============================================== + // 00..07 Unused zeros Null descriptor + // 08..0f GDT zeros filled in by BIOS + // 10..17 source ssssssss source of data + // 18..1f dest dddddddd destination of data + // 20..27 CS zeros filled in by BIOS + // 28..2f SS zeros filled in by BIOS + + //es:si + //eeee0 + //0ssss + //----- + +// check for access rights of source & dest here + + // Initialize GDT descriptor + base15_00 = (ES << 4) + regs.u.r16.si; + base23_16 = ES >> 12; + if (base15_00 < (ES<<4)) + base23_16++; + write_word(ES, regs.u.r16.si+0x08+0, 47); // limit 15:00 = 6 * 8bytes/descriptor + write_word(ES, regs.u.r16.si+0x08+2, base15_00);// base 15:00 + write_byte(ES, regs.u.r16.si+0x08+4, base23_16);// base 23:16 + write_byte(ES, regs.u.r16.si+0x08+5, 0x93); // access + write_word(ES, regs.u.r16.si+0x08+6, 0x0000); // base 31:24/reserved/limit 19:16 + + // Initialize CS descriptor + write_word(ES, regs.u.r16.si+0x20+0, 0xffff);// limit 15:00 = normal 64K limit + write_word(ES, regs.u.r16.si+0x20+2, 0x0000);// base 15:00 + write_byte(ES, regs.u.r16.si+0x20+4, 0x000f);// base 23:16 + write_byte(ES, regs.u.r16.si+0x20+5, 0x9b); // access + write_word(ES, regs.u.r16.si+0x20+6, 0x0000);// base 31:24/reserved/limit 19:16 + + // Initialize SS descriptor + ss = get_SS(); + base15_00 = ss << 4; + base23_16 = ss >> 12; + write_word(ES, regs.u.r16.si+0x28+0, 0xffff); // limit 15:00 = normal 64K limit + write_word(ES, regs.u.r16.si+0x28+2, base15_00);// base 15:00 + write_byte(ES, regs.u.r16.si+0x28+4, base23_16);// base 23:16 + write_byte(ES, regs.u.r16.si+0x28+5, 0x93); // access + write_word(ES, regs.u.r16.si+0x28+6, 0x0000); // base 31:24/reserved/limit 19:16 + + CX = regs.u.r16.cx; +ASM_START + // Compile generates locals offset info relative to SP. + // Get CX (word count) from stack. + mov bx, sp + SEG SS + mov cx, _int15_function.CX [bx] + + // since we need to set SS:SP, save them to the BDA + // for future restore + push eax + xor eax, eax + mov ds, ax + mov 0x0469, ss + mov 0x0467, sp + + SEG ES + lgdt [si + 0x08] + SEG CS + lidt [pmode_IDT_info] + ;; perhaps do something with IDT here + + ;; set PE bit in CR0 + mov eax, cr0 + or al, #0x01 + mov cr0, eax + ;; far jump to flush CPU queue after transition to protected mode + JMP_AP(0x0020, protected_mode) + +protected_mode: + ;; GDT points to valid descriptor table, now load SS, DS, ES + mov ax, #0x28 ;; 101 000 = 5th descriptor in table, TI=GDT, RPL=00 + mov ss, ax + mov ax, #0x10 ;; 010 000 = 2nd descriptor in table, TI=GDT, RPL=00 + mov ds, ax + mov ax, #0x18 ;; 011 000 = 3rd descriptor in table, TI=GDT, RPL=00 + mov es, ax + xor si, si + xor di, di + cld + rep + movsw ;; move CX words from DS:SI to ES:DI + + ;; make sure DS and ES limits are 64KB + mov ax, #0x28 + mov ds, ax + mov es, ax + + ;; reset PG bit in CR0 ??? + mov eax, cr0 + and al, #0xFE + mov cr0, eax + + ;; far jump to flush CPU queue after transition to real mode + JMP_AP(0xf000, real_mode) + +real_mode: + ;; restore IDT to normal real-mode defaults + SEG CS + lidt [rmode_IDT_info] + + // restore SS:SP from the BDA + xor ax, ax + mov ds, ax + mov ss, 0x0469 + mov sp, 0x0467 + pop eax +ASM_END + + set_enable_a20(prev_a20_enable); + + // turn back on interrupts +ASM_START + sti +ASM_END + + regs.u.r8.ah = 0; + CLEAR_CF(); + break; + + + case 0x88: + // Get the amount of extended memory (above 1M) + regs.u.r8.al = inb_cmos(0x30); + regs.u.r8.ah = inb_cmos(0x31); + + // According to Ralf Brown's interrupt the limit should be 15M, + // but real machines mostly return max. 63M. + if(regs.u.r16.ax > 0xffc0) + regs.u.r16.ax = 0xffc0; + + CLEAR_CF(); + break; + + case 0x89: + // Switch to Protected Mode. + // ES:DI points to user-supplied GDT + // BH/BL contains starting interrupt numbers for PIC0/PIC1 + // This subfunction does not return! + +// turn off interrupts +ASM_START + cli +ASM_END + + set_enable_a20(1); // enable A20 line; we're supposed to fail if that fails + + // Initialize CS descriptor for BIOS + write_word(ES, regs.u.r16.si+0x38+0, 0xffff);// limit 15:00 = normal 64K limit + write_word(ES, regs.u.r16.si+0x38+2, 0x0000);// base 15:00 + write_byte(ES, regs.u.r16.si+0x38+4, 0x000f);// base 23:16 (hardcoded to f000:0000) + write_byte(ES, regs.u.r16.si+0x38+5, 0x9b); // access + write_word(ES, regs.u.r16.si+0x38+6, 0x0000);// base 31:24/reserved/limit 19:16 + + BX = regs.u.r16.bx; +ASM_START + // Compiler generates locals offset info relative to SP. + // Get BX (PIC offsets) from stack. + mov bx, sp + SEG SS + mov bx, _int15_function.BX [bx] + + // Program PICs + mov al, #0x11 ; send initialisation commands + out PORT_PIC1_CMD, al + out PORT_PIC2_CMD, al + mov al, bh + out PORT_PIC1_DATA, al + mov al, bl + out PORT_PIC2_DATA, al + mov al, #0x04 + out PORT_PIC1_DATA, al + mov al, #0x02 + out PORT_PIC2_DATA, al + mov al, #0x01 + out PORT_PIC1_DATA, al + out PORT_PIC2_DATA, al + mov al, #0xff ; mask all IRQs, user must re-enable + out PORT_PIC1_DATA, al + out PORT_PIC2_DATA, al + + // Load GDT and IDT from supplied data + SEG ES + lgdt [si + 0x08] + SEG ES + lidt [si + 0x10] + + // set PE bit in CR0 + mov eax, cr0 + or al, #0x01 + mov cr0, eax + // far jump to flush CPU queue after transition to protected mode + JMP_AP(0x0038, protmode_switch) + +protmode_switch: + ;; GDT points to valid descriptor table, now load SS, DS, ES + mov ax, #0x28 + mov ss, ax + mov ax, #0x18 + mov ds, ax + mov ax, #0x20 + mov es, ax + + // unwind the stack - this will break if calling sequence changes! + mov sp,bp + add sp,#4 ; skip return address + popa ; restore regs + pop ax ; skip saved es + pop ax ; skip saved ds + pop ax ; skip saved flags + + // return to caller - note that we do not use IRET because + // we cannot enable interrupts + pop cx ; get return offset + pop ax ; skip return segment + pop ax ; skip flags + mov ax, #0x30 ; ah must be 0 on successful exit + push ax + push cx ; re-create modified ret address on stack + retf + +ASM_END + + break; + + case 0x90: + /* Device busy interrupt. Called by Int 16h when no key available */ + break; + + case 0x91: + /* Interrupt complete. Called by Int 16h when key becomes available */ + break; + + case 0xbf: + BX_INFO("*** int 15h function AH=bf not yet supported!\n"); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + break; + + case 0xC0: +#if 0 + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + break; +#endif + CLEAR_CF(); + regs.u.r8.ah = 0; + regs.u.r16.bx = BIOS_CONFIG_TABLE; + ES = 0xF000; + break; + + case 0xc1: + ES = ebda_seg; + CLEAR_CF(); + break; + + case 0xd8: + bios_printf(BIOS_PRINTF_DEBUG, "EISA BIOS not present\n"); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + break; + + default: + BX_INFO("*** int 15h function AX=%04x, BX=%04x not yet supported!\n", + (unsigned) regs.u.r16.ax, (unsigned) regs.u.r16.bx); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + break; + } +} + +#if BX_USE_PS2_MOUSE + void +int15_function_mouse(regs, ES, DS, FLAGS) + pusha_regs_t regs; // REGS pushed via pusha + Bit16u ES, DS, FLAGS; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u mouse_flags_1, mouse_flags_2; + Bit16u mouse_driver_seg; + Bit16u mouse_driver_offset; + Bit8u comm_byte, prev_command_byte; + Bit8u ret, mouse_data1, mouse_data2, mouse_data3; + +BX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax); + + switch (regs.u.r8.ah) { + case 0xC2: + // Return Codes status in AH + // ========================= + // 00: success + // 01: invalid subfunction (AL > 7) + // 02: invalid input value (out of allowable range) + // 03: interface error + // 04: resend command received from mouse controller, + // device driver should attempt command again + // 05: cannot enable mouse, since no far call has been installed + // 80/86: mouse service not implemented + + switch (regs.u.r8.al) { + case 0: // Disable/Enable Mouse +BX_DEBUG_INT15("case 0:\n"); + switch (regs.u.r8.bh) { + case 0: // Disable Mouse +BX_DEBUG_INT15("case 0: disable mouse\n"); + inhibit_mouse_int_and_events(); // disable IRQ12 and packets + ret = send_to_mouse_ctrl(0xF5); // disable mouse command + if (ret == 0) { + ret = get_mouse_data(&mouse_data1); + if ( (ret == 0) || (mouse_data1 == 0xFA) ) { + CLEAR_CF(); + regs.u.r8.ah = 0; + return; + } + } + + // error + SET_CF(); + regs.u.r8.ah = ret; + return; + break; + + case 1: // Enable Mouse +BX_DEBUG_INT15("case 1: enable mouse\n"); + mouse_flags_2 = read_byte(ebda_seg, &EbdaData->mouse_flag2); + if ( (mouse_flags_2 & 0x80) == 0 ) { + BX_DEBUG_INT15("INT 15h C2 Enable Mouse, no far call handler\n"); + SET_CF(); // error + regs.u.r8.ah = 5; // no far call installed + return; + } + inhibit_mouse_int_and_events(); // disable IRQ12 and packets + ret = send_to_mouse_ctrl(0xF4); // enable mouse command + if (ret == 0) { + ret = get_mouse_data(&mouse_data1); + if ( (ret == 0) && (mouse_data1 == 0xFA) ) { + enable_mouse_int_and_events(); // turn IRQ12 and packet generation on + CLEAR_CF(); + regs.u.r8.ah = 0; + return; + } + } + SET_CF(); + regs.u.r8.ah = ret; + return; + + default: // invalid subfunction + BX_DEBUG_INT15("INT 15h C2 AL=0, BH=%02x\n", (unsigned) regs.u.r8.bh); + SET_CF(); // error + regs.u.r8.ah = 1; // invalid subfunction + return; + } + break; + + case 1: // Reset Mouse + case 5: // Initialize Mouse +BX_DEBUG_INT15("case 1 or 5:\n"); + if (regs.u.r8.al == 5) { + if (regs.u.r8.bh != 3) { + SET_CF(); + regs.u.r8.ah = 0x02; // invalid input + return; + } + mouse_flags_2 = read_byte(ebda_seg, &EbdaData->mouse_flag2); + mouse_flags_2 = (mouse_flags_2 & 0x00) | regs.u.r8.bh; + mouse_flags_1 = 0x00; + write_byte(ebda_seg, &EbdaData->mouse_flag1, mouse_flags_1); + write_byte(ebda_seg, &EbdaData->mouse_flag2, mouse_flags_2); + } + + inhibit_mouse_int_and_events(); // disable IRQ12 and packets + ret = send_to_mouse_ctrl(0xFF); // reset mouse command + if (ret == 0) { + ret = get_mouse_data(&mouse_data3); + // if no mouse attached, it will return RESEND + if (mouse_data3 == 0xfe) { + SET_CF(); + return; + } + if (mouse_data3 != 0xfa) + BX_PANIC("Mouse reset returned %02x (should be ack)\n", (unsigned)mouse_data3); + if ( ret == 0 ) { + ret = get_mouse_data(&mouse_data1); + if ( ret == 0 ) { + ret = get_mouse_data(&mouse_data2); + if ( ret == 0 ) { + // turn IRQ12 and packet generation on + enable_mouse_int_and_events(); + CLEAR_CF(); + regs.u.r8.ah = 0; + regs.u.r8.bl = mouse_data1; + regs.u.r8.bh = mouse_data2; + return; + } + } + } + } + + // error + SET_CF(); + regs.u.r8.ah = ret; + return; + + case 2: // Set Sample Rate +BX_DEBUG_INT15("case 2:\n"); + switch (regs.u.r8.bh) { + case 0: mouse_data1 = 10; break; // 10 reports/sec + case 1: mouse_data1 = 20; break; // 20 reports/sec + case 2: mouse_data1 = 40; break; // 40 reports/sec + case 3: mouse_data1 = 60; break; // 60 reports/sec + case 4: mouse_data1 = 80; break; // 80 reports/sec + case 5: mouse_data1 = 100; break; // 100 reports/sec (default) + case 6: mouse_data1 = 200; break; // 200 reports/sec + default: mouse_data1 = 0; + } + if (mouse_data1 > 0) { + ret = send_to_mouse_ctrl(0xF3); // set sample rate command + if (ret == 0) { + ret = get_mouse_data(&mouse_data2); + ret = send_to_mouse_ctrl(mouse_data1); + ret = get_mouse_data(&mouse_data2); + CLEAR_CF(); + regs.u.r8.ah = 0; + } else { + // error + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + } else { + // error + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + break; + + case 3: // Set Resolution +BX_DEBUG_INT15("case 3:\n"); + // BH: + // 0 = 25 dpi, 1 count per millimeter + // 1 = 50 dpi, 2 counts per millimeter + // 2 = 100 dpi, 4 counts per millimeter + // 3 = 200 dpi, 8 counts per millimeter + comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets + if (regs.u.r8.bh < 4) { + ret = send_to_mouse_ctrl(0xE8); // set resolution command + if (ret == 0) { + ret = get_mouse_data(&mouse_data1); + if (mouse_data1 != 0xfa) + BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1); + ret = send_to_mouse_ctrl(regs.u.r8.bh); + ret = get_mouse_data(&mouse_data1); + if (mouse_data1 != 0xfa) + BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1); + CLEAR_CF(); + regs.u.r8.ah = 0; + } else { + // error + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + } else { + // error + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable + break; + + case 4: // Get Device ID +BX_DEBUG_INT15("case 4:\n"); + inhibit_mouse_int_and_events(); // disable IRQ12 and packets + ret = send_to_mouse_ctrl(0xF2); // get mouse ID command + if (ret == 0) { + ret = get_mouse_data(&mouse_data1); + ret = get_mouse_data(&mouse_data2); + CLEAR_CF(); + regs.u.r8.ah = 0; + regs.u.r8.bh = mouse_data2; + } else { + // error + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + break; + + case 6: // Return Status & Set Scaling Factor... +BX_DEBUG_INT15("case 6:\n"); + switch (regs.u.r8.bh) { + case 0: // Return Status + comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets + ret = send_to_mouse_ctrl(0xE9); // get mouse info command + if (ret == 0) { + ret = get_mouse_data(&mouse_data1); + if (mouse_data1 != 0xfa) + BX_PANIC("Mouse status returned %02x (should be ack)\n", (unsigned)mouse_data1); + if (ret == 0) { + ret = get_mouse_data(&mouse_data1); + if (ret == 0) { + ret = get_mouse_data(&mouse_data2); + if (ret == 0) { + ret = get_mouse_data(&mouse_data3); + if (ret == 0) { + CLEAR_CF(); + regs.u.r8.ah = 0; + regs.u.r8.bl = mouse_data1; + regs.u.r8.cl = mouse_data2; + regs.u.r8.dl = mouse_data3; + set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable + return; + } + } + } + } + } + + // error + SET_CF(); + regs.u.r8.ah = ret; + set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable + return; + + case 1: // Set Scaling Factor to 1:1 + case 2: // Set Scaling Factor to 2:1 + comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets + if (regs.u.r8.bh == 1) { + ret = send_to_mouse_ctrl(0xE6); + } else { + ret = send_to_mouse_ctrl(0xE7); + } + if (ret == 0) { + get_mouse_data(&mouse_data1); + ret = (mouse_data1 != 0xFA); + } + if (ret == 0) { + CLEAR_CF(); + regs.u.r8.ah = 0; + } else { + // error + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + } + set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable + break; + + default: + BX_PANIC("INT 15h C2 AL=6, BH=%02x\n", (unsigned) regs.u.r8.bh); + } + break; + + case 7: // Set Mouse Handler Address +BX_DEBUG_INT15("case 7:\n"); + mouse_driver_seg = ES; + mouse_driver_offset = regs.u.r16.bx; + write_word(ebda_seg, &EbdaData->mouse_driver_offset, mouse_driver_offset); + write_word(ebda_seg, &EbdaData->mouse_driver_seg, mouse_driver_seg); + mouse_flags_2 = read_byte(ebda_seg, &EbdaData->mouse_flag2); + if (mouse_driver_offset == 0 && mouse_driver_seg == 0) { + /* remove handler */ + if ( (mouse_flags_2 & 0x80) != 0 ) { + mouse_flags_2 &= ~0x80; + inhibit_mouse_int_and_events(); // disable IRQ12 and packets + } + } + else { + /* install handler */ + mouse_flags_2 |= 0x80; + } + write_byte(ebda_seg, &EbdaData->mouse_flag2, mouse_flags_2); + CLEAR_CF(); + regs.u.r8.ah = 0; + break; + + default: +BX_DEBUG_INT15("case default:\n"); + regs.u.r8.ah = 1; // invalid function + SET_CF(); + } + break; + + default: + BX_INFO("*** int 15h function AX=%04x, BX=%04x not yet supported!\n", + (unsigned) regs.u.r16.ax, (unsigned) regs.u.r16.bx); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + break; + } +} +#endif // BX_USE_PS2_MOUSE + + +void set_e820_range(ES, DI, start, end, extra_start, extra_end, type) + Bit16u ES; + Bit16u DI; + Bit32u start; + Bit32u end; + Bit8u extra_start; + Bit8u extra_end; + Bit16u type; +{ + write_word(ES, DI, start); + write_word(ES, DI+2, start >> 16); + write_word(ES, DI+4, extra_start); + write_word(ES, DI+6, 0x00); + + end -= start; + extra_end -= extra_start; + write_word(ES, DI+8, end); + write_word(ES, DI+10, end >> 16); + write_word(ES, DI+12, extra_end); + write_word(ES, DI+14, 0x0000); + + write_word(ES, DI+16, type); + write_word(ES, DI+18, 0x0); +} + + void +int15_function32(regs, ES, DS, FLAGS) + pushad_regs_t regs; // REGS pushed via pushad + Bit16u ES, DS, FLAGS; +{ + Bit32u extended_memory_size=0; // 64bits long + Bit32u extra_lowbits_memory_size=0; + Bit16u CX,DX; + Bit8u extra_highbits_memory_size=0; + +BX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax); + + switch (regs.u.r8.ah) { + case 0x86: + // Wait for CX:DX microseconds. currently using the + // refresh request port 0x61 bit4, toggling every 15usec + + CX = regs.u.r16.cx; + DX = regs.u.r16.dx; + +ASM_START + sti + + ;; Get the count in eax + mov bx, sp + SEG SS + mov ax, _int15_function32.CX [bx] + shl eax, #16 + SEG SS + mov ax, _int15_function32.DX [bx] + + ;; convert to numbers of 15usec ticks + mov ebx, #15 + xor edx, edx + div eax, ebx + mov ecx, eax + + ;; wait for ecx number of refresh requests + in al, PORT_PS2_CTRLB + and al,#0x10 + mov ah, al + + or ecx, ecx + je int1586_tick_end +int1586_tick: + in al, PORT_PS2_CTRLB + and al,#0x10 + cmp al, ah + je int1586_tick + mov ah, al + dec ecx + jnz int1586_tick +int1586_tick_end: +ASM_END + + break; + + case 0xe8: + switch(regs.u.r8.al) { + case 0x20: // coded by osmaker aka K.J. + if(regs.u.r32.edx == 0x534D4150) + { + extended_memory_size = inb_cmos(0x35); + extended_memory_size <<= 8; + extended_memory_size |= inb_cmos(0x34); + extended_memory_size *= 64; + if(extended_memory_size > 0x2fc000) { + extended_memory_size = 0x2fc000; // everything after this is reserved memory until we get to 0x100000000 + } + extended_memory_size *= 1024; + extended_memory_size += (16L * 1024 * 1024); + + if(extended_memory_size <= (16L * 1024 * 1024)) { + extended_memory_size = inb_cmos(0x31); + extended_memory_size <<= 8; + extended_memory_size |= inb_cmos(0x30); + extended_memory_size *= 1024; + extended_memory_size += (1L * 1024 * 1024); + } + + extra_lowbits_memory_size = inb_cmos(0x5c); + extra_lowbits_memory_size <<= 8; + extra_lowbits_memory_size |= inb_cmos(0x5b); + extra_lowbits_memory_size *= 64; + extra_lowbits_memory_size *= 1024; + extra_highbits_memory_size = inb_cmos(0x5d); + + switch(regs.u.r16.bx) + { + case 0: + set_e820_range(ES, regs.u.r16.di, + 0x0000000L, 0x0009f000L, 0, 0, E820_RAM); + regs.u.r32.ebx = 1; + break; + case 1: + set_e820_range(ES, regs.u.r16.di, + 0x0009f000L, 0x000a0000L, 0, 0, E820_RESERVED); + regs.u.r32.ebx = 2; + break; + case 2: + set_e820_range(ES, regs.u.r16.di, + 0x000e8000L, 0x00100000L, 0, 0, E820_RESERVED); + if (extended_memory_size <= 0x100000) + regs.u.r32.ebx = 6; + else + regs.u.r32.ebx = 3; + break; + case 3: +#if BX_ROMBIOS32 +#ifdef BX_USE_EBDA_TABLES + set_e820_range(ES, regs.u.r16.di, + 0x00100000L, + extended_memory_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE, 0, 0, E820_RAM); + regs.u.r32.ebx = 4; +#else + set_e820_range(ES, regs.u.r16.di, + 0x00100000L, + extended_memory_size - ACPI_DATA_SIZE, 0, 0, E820_RAM); + regs.u.r32.ebx = 5; +#endif +#else + set_e820_range(ES, regs.u.r16.di, + 0x00100000L, + extended_memory_size, 0, 0, E820_RAM); + regs.u.r32.ebx = 6; +#endif + break; + case 4: + set_e820_range(ES, regs.u.r16.di, + extended_memory_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE, + extended_memory_size - ACPI_DATA_SIZE, 0, 0, E820_RESERVED); + regs.u.r32.ebx = 5; + break; + case 5: + set_e820_range(ES, regs.u.r16.di, + extended_memory_size - ACPI_DATA_SIZE, + extended_memory_size, 0, 0, E820_ACPI); + regs.u.r32.ebx = 6; + break; + case 6: + /* 256KB BIOS area at the end of 4 GB */ + set_e820_range(ES, regs.u.r16.di, + 0xfffc0000L, 0x00000000L, 0, 0, E820_RESERVED); + if (extra_highbits_memory_size || extra_lowbits_memory_size) + regs.u.r32.ebx = 7; + else + regs.u.r32.ebx = 0; + break; + case 7: + /* Mapping of memory above 4 GB */ + set_e820_range(ES, regs.u.r16.di, 0x00000000L, + extra_lowbits_memory_size, 1, extra_highbits_memory_size + + 1, E820_RAM); + regs.u.r32.ebx = 0; + break; + default: /* AX=E820, DX=534D4150, BX unrecognized */ + goto int15_unimplemented; + break; + } + regs.u.r32.eax = 0x534D4150; + regs.u.r32.ecx = 0x14; + CLEAR_CF(); + } else { + // if DX != 0x534D4150) + goto int15_unimplemented; + } + break; + + case 0x01: + // do we have any reason to fail here ? + CLEAR_CF(); + + // my real system sets ax and bx to 0 + // this is confirmed by Ralph Brown list + // but syslinux v1.48 is known to behave + // strangely if ax is set to 0 + // regs.u.r16.ax = 0; + // regs.u.r16.bx = 0; + + // Get the amount of extended memory (above 1M) + regs.u.r8.cl = inb_cmos(0x30); + regs.u.r8.ch = inb_cmos(0x31); + + // limit to 15M + if(regs.u.r16.cx > 0x3c00) + { + regs.u.r16.cx = 0x3c00; + } + + // Get the amount of extended memory above 16M in 64k blocs + regs.u.r8.dl = inb_cmos(0x34); + regs.u.r8.dh = inb_cmos(0x35); + + // Set configured memory equal to extended memory + regs.u.r16.ax = regs.u.r16.cx; + regs.u.r16.bx = regs.u.r16.dx; + break; + default: /* AH=0xE8?? but not implemented */ + goto int15_unimplemented; + } + break; + int15_unimplemented: + // fall into the default + default: + BX_INFO("*** int 15h function AX=%04x, BX=%04x not yet supported!\n", + (unsigned) regs.u.r16.ax, (unsigned) regs.u.r16.bx); + SET_CF(); + regs.u.r8.ah = UNSUPPORTED_FUNCTION; + break; + } +} + + void +int16_function(DI, SI, BP, SP, BX, DX, CX, AX, FLAGS) + Bit16u DI, SI, BP, SP, BX, DX, CX, AX, FLAGS; +{ + Bit8u scan_code, ascii_code, shift_flags, led_flags, count; + Bit16u kbd_code, max; + + BX_DEBUG_INT16("int16: AX=%04x BX=%04x CX=%04x DX=%04x \n", AX, BX, CX, DX); + + shift_flags = read_byte(0x0040, 0x17); + led_flags = read_byte(0x0040, 0x97); + if ((((shift_flags >> 4) & 0x07) ^ (led_flags & 0x07)) != 0) { +ASM_START + cli +ASM_END + outb(PORT_PS2_DATA, 0xed); + while ((inb(PORT_PS2_STATUS) & 0x01) == 0) outb(PORT_DIAG, 0x21); + if ((inb(PORT_PS2_DATA) == 0xfa)) { + led_flags &= 0xf8; + led_flags |= ((shift_flags >> 4) & 0x07); + outb(PORT_PS2_DATA, led_flags & 0x07); + while ((inb(PORT_PS2_STATUS) & 0x01) == 0) outb(PORT_DIAG, 0x21); + inb(PORT_PS2_DATA); + write_byte(0x0040, 0x97, led_flags); + } +ASM_START + sti +ASM_END + } + + switch (GET_AH()) { + case 0x00: /* read keyboard input */ + + if ( !dequeue_key(&scan_code, &ascii_code, 1) ) { + BX_PANIC("KBD: int16h: out of keyboard input\n"); + } + if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0; + else if (ascii_code == 0xE0) ascii_code = 0; + AX = (scan_code << 8) | ascii_code; + break; + + case 0x01: /* check keyboard status */ + if ( !dequeue_key(&scan_code, &ascii_code, 0) ) { + SET_ZF(); + return; + } + if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0; + else if (ascii_code == 0xE0) ascii_code = 0; + AX = (scan_code << 8) | ascii_code; + CLEAR_ZF(); + break; + + case 0x02: /* get shift flag status */ + shift_flags = read_byte(0x0040, 0x17); + SET_AL(shift_flags); + break; + + case 0x05: /* store key-stroke into buffer */ + if ( !enqueue_key(GET_CH(), GET_CL()) ) { + SET_AL(1); + } + else { + SET_AL(0); + } + break; + + case 0x09: /* GET KEYBOARD FUNCTIONALITY */ + // bit Bochs Description + // 7 0 reserved + // 6 0 INT 16/AH=20h-22h supported (122-key keyboard support) + // 5 1 INT 16/AH=10h-12h supported (enhanced keyboard support) + // 4 1 INT 16/AH=0Ah supported + // 3 0 INT 16/AX=0306h supported + // 2 0 INT 16/AX=0305h supported + // 1 0 INT 16/AX=0304h supported + // 0 0 INT 16/AX=0300h supported + // + SET_AL(0x30); + break; + + case 0x0A: /* GET KEYBOARD ID */ + count = 2; + kbd_code = 0x0; + outb(PORT_PS2_DATA, 0xf2); + /* Wait for data */ + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x00); + if (max>0x0) { + if ((inb(PORT_PS2_DATA) == 0xfa)) { + do { + max=0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) outb(PORT_DIAG, 0x00); + if (max>0x0) { + kbd_code >>= 8; + kbd_code |= (inb(PORT_PS2_DATA) << 8); + } + } while (--count>0); + } + } + BX=kbd_code; + break; + + case 0x10: /* read MF-II keyboard input */ + + if ( !dequeue_key(&scan_code, &ascii_code, 1) ) { + BX_PANIC("KBD: int16h: out of keyboard input\n"); + } + if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0; + AX = (scan_code << 8) | ascii_code; + break; + + case 0x11: /* check MF-II keyboard status */ + if ( !dequeue_key(&scan_code, &ascii_code, 0) ) { + SET_ZF(); + return; + } + if (scan_code !=0 && ascii_code == 0xF0) ascii_code = 0; + AX = (scan_code << 8) | ascii_code; + CLEAR_ZF(); + break; + + case 0x12: /* get extended keyboard status */ + shift_flags = read_byte(0x0040, 0x17); + SET_AL(shift_flags); + shift_flags = read_byte(0x0040, 0x18) & 0x73; + shift_flags |= read_byte(0x0040, 0x96) & 0x0c; + SET_AH(shift_flags); + BX_DEBUG_INT16("int16: func 12 sending %04x\n",AX); + break; + + case 0x92: /* keyboard capability check called by DOS 5.0+ keyb */ + SET_AH(0x80); // function int16 ah=0x10-0x12 supported + break; + + case 0xA2: /* 122 keys capability check called by DOS 5.0+ keyb */ + // don't change AH : function int16 ah=0x20-0x22 NOT supported + break; + + case 0x6F: + if (GET_AL() == 0x08) + SET_AH(0x02); // unsupported, aka normal keyboard + + default: + BX_INFO("KBD: unsupported int 16h function %02x\n", GET_AH()); + } +} + + unsigned int +dequeue_key(scan_code, ascii_code, incr) + Bit8u *scan_code; + Bit8u *ascii_code; + unsigned int incr; +{ + Bit16u buffer_start, buffer_end, buffer_head, buffer_tail; + Bit16u ss; + Bit8u acode, scode; + + buffer_start = read_word(0x0040, 0x0080); + buffer_end = read_word(0x0040, 0x0082); + + buffer_head = read_word(0x0040, 0x001a); + buffer_tail = read_word(0x0040, 0x001c); + + if (buffer_head != buffer_tail) { + ss = get_SS(); + acode = read_byte(0x0040, buffer_head); + scode = read_byte(0x0040, buffer_head+1); + write_byte(ss, ascii_code, acode); + write_byte(ss, scan_code, scode); + + if (incr) { + buffer_head += 2; + if (buffer_head >= buffer_end) + buffer_head = buffer_start; + write_word(0x0040, 0x001a, buffer_head); + } + return(1); + } + else { + return(0); + } +} + +static char panic_msg_keyb_buffer_full[] = "%s: keyboard input buffer full\n"; + + Bit8u +inhibit_mouse_int_and_events() +{ + Bit8u command_byte, prev_command_byte; + + // Turn off IRQ generation and aux data line + if ( inb(PORT_PS2_STATUS) & 0x02 ) + BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse"); + outb(PORT_PS2_STATUS, 0x20); // get command byte + while ( (inb(PORT_PS2_STATUS) & 0x01) != 0x01 ); + prev_command_byte = inb(PORT_PS2_DATA); + command_byte = prev_command_byte; + //while ( (inb(PORT_PS2_STATUS) & 0x02) ); + if ( inb(PORT_PS2_STATUS) & 0x02 ) + BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse"); + command_byte &= 0xfd; // turn off IRQ 12 generation + command_byte |= 0x20; // disable mouse serial clock line + outb(PORT_PS2_STATUS, 0x60); // write command byte + outb(PORT_PS2_DATA, command_byte); + return(prev_command_byte); +} + + void +enable_mouse_int_and_events() +{ + Bit8u command_byte; + + // Turn on IRQ generation and aux data line + if ( inb(PORT_PS2_STATUS) & 0x02 ) + BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse"); + outb(PORT_PS2_STATUS, 0x20); // get command byte + while ( (inb(PORT_PS2_STATUS) & 0x01) != 0x01 ); + command_byte = inb(PORT_PS2_DATA); + //while ( (inb(PORT_PS2_STATUS) & 0x02) ); + if ( inb(PORT_PS2_STATUS) & 0x02 ) + BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse"); + command_byte |= 0x02; // turn on IRQ 12 generation + command_byte &= 0xdf; // enable mouse serial clock line + outb(PORT_PS2_STATUS, 0x60); // write command byte + outb(PORT_PS2_DATA, command_byte); +} + + Bit8u +send_to_mouse_ctrl(sendbyte) + Bit8u sendbyte; +{ + Bit8u response; + + // wait for chance to write to ctrl + if ( inb(PORT_PS2_STATUS) & 0x02 ) + BX_PANIC(panic_msg_keyb_buffer_full,"sendmouse"); + outb(PORT_PS2_STATUS, 0xD4); + outb(PORT_PS2_DATA, sendbyte); + return(0); +} + + + Bit8u +get_mouse_data(data) + Bit8u *data; +{ + Bit8u response; + Bit16u ss; + + while ((inb(PORT_PS2_STATUS) & 0x21) != 0x21) { } + + response = inb(PORT_PS2_DATA); + + ss = get_SS(); + write_byte(ss, data, response); + return(0); +} + + void +set_kbd_command_byte(command_byte) + Bit8u command_byte; +{ + if ( inb(PORT_PS2_STATUS) & 0x02 ) + BX_PANIC(panic_msg_keyb_buffer_full,"setkbdcomm"); + outb(PORT_PS2_STATUS, 0xD4); + + outb(PORT_PS2_STATUS, 0x60); // write command byte + outb(PORT_PS2_DATA, command_byte); +} + + void +int09_function(DI, SI, BP, SP, BX, DX, CX, AX) + Bit16u DI, SI, BP, SP, BX, DX, CX, AX; +{ + Bit8u scancode, asciicode, shift_flags; + Bit8u mf2_flags, mf2_state; + + // + // DS has been set to F000 before call + // + + + scancode = GET_AL(); + + if (scancode == 0) { + BX_INFO("KBD: int09 handler: AL=0\n"); + return; + } + + + shift_flags = read_byte(0x0040, 0x17); + mf2_flags = read_byte(0x0040, 0x18); + mf2_state = read_byte(0x0040, 0x96); + asciicode = 0; + + switch (scancode) { + case 0x3a: /* Caps Lock press */ + shift_flags ^= 0x40; + write_byte(0x0040, 0x17, shift_flags); + mf2_flags |= 0x40; + write_byte(0x0040, 0x18, mf2_flags); + break; + case 0xba: /* Caps Lock release */ + mf2_flags &= ~0x40; + write_byte(0x0040, 0x18, mf2_flags); + break; + + case 0x2a: /* L Shift press */ + shift_flags |= 0x02; + write_byte(0x0040, 0x17, shift_flags); + break; + case 0xaa: /* L Shift release */ + shift_flags &= ~0x02; + write_byte(0x0040, 0x17, shift_flags); + break; + + case 0x36: /* R Shift press */ + shift_flags |= 0x01; + write_byte(0x0040, 0x17, shift_flags); + break; + case 0xb6: /* R Shift release */ + shift_flags &= ~0x01; + write_byte(0x0040, 0x17, shift_flags); + break; + + case 0x1d: /* Ctrl press */ + if ((mf2_state & 0x01) == 0) { + shift_flags |= 0x04; + write_byte(0x0040, 0x17, shift_flags); + if (mf2_state & 0x02) { + mf2_state |= 0x04; + write_byte(0x0040, 0x96, mf2_state); + } else { + mf2_flags |= 0x01; + write_byte(0x0040, 0x18, mf2_flags); + } + } + break; + case 0x9d: /* Ctrl release */ + if ((mf2_state & 0x01) == 0) { + shift_flags &= ~0x04; + write_byte(0x0040, 0x17, shift_flags); + if (mf2_state & 0x02) { + mf2_state &= ~0x04; + write_byte(0x0040, 0x96, mf2_state); + } else { + mf2_flags &= ~0x01; + write_byte(0x0040, 0x18, mf2_flags); + } + } + break; + + case 0x38: /* Alt press */ + shift_flags |= 0x08; + write_byte(0x0040, 0x17, shift_flags); + if (mf2_state & 0x02) { + mf2_state |= 0x08; + write_byte(0x0040, 0x96, mf2_state); + } else { + mf2_flags |= 0x02; + write_byte(0x0040, 0x18, mf2_flags); + } + break; + case 0xb8: /* Alt release */ + shift_flags &= ~0x08; + write_byte(0x0040, 0x17, shift_flags); + if (mf2_state & 0x02) { + mf2_state &= ~0x08; + write_byte(0x0040, 0x96, mf2_state); + } else { + mf2_flags &= ~0x02; + write_byte(0x0040, 0x18, mf2_flags); + } + break; + + case 0x45: /* Num Lock press */ + if ((mf2_state & 0x03) == 0) { + mf2_flags |= 0x20; + write_byte(0x0040, 0x18, mf2_flags); + shift_flags ^= 0x20; + write_byte(0x0040, 0x17, shift_flags); + } + break; + case 0xc5: /* Num Lock release */ + if ((mf2_state & 0x03) == 0) { + mf2_flags &= ~0x20; + write_byte(0x0040, 0x18, mf2_flags); + } + break; + + case 0x46: /* Scroll Lock press */ + mf2_flags |= 0x10; + write_byte(0x0040, 0x18, mf2_flags); + shift_flags ^= 0x10; + write_byte(0x0040, 0x17, shift_flags); + break; + + case 0xc6: /* Scroll Lock release */ + mf2_flags &= ~0x10; + write_byte(0x0040, 0x18, mf2_flags); + break; + + default: + if (scancode & 0x80) { + break; /* toss key releases ... */ + } + if (scancode > MAX_SCAN_CODE) { + BX_INFO("KBD: int09h_handler(): unknown scancode read: 0x%02x!\n", scancode); + return; + } + if (shift_flags & 0x08) { /* ALT */ + asciicode = scan_to_scanascii[scancode].alt; + scancode = scan_to_scanascii[scancode].alt >> 8; + } else if (shift_flags & 0x04) { /* CONTROL */ + asciicode = scan_to_scanascii[scancode].control; + scancode = scan_to_scanascii[scancode].control >> 8; + } else if (((mf2_state & 0x02) > 0) && ((scancode >= 0x47) && (scancode <= 0x53))) { + /* extended keys handling */ + asciicode = 0xe0; + scancode = scan_to_scanascii[scancode].normal >> 8; + } else if (shift_flags & 0x03) { /* LSHIFT + RSHIFT */ + /* check if lock state should be ignored + * because a SHIFT key are pressed */ + + if (shift_flags & scan_to_scanascii[scancode].lock_flags) { + asciicode = scan_to_scanascii[scancode].normal; + scancode = scan_to_scanascii[scancode].normal >> 8; + } else { + asciicode = scan_to_scanascii[scancode].shift; + scancode = scan_to_scanascii[scancode].shift >> 8; + } + } else { + /* check if lock is on */ + if (shift_flags & scan_to_scanascii[scancode].lock_flags) { + asciicode = scan_to_scanascii[scancode].shift; + scancode = scan_to_scanascii[scancode].shift >> 8; + } else { + asciicode = scan_to_scanascii[scancode].normal; + scancode = scan_to_scanascii[scancode].normal >> 8; + } + } + if (scancode==0 && asciicode==0) { + BX_INFO("KBD: int09h_handler(): scancode & asciicode are zero?\n"); + } + enqueue_key(scancode, asciicode); + break; + } + if ((scancode & 0x7f) != 0x1d) { + mf2_state &= ~0x01; + } + mf2_state &= ~0x02; + write_byte(0x0040, 0x96, mf2_state); +} + + unsigned int +enqueue_key(scan_code, ascii_code) + Bit8u scan_code, ascii_code; +{ + Bit16u buffer_start, buffer_end, buffer_head, buffer_tail, temp_tail; + + buffer_start = read_word(0x0040, 0x0080); + buffer_end = read_word(0x0040, 0x0082); + + buffer_head = read_word(0x0040, 0x001A); + buffer_tail = read_word(0x0040, 0x001C); + + temp_tail = buffer_tail; + buffer_tail += 2; + if (buffer_tail >= buffer_end) + buffer_tail = buffer_start; + + if (buffer_tail == buffer_head) { + return(0); + } + + write_byte(0x0040, temp_tail, ascii_code); + write_byte(0x0040, temp_tail+1, scan_code); + write_word(0x0040, 0x001C, buffer_tail); + return(1); +} + + void +int74_function(make_farcall, Z, Y, X, status) + Bit16u make_farcall, Z, Y, X, status; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u in_byte, index, package_count; + Bit8u mouse_flags_1, mouse_flags_2; + +BX_DEBUG_INT74("entering int74_function\n"); + make_farcall = 0; + + in_byte = inb(PORT_PS2_STATUS); + if ((in_byte & 0x21) != 0x21) { + return; + } + + in_byte = inb(PORT_PS2_DATA); +BX_DEBUG_INT74("int74: read byte %02x\n", in_byte); + + mouse_flags_1 = read_byte(ebda_seg, &EbdaData->mouse_flag1); + mouse_flags_2 = read_byte(ebda_seg, &EbdaData->mouse_flag2); + + if ((mouse_flags_2 & 0x80) != 0x80) { + return; + } + + package_count = mouse_flags_2 & 0x07; + index = mouse_flags_1 & 0x07; + write_byte(ebda_seg, &EbdaData->mouse_data[index], in_byte); + + if ( (index+1) >= package_count ) { +BX_DEBUG_INT74("int74_function: make_farcall=1\n"); + status = read_byte(ebda_seg, &EbdaData->mouse_data[0]); + X = read_byte(ebda_seg, &EbdaData->mouse_data[1]); + Y = read_byte(ebda_seg, &EbdaData->mouse_data[2]); + Z = 0; + mouse_flags_1 = 0; + // check if far call handler installed + if (mouse_flags_2 & 0x80) + make_farcall = 1; + } + else { + mouse_flags_1++; + } + write_byte(ebda_seg, &EbdaData->mouse_flag1, mouse_flags_1); +} + +#define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status) + +#if BX_USE_ATADRV + + int +int13_edd(DS, SI, device) + Bit16u DS, SI; + Bit8u device; +{ + Bit32u lba_low, lba_high; + Bit16u npc, nph, npspt, size, t13; + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type); + + size=read_word(DS,SI+(Bit16u)&Int13DPT->size); + t13 = size == 74; + + // Buffer is too small + if(size < 26) + return 1; + + // EDD 1.x + if(size >= 26) { + Bit16u blksize, infos; + + write_word(DS, SI+(Bit16u)&Int13DPT->size, 26); + + blksize = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize); + + if (type == ATA_TYPE_ATA) + { + npc = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.cylinders); + nph = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads); + npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt); + lba_low = read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_low); + lba_high = read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high); + + if (lba_high || (lba_low/npspt)/nph > 0x3fff) + { + infos = 0 << 1; // geometry is invalid + npc = 0x3fff; + } + else + { + infos = 1 << 1; // geometry is valid + } + } + + if (type == ATA_TYPE_ATAPI) + { + npc = 0xffffffff; + nph = 0xffffffff; + npspt = 0xffffffff; + lba_low = 0xffffffff; + lba_high = 0xffffffff; + + infos = 1 << 2 /* removable */ | 1 << 4 /* media change */ | + 1 << 5 /* lockable */ | 1 << 6; /* max values */ + } + + write_word(DS, SI+(Bit16u)&Int13DPT->infos, infos); + write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc); + write_dword(DS, SI+(Bit16u)&Int13DPT->heads, (Bit32u)nph); + write_dword(DS, SI+(Bit16u)&Int13DPT->spt, (Bit32u)npspt); + write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba_low); + write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count2, lba_high); + write_word(DS, SI+(Bit16u)&Int13DPT->blksize, blksize); + } + + // EDD 2.x + if(size >= 30) { + Bit8u channel, dev, irq, mode, checksum, i, translation; + Bit16u iobase1, iobase2, options; + + write_word(DS, SI+(Bit16u)&Int13DPT->size, 30); + + write_word(DS, SI+(Bit16u)&Int13DPT->dpte_segment, ebda_seg); + write_word(DS, SI+(Bit16u)&Int13DPT->dpte_offset, &EbdaData->ata.dpte); + + // Fill in dpte + channel = device / 2; + iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); + iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); + irq = read_byte(ebda_seg, &EbdaData->ata.channels[channel].irq); + mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode); + translation = read_byte(ebda_seg, &EbdaData->ata.devices[device].translation); + + options = (1<<4); // lba translation + options |= (mode==ATA_MODE_PIO32?1:0)<<7; + + if (type == ATA_TYPE_ATA) + { + options |= (translation==ATA_TRANSLATION_NONE?0:1)<<3; // chs translation + options |= (translation==ATA_TRANSLATION_LBA?1:0)<<9; + options |= (translation==ATA_TRANSLATION_RECHS?3:0)<<9; + } + + if (type == ATA_TYPE_ATAPI) + { + options |= (1<<5); // removable device + options |= (1<<6); // atapi device + } + + write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1); + write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2 + ATA_CB_DC); + write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | (device % 2))<<4 ); + write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb ); + write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq ); + write_byte(ebda_seg, &EbdaData->ata.dpte.blkcount, 1 ); + write_byte(ebda_seg, &EbdaData->ata.dpte.dma, 0 ); + write_byte(ebda_seg, &EbdaData->ata.dpte.pio, 0 ); + write_word(ebda_seg, &EbdaData->ata.dpte.options, options); + write_word(ebda_seg, &EbdaData->ata.dpte.reserved, 0); + write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11); + + checksum=0; + for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, ((Bit8u*)(&EbdaData->ata.dpte)) + i); + checksum = -checksum; + write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum); + } + + // EDD 3.x + if(size >= 66) { + Bit8u channel, iface, checksum, i; + Bit16u iobase1; + + channel = device / 2; + iface = read_byte(ebda_seg, &EbdaData->ata.channels[channel].iface); + iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); + + write_word(DS, SI+(Bit16u)&Int13DPT->dpi.t13.key, 0xbedd); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.dpi_length, t13 ? 44 : 36); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.reserved1, 0); + write_word(DS, SI+(Bit16u)&Int13DPT->dpi.t13.reserved2, 0); + + if (iface==ATA_IFACE_ISA) { + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.host_bus[0], 'I'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.host_bus[1], 'S'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.host_bus[2], 'A'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.host_bus[3], ' '); + } + else { + // FIXME PCI + } + + if (type == ATA_TYPE_ATA) { + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[0], 'A'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[1], 'T'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[2], 'A'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[3], ' '); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[4], ' '); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[5], ' '); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[6], ' '); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[7], ' '); + } else if (type == ATA_TYPE_ATAPI) { + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[0], 'A'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[1], 'T'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[2], 'A'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[3], 'P'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[4], 'I'); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[5], ' '); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[6], ' '); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_type[7], ' '); + } + + if (iface==ATA_IFACE_ISA) { + write_word(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_path[0], iobase1); + write_word(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_path[2], 0); + write_dword(DS, SI+(Bit16u)&Int13DPT->dpi.t13.iface_path[4], 0L); + } + else { + // FIXME PCI + } + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.device_path[0], device%2); + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.device_path[1], 0); + write_word(DS, SI+(Bit16u)&Int13DPT->dpi.t13.device_path[2], 0); + write_dword(DS, SI+(Bit16u)&Int13DPT->dpi.t13.device_path[4], 0L); + if (t13) { + write_dword(DS, SI+(Bit16u)&Int13DPT->dpi.t13.device_path[8], 0L); + write_dword(DS, SI+(Bit16u)&Int13DPT->dpi.t13.device_path[12], 0L); + } + + if (t13) + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.reserved3, 0); + else + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.phoenix.reserved3, 0); + + checksum = 0; + for (i = 30; i < (t13 ? 73 : 65); i++) checksum += read_byte(DS, SI + i); + checksum = -checksum; + if (t13) + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.t13.checksum, checksum); + else + write_byte(DS, SI+(Bit16u)&Int13DPT->dpi.phoenix.checksum, checksum); + } + + return 0; +} + + void +int13_harddisk(EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS) + Bit16u EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS; +{ + Bit32u lba_low, lba_high; + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit16u cylinder, head, sector; + Bit16u segment, offset; + Bit16u npc, nph, npspt, nlc, nlh, nlspt; + Bit16u size, count; + Bit8u device, status; + + BX_DEBUG_INT13_HD("int13_harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES); + + write_byte(0x0040, 0x008e, 0); // clear completion flag + + // basic check : device has to be defined + if ( (GET_ELDL() < 0x80) || (GET_ELDL() >= 0x80 + BX_MAX_ATA_DEVICES) ) { + BX_INFO("int13_harddisk: function %02x, ELDL out of range %02x\n", GET_AH(), GET_ELDL()); + goto int13_fail; + } + + // Get the ata channel + device=read_byte(ebda_seg,&EbdaData->ata.hdidmap[GET_ELDL()-0x80]); + + // basic check : device has to be valid + if (device >= BX_MAX_ATA_DEVICES) { + BX_INFO("int13_harddisk: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_ELDL()); + goto int13_fail; + } + + switch (GET_AH()) { + + case 0x00: /* disk controller reset */ + ata_reset (device); + goto int13_success; + break; + + case 0x01: /* read disk status */ + status = read_byte(0x0040, 0x0074); + SET_AH(status); + SET_DISK_RET_STATUS(0); + /* set CF if error status read */ + if (status) goto int13_fail_nostatus; + else goto int13_success_noah; + break; + + case 0x02: // read disk sectors + case 0x03: // write disk sectors + case 0x04: // verify disk sectors + + count = GET_AL(); + cylinder = GET_CH(); + cylinder |= ( ((Bit16u) GET_CL()) << 2) & 0x300; + sector = (GET_CL() & 0x3f); + head = GET_DH(); + + segment = ES; + offset = BX; + + if ((count > 128) || (count == 0) || (sector == 0)) { + BX_INFO("int13_harddisk: function %02x, parameter out of range!\n",GET_AH()); + goto int13_fail; + } + + nlc = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders); + nlh = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads); + nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt); + + // sanity check on cyl heads, sec + if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt) ) { + BX_INFO("int13_harddisk: function %02x, parameters out of range %04x/%04x/%04x!\n", GET_AH(), cylinder, head, sector); + goto int13_fail; + } + + // FIXME verify + if (GET_AH() == 0x04) goto int13_success; + + nph = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads); + npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt); + + // if needed, translate lchs to lba, and execute command + if ( (nph != nlh) || (npspt != nlspt)) { + lba_low = ((((Bit32u)cylinder * (Bit32u)nlh) + (Bit32u)head) * (Bit32u)nlspt) + (Bit32u)sector - 1; + lba_high = 0; + sector = 0; // this forces the command to be lba + } + + if (GET_AH() == 0x02) + status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset); + else + status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset); + + // Set nb of sector transferred + SET_AL(read_word(ebda_seg, &EbdaData->ata.trsfsectors)); + + if (status != 0) { + BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status); + SET_AH(0x0c); + goto int13_fail_noah; + } + + goto int13_success; + break; + + case 0x05: /* format disk track */ + BX_INFO("format disk track called\n"); + goto int13_success; + return; + break; + + case 0x08: /* read disk drive parameters */ + + // Get logical geometry from table + nlc = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders); + nlh = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads); + nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt); + count = read_byte(ebda_seg, &EbdaData->ata.hdcount); + + nlc = nlc - 1; /* 0 based */ + SET_AL(0); + SET_CH(nlc & 0xff); + SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f)); + SET_DH(nlh - 1); + SET_DL(count); /* FIXME returns 0, 1, or n hard drives */ + + // FIXME should set ES & DI + + goto int13_success; + break; + + case 0x10: /* check drive ready */ + // should look at 40:8E also??? + + // Read the status from controller + status = inb(read_word(ebda_seg, &EbdaData->ata.channels[device/2].iobase1) + ATA_CB_STAT); + if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY)) == ATA_CB_STAT_RDY ) { + goto int13_success; + } + else { + SET_AH(0xAA); + goto int13_fail_noah; + } + break; + + case 0x15: /* read disk drive size */ + + // Get logical geometry from table + nlc = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders); + nlh = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads); + nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt); + + // Compute sector count seen by int13 + lba_low = (Bit32u)(nlc - 1) * (Bit32u)nlh * (Bit32u)nlspt; + CX = lba_low >> 16; + DX = lba_low & 0xffff; + + SET_AH(3); // hard disk accessible + goto int13_success_noah; + break; + + case 0x41: // IBM/MS installation check + BX=0xaa55; // install check + SET_AH(0x30); // EDD 3.0 + CX=0x0007; // ext disk access and edd, removable supported + goto int13_success_noah; + break; + + case 0x42: // IBM/MS extended read + case 0x43: // IBM/MS extended write + case 0x44: // IBM/MS verify + case 0x47: // IBM/MS extended seek + + count=read_word(DS, SI+(Bit16u)&Int13Ext->count); + segment=read_word(DS, SI+(Bit16u)&Int13Ext->segment); + offset=read_word(DS, SI+(Bit16u)&Int13Ext->offset); + + // Get 32 msb lba and check + lba_high=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2); + if (lba_high > read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high) ) { + BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH()); + goto int13_fail; + } + + // Get 32 lsb lba and check + lba_low=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1); + if (lba_high == read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high) + && lba_low >= read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_low) ) { + BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH()); + goto int13_fail; + } + + // If verify or seek + if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 )) + goto int13_success; + + // Execute the command + if (GET_AH() == 0x42) + status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset); + else + status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset); + + count=read_word(ebda_seg, &EbdaData->ata.trsfsectors); + write_word(DS, SI+(Bit16u)&Int13Ext->count, count); + + if (status != 0) { + BX_INFO("int13_harddisk: function %02x, error %02x !\n",GET_AH(),status); + SET_AH(0x0c); + goto int13_fail_noah; + } + + goto int13_success; + break; + + case 0x45: // IBM/MS lock/unlock drive + case 0x49: // IBM/MS extended media change + goto int13_success; // Always success for HD + break; + + case 0x46: // IBM/MS eject media + SET_AH(0xb2); // Volume Not Removable + goto int13_fail_noah; // Always fail for HD + break; + + case 0x48: // IBM/MS get drive parameters + if (int13_edd(DS, SI, device)) + goto int13_fail; + + goto int13_success; + break; + + case 0x4e: // // IBM/MS set hardware configuration + // DMA, prefetch, PIO maximum not supported + switch (GET_AL()) { + case 0x01: + case 0x03: + case 0x04: + case 0x06: + goto int13_success; + break; + default: + goto int13_fail; + } + break; + + case 0x09: /* initialize drive parameters */ + case 0x0c: /* seek to specified cylinder */ + case 0x0d: /* alternate disk reset */ + case 0x11: /* recalibrate */ + case 0x14: /* controller internal diagnostic */ + BX_INFO("int13_harddisk: function %02xh unimplemented, returns success\n", GET_AH()); + goto int13_success; + break; + + case 0x0a: /* read disk sectors with ECC */ + case 0x0b: /* write disk sectors with ECC */ + case 0x18: // set media type for format + case 0x50: // IBM/MS send packet command + default: + BX_INFO("int13_harddisk: function %02xh unsupported, returns fail\n", GET_AH()); + goto int13_fail; + break; + } + +int13_fail: + SET_AH(0x01); // defaults to invalid function in AH or invalid parameter +int13_fail_noah: + SET_DISK_RET_STATUS(GET_AH()); +int13_fail_nostatus: + SET_CF(); // error occurred + return; + +int13_success: + SET_AH(0x00); // no error +int13_success_noah: + SET_DISK_RET_STATUS(0x00); + CLEAR_CF(); // no error +} + +// --------------------------------------------------------------------------- +// Start of int13 for cdrom +// --------------------------------------------------------------------------- + + void +int13_cdrom(EHBX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS) + Bit16u EHBX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u device, status, locks; + Bit8u atacmd[12]; + Bit32u lba; + Bit16u count, segment, offset, i, size; + + BX_DEBUG_INT13_CD("int13_cdrom: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES); + + SET_DISK_RET_STATUS(0x00); + + /* basic check : device should be 0xE0+ */ + if( (GET_ELDL() < 0xE0) || (GET_ELDL() >= 0xE0+BX_MAX_ATA_DEVICES) ) { + BX_INFO("int13_cdrom: function %02x, ELDL out of range %02x\n", GET_AH(), GET_ELDL()); + goto int13_fail; + } + + // Get the ata channel + device=read_byte(ebda_seg,&EbdaData->ata.cdidmap[GET_ELDL()-0xE0]); + + /* basic check : device has to be valid */ + if (device >= BX_MAX_ATA_DEVICES) { + BX_INFO("int13_cdrom: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_ELDL()); + goto int13_fail; + } + + switch (GET_AH()) { + + // all those functions return SUCCESS + case 0x00: /* disk controller reset */ + case 0x09: /* initialize drive parameters */ + case 0x0c: /* seek to specified cylinder */ + case 0x0d: /* alternate disk reset */ + case 0x10: /* check drive ready */ + case 0x11: /* recalibrate */ + case 0x14: /* controller internal diagnostic */ + case 0x16: /* detect disk change */ + goto int13_success; + break; + + // all those functions return disk write-protected + case 0x03: /* write disk sectors */ + case 0x05: /* format disk track */ + case 0x43: // IBM/MS extended write + SET_AH(0x03); + goto int13_fail_noah; + break; + + case 0x01: /* read disk status */ + status = read_byte(0x0040, 0x0074); + SET_AH(status); + SET_DISK_RET_STATUS(0); + + /* set CF if error status read */ + if (status) goto int13_fail_nostatus; + else goto int13_success_noah; + break; + + case 0x15: /* read disk drive size */ + SET_AH(0x02); + goto int13_fail_noah; + break; + + case 0x41: // IBM/MS installation check + BX=0xaa55; // install check + SET_AH(0x30); // EDD 2.1 + CX=0x0007; // ext disk access, removable and edd + goto int13_success_noah; + break; + + case 0x42: // IBM/MS extended read + case 0x44: // IBM/MS verify sectors + case 0x47: // IBM/MS extended seek + + count=read_word(DS, SI+(Bit16u)&Int13Ext->count); + segment=read_word(DS, SI+(Bit16u)&Int13Ext->segment); + offset=read_word(DS, SI+(Bit16u)&Int13Ext->offset); + + // Can't use 64 bits lba + lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2); + if (lba != 0L) { + BX_PANIC("int13_cdrom: function %02x. Can't use 64bits lba\n",GET_AH()); + goto int13_fail; + } + + // Get 32 bits lba + lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1); + + // If verify or seek + if ((GET_AH() == 0x44) || (GET_AH() == 0x47)) + goto int13_success; + + memsetb(get_SS(),atacmd,0,12); + atacmd[0]=0x28; // READ command + atacmd[7]=(count & 0xff00) >> 8; // Sectors + atacmd[8]=(count & 0x00ff); // Sectors + atacmd[2]=(lba & 0xff000000) >> 24; // LBA + atacmd[3]=(lba & 0x00ff0000) >> 16; + atacmd[4]=(lba & 0x0000ff00) >> 8; + atacmd[5]=(lba & 0x000000ff); + status = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, count*2048L, ATA_DATA_IN, segment,offset); + + count = (Bit16u)(read_dword(ebda_seg, &EbdaData->ata.trsfbytes) >> 11); + write_word(DS, SI+(Bit16u)&Int13Ext->count, count); + + if (status != 0) { + BX_INFO("int13_cdrom: function %02x, status %02x !\n",GET_AH(),status); + SET_AH(0x0c); + goto int13_fail_noah; + } + + goto int13_success; + break; + + case 0x45: // IBM/MS lock/unlock drive + if (GET_AL() > 2) goto int13_fail; + + locks = read_byte(ebda_seg, &EbdaData->ata.devices[device].lock); + + switch (GET_AL()) { + case 0 : // lock + if (locks == 0xff) { + SET_AH(0xb4); + SET_AL(1); + goto int13_fail_noah; + } + write_byte(ebda_seg, &EbdaData->ata.devices[device].lock, ++locks); + SET_AL(1); + break; + case 1 : // unlock + if (locks == 0x00) { + SET_AH(0xb0); + SET_AL(0); + goto int13_fail_noah; + } + write_byte(ebda_seg, &EbdaData->ata.devices[device].lock, --locks); + SET_AL(locks==0?0:1); + break; + case 2 : // status + SET_AL(locks==0?0:1); + break; + } + + goto int13_success; + break; + + case 0x46: // IBM/MS eject media + locks = read_byte(ebda_seg, &EbdaData->ata.devices[device].lock); + + if (locks != 0) { + SET_AH(0xb1); // media locked + goto int13_fail_noah; + } + // FIXME should handle 0x31 no media in device + // FIXME should handle 0xb5 valid request failed + + // Call removable media eject + ASM_START + push bp + mov bp, sp + + mov ah, #0x52 + int #0x15 + mov _int13_cdrom.status + 2[bp], ah + jnc int13_cdrom_rme_end + mov _int13_cdrom.status, #1 +int13_cdrom_rme_end: + pop bp + ASM_END + + if (status != 0) { + SET_AH(0xb1); // media locked + goto int13_fail_noah; + } + + goto int13_success; + break; + + case 0x48: // IBM/MS get drive parameters + if (int13_edd(DS, SI, device)) + goto int13_fail; + + goto int13_success; + break; + + case 0x49: // IBM/MS extended media change + // always send changed ?? + SET_AH(06); + goto int13_fail_nostatus; + break; + + case 0x4e: // // IBM/MS set hardware configuration + // DMA, prefetch, PIO maximum not supported + switch (GET_AL()) { + case 0x01: + case 0x03: + case 0x04: + case 0x06: + goto int13_success; + break; + default: + goto int13_fail; + } + break; + + // all those functions return unimplemented + case 0x02: /* read sectors */ + case 0x04: /* verify sectors */ + case 0x08: /* read disk drive parameters */ + case 0x0a: /* read disk sectors with ECC */ + case 0x0b: /* write disk sectors with ECC */ + case 0x18: /* set media type for format */ + case 0x50: // ? - send packet command + default: + BX_INFO("int13_cdrom: unsupported AH=%02x\n", GET_AH()); + goto int13_fail; + break; + } + +int13_fail: + SET_AH(0x01); // defaults to invalid function in AH or invalid parameter +int13_fail_noah: + SET_DISK_RET_STATUS(GET_AH()); +int13_fail_nostatus: + SET_CF(); // error occurred + return; + +int13_success: + SET_AH(0x00); // no error +int13_success_noah: + SET_DISK_RET_STATUS(0x00); + CLEAR_CF(); // no error +} + +// --------------------------------------------------------------------------- +// End of int13 for cdrom +// --------------------------------------------------------------------------- + +#if BX_ELTORITO_BOOT +// --------------------------------------------------------------------------- +// Start of int13 for eltorito functions +// --------------------------------------------------------------------------- + + void +int13_eltorito(DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS) + Bit16u DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + + BX_DEBUG_INT13_ET("int13_eltorito: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES); + // BX_DEBUG_INT13_ET("int13_eltorito: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), DS, ES, DI, SI); + + switch (GET_AH()) { + + // FIXME ElTorito Various. Should be implemented + case 0x4a: // ElTorito - Initiate disk emu + case 0x4c: // ElTorito - Initiate disk emu and boot + case 0x4d: // ElTorito - Return Boot catalog + BX_PANIC("Int13 eltorito call with AX=%04x. Please report\n",AX); + goto int13_fail; + break; + + case 0x4b: // ElTorito - Terminate disk emu + // FIXME ElTorito Hardcoded + write_byte(DS,SI+0x00,0x13); + write_byte(DS,SI+0x01,read_byte(ebda_seg,&EbdaData->cdemu.media)); + write_byte(DS,SI+0x02,read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)); + write_byte(DS,SI+0x03,read_byte(ebda_seg,&EbdaData->cdemu.controller_index)); + write_dword(DS,SI+0x04,read_dword(ebda_seg,&EbdaData->cdemu.ilba)); + write_word(DS,SI+0x08,read_word(ebda_seg,&EbdaData->cdemu.device_spec)); + write_word(DS,SI+0x0a,read_word(ebda_seg,&EbdaData->cdemu.buffer_segment)); + write_word(DS,SI+0x0c,read_word(ebda_seg,&EbdaData->cdemu.load_segment)); + write_word(DS,SI+0x0e,read_word(ebda_seg,&EbdaData->cdemu.sector_count)); + write_byte(DS,SI+0x10,read_byte(ebda_seg,&EbdaData->cdemu.vdevice.cylinders)); + write_byte(DS,SI+0x11,read_byte(ebda_seg,&EbdaData->cdemu.vdevice.spt)); + write_byte(DS,SI+0x12,read_byte(ebda_seg,&EbdaData->cdemu.vdevice.heads)); + + // If we have to terminate emulation + if(GET_AL() == 0x00) { + // FIXME ElTorito Various. Should be handled accordingly to spec + write_byte(ebda_seg,&EbdaData->cdemu.active, 0x00); // bye bye + } + + goto int13_success; + break; + + default: + BX_INFO("int13_eltorito: unsupported AH=%02x\n", GET_AH()); + goto int13_fail; + break; + } + +int13_fail: + SET_AH(0x01); // defaults to invalid function in AH or invalid parameter + SET_DISK_RET_STATUS(GET_AH()); + SET_CF(); // error occurred + return; + +int13_success: + SET_AH(0x00); // no error + SET_DISK_RET_STATUS(0x00); + CLEAR_CF(); // no error +} + +// --------------------------------------------------------------------------- +// End of int13 for eltorito functions +// --------------------------------------------------------------------------- + +// --------------------------------------------------------------------------- +// Start of int13 when emulating a device from the cd +// --------------------------------------------------------------------------- + + void +int13_cdemu(DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS) + Bit16u DS, ES, DI, SI, BP, SP, BX, DX, CX, AX, IP, CS, FLAGS; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit8u device, status; + Bit16u vheads, vspt, vcylinders; + Bit16u head, sector, cylinder, nbsectors; + Bit32u vlba, ilba, slba, elba; + Bit16u before, segment, offset; + Bit8u atacmd[12]; + + BX_DEBUG_INT13_ET("int13_cdemu: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES); + + /* at this point, we are emulating a floppy/harddisk */ + + // Recompute the device number + device = read_byte(ebda_seg,&EbdaData->cdemu.controller_index) * 2; + device += read_byte(ebda_seg,&EbdaData->cdemu.device_spec); + + SET_DISK_RET_STATUS(0x00); + + /* basic checks : emulation should be active, dl should equal the emulated drive */ + if( (read_byte(ebda_seg,&EbdaData->cdemu.active) ==0) || + (read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive ) != GET_DL())) { + BX_INFO("int13_cdemu: function %02x, emulation not active for DL= %02x\n", GET_AH(), GET_DL()); + goto int13_fail; + } + + switch (GET_AH()) { + + // all those functions return SUCCESS + case 0x00: /* disk controller reset */ + case 0x09: /* initialize drive parameters */ + case 0x0c: /* seek to specified cylinder */ + case 0x0d: /* alternate disk reset */ // FIXME ElTorito Various. should really reset ? + case 0x10: /* check drive ready */ // FIXME ElTorito Various. should check if ready ? + case 0x11: /* recalibrate */ + case 0x14: /* controller internal diagnostic */ + case 0x16: /* detect disk change */ + goto int13_success; + break; + + // all those functions return disk write-protected + case 0x03: /* write disk sectors */ + case 0x05: /* format disk track */ + SET_AH(0x03); + goto int13_fail_noah; + break; + + case 0x01: /* read disk status */ + status=read_byte(0x0040, 0x0074); + SET_AH(status); + SET_DISK_RET_STATUS(0); + + /* set CF if error status read */ + if (status) goto int13_fail_nostatus; + else goto int13_success_noah; + break; + + case 0x02: // read disk sectors + case 0x04: // verify disk sectors + vspt = read_word(ebda_seg,&EbdaData->cdemu.vdevice.spt); + vcylinders = read_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders); + vheads = read_word(ebda_seg,&EbdaData->cdemu.vdevice.heads); + + ilba = read_dword(ebda_seg,&EbdaData->cdemu.ilba); + + sector = GET_CL() & 0x003f; + cylinder = (GET_CL() & 0x00c0) << 2 | GET_CH(); + head = GET_DH(); + nbsectors = GET_AL(); + segment = ES; + offset = BX; + + // no sector to read ? + if(nbsectors==0) goto int13_success; + + // sanity checks sco openserver needs this! + if ((sector > vspt) + || (cylinder >= vcylinders) + || (head >= vheads)) { + goto int13_fail; + } + + // After controls, verify do nothing + if (GET_AH() == 0x04) goto int13_success; + + segment = ES+(BX / 16); + offset = BX % 16; + + // calculate the virtual lba inside the image + vlba=((((Bit32u)cylinder*(Bit32u)vheads)+(Bit32u)head)*(Bit32u)vspt)+((Bit32u)(sector-1)); + + // In advance so we don't loose the count + SET_AL(nbsectors); + + // start lba on cd + slba = (Bit32u)vlba/4; + before= (Bit16u)vlba%4; + + // end lba on cd + elba = (Bit32u)(vlba+nbsectors-1)/4; + + memsetb(get_SS(),atacmd,0,12); + atacmd[0]=0x28; // READ command + atacmd[7]=((Bit16u)(elba-slba+1) & 0xff00) >> 8; // Sectors + atacmd[8]=((Bit16u)(elba-slba+1) & 0x00ff); // Sectors + atacmd[2]=(ilba+slba & 0xff000000) >> 24; // LBA + atacmd[3]=(ilba+slba & 0x00ff0000) >> 16; + atacmd[4]=(ilba+slba & 0x0000ff00) >> 8; + atacmd[5]=(ilba+slba & 0x000000ff); + if((status = ata_cmd_packet(device, 12, get_SS(), atacmd, before*512, nbsectors*512L, ATA_DATA_IN, segment,offset)) != 0) { + BX_INFO("int13_cdemu: function %02x, error %02x !\n",GET_AH(),status); + SET_AH(0x02); + SET_AL(0); + goto int13_fail_noah; + } + + goto int13_success; + break; + + case 0x08: /* read disk drive parameters */ + vspt=read_word(ebda_seg,&EbdaData->cdemu.vdevice.spt); + vcylinders=read_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders) - 1; + vheads=read_word(ebda_seg,&EbdaData->cdemu.vdevice.heads) - 1; + + SET_AL(0x00); + SET_BL(0x00); + SET_CH(vcylinders & 0xff); + SET_CL(((vcylinders >> 2) & 0xc0) | (vspt & 0x3f)); + SET_DH(vheads); + SET_DL(0x02); // FIXME ElTorito Various. should send the real count of drives 1 or 2 + // FIXME ElTorito Harddisk. should send the HD count + + switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) { + case 0x01: SET_BL( 0x02 ); break; + case 0x02: SET_BL( 0x04 ); break; + case 0x03: SET_BL( 0x06 ); break; + } + +ASM_START + push bp + mov bp, sp + mov ax, #diskette_param_table2 + mov _int13_cdemu.DI+2[bp], ax + mov _int13_cdemu.ES+2[bp], cs + pop bp +ASM_END + goto int13_success; + break; + + case 0x15: /* read disk drive size */ + // FIXME ElTorito Harddisk. What geometry to send ? + SET_AH(0x03); + goto int13_success_noah; + break; + + // all those functions return unimplemented + case 0x0a: /* read disk sectors with ECC */ + case 0x0b: /* write disk sectors with ECC */ + case 0x18: /* set media type for format */ + case 0x41: // IBM/MS installation check + // FIXME ElTorito Harddisk. Darwin would like to use EDD + case 0x42: // IBM/MS extended read + case 0x43: // IBM/MS extended write + case 0x44: // IBM/MS verify sectors + case 0x45: // IBM/MS lock/unlock drive + case 0x46: // IBM/MS eject media + case 0x47: // IBM/MS extended seek + case 0x48: // IBM/MS get drive parameters + case 0x49: // IBM/MS extended media change + case 0x4e: // ? - set hardware configuration + case 0x50: // ? - send packet command + default: + BX_INFO("int13_cdemu function AH=%02x unsupported, returns fail\n", GET_AH()); + goto int13_fail; + break; + } + +int13_fail: + SET_AH(0x01); // defaults to invalid function in AH or invalid parameter +int13_fail_noah: + SET_DISK_RET_STATUS(GET_AH()); +int13_fail_nostatus: + SET_CF(); // error occurred + return; + +int13_success: + SET_AH(0x00); // no error +int13_success_noah: + SET_DISK_RET_STATUS(0x00); + CLEAR_CF(); // no error +} + +// --------------------------------------------------------------------------- +// End of int13 when emulating a device from the cd +// --------------------------------------------------------------------------- + +#endif // BX_ELTORITO_BOOT + +#else //BX_USE_ATADRV + + void +outLBA(cylinder,hd_heads,head,hd_sectors,sector,dl) + Bit16u cylinder; + Bit16u hd_heads; + Bit16u head; + Bit16u hd_sectors; + Bit16u sector; + Bit16u dl; +{ +ASM_START + push bp + mov bp, sp + push eax + push ebx + push edx + xor eax,eax + mov ax,4[bp] // cylinder + xor ebx,ebx + mov bl,6[bp] // hd_heads + imul ebx + + mov bl,8[bp] // head + add eax,ebx + mov bl,10[bp] // hd_sectors + imul ebx + mov bl,12[bp] // sector + add eax,ebx + + dec eax + mov dx,#0x1f3 + out dx,al + mov dx,#0x1f4 + mov al,ah + out dx,al + shr eax,#16 + mov dx,#0x1f5 + out dx,al + and ah,#0xf + mov bl,14[bp] // dl + and bl,#1 + shl bl,#4 + or ah,bl + or ah,#0xe0 + mov al,ah + mov dx,#0x01f6 + out dx,al + pop edx + pop ebx + pop eax + pop bp +ASM_END +} + + void +int13_harddisk(EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS) + Bit16u EHAX, DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS; +{ + Bit8u drive, num_sectors, sector, head, status, mod; + Bit8u drive_map; + Bit8u n_drives; + Bit16u cyl_mod, ax; + Bit16u max_cylinder, cylinder, total_sectors; + Bit16u hd_cylinders; + Bit8u hd_heads, hd_sectors; + Bit16u val16; + Bit8u sector_count; + unsigned int i; + Bit16u tempbx; + Bit16u dpsize; + + Bit16u count, segment, offset; + Bit32u lba; + Bit16u error; + + BX_DEBUG_INT13_HD("int13 harddisk: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES); + + write_byte(0x0040, 0x008e, 0); // clear completion flag + + /* at this point, DL is >= 0x80 to be passed from the floppy int13h + handler code */ + /* check how many disks first (cmos reg 0x12), return an error if + drive not present */ + drive_map = inb_cmos(0x12); + drive_map = (((drive_map & 0xf0)==0) ? 0 : 1) | + (((drive_map & 0x0f)==0) ? 0 : 2); + n_drives = (drive_map==0) ? 0 : ((drive_map==3) ? 2 : 1); + + if (!(drive_map & (1<<(GET_ELDL()&0x7f)))) { /* allow 0, 1, or 2 disks */ + SET_AH(0x01); + SET_DISK_RET_STATUS(0x01); + SET_CF(); /* error occurred */ + return; + } + + switch (GET_AH()) { + + case 0x00: /* disk controller reset */ +BX_DEBUG_INT13_HD("int13_f00\n"); + + SET_AH(0); + SET_DISK_RET_STATUS(0); + set_diskette_ret_status(0); + set_diskette_current_cyl(0, 0); /* current cylinder, diskette 1 */ + set_diskette_current_cyl(1, 0); /* current cylinder, diskette 2 */ + CLEAR_CF(); /* successful */ + return; + break; + + case 0x01: /* read disk status */ +BX_DEBUG_INT13_HD("int13_f01\n"); + status = read_byte(0x0040, 0x0074); + SET_AH(status); + SET_DISK_RET_STATUS(0); + /* set CF if error status read */ + if (status) SET_CF(); + else CLEAR_CF(); + return; + break; + + case 0x04: // verify disk sectors + case 0x02: // read disk sectors + drive = GET_ELDL(); + get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors); + + num_sectors = GET_AL(); + cylinder = (GET_CL() & 0x00c0) << 2 | GET_CH(); + sector = (GET_CL() & 0x3f); + head = GET_DH(); + + + if (hd_cylinders > 1024) { + if (hd_cylinders <= 2048) { + cylinder <<= 1; + } + else if (hd_cylinders <= 4096) { + cylinder <<= 2; + } + else if (hd_cylinders <= 8192) { + cylinder <<= 3; + } + else { // hd_cylinders <= 16384 + cylinder <<= 4; + } + + ax = head / hd_heads; + cyl_mod = ax & 0xff; + head = ax >> 8; + cylinder |= cyl_mod; + } + + if ( (cylinder >= hd_cylinders) || + (sector > hd_sectors) || + (head >= hd_heads) ) { + SET_AH(1); + SET_DISK_RET_STATUS(1); + SET_CF(); /* error occurred */ + return; + } + + if ( (num_sectors > 128) || (num_sectors == 0) ) + BX_PANIC("int13_harddisk: num_sectors out of range!\n"); + + if (head > 15) + BX_PANIC("hard drive BIOS:(read/verify) head > 15\n"); + + if ( GET_AH() == 0x04 ) { + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); + return; + } + + status = inb(PORT_ATA1_CMD_BASE + 7); + if (status & 0x80) { + BX_PANIC("hard drive BIOS:(read/verify) BUSY bit set\n"); + } + outb(PORT_ATA1_CMD_BASE + 2, num_sectors); + /* activate LBA? (tomv) */ + if (hd_heads > 16) { +BX_DEBUG_INT13_HD("CHS: %x %x %x\n", cylinder, head, sector); + outLBA(cylinder,hd_heads,head,hd_sectors,sector,drive); + } + else { + outb(PORT_ATA1_CMD_BASE + 3, sector); + outb(PORT_ATA1_CMD_BASE + 4, cylinder & 0x00ff); + outb(PORT_ATA1_CMD_BASE + 5, cylinder >> 8); + outb(PORT_ATA1_CMD_BASE + 6, 0xa0 | ((drive & 0x01)<<4) | (head & 0x0f)); + } + outb(PORT_ATA1_CMD_BASE + 7, 0x20); + + while (1) { + status = inb(PORT_ATA1_CMD_BASE + 7); + if (!(status & 0x80)) break; + } + + if (status & 0x01) { + BX_PANIC("hard drive BIOS:(read/verify) read error\n"); + } else if (!(status & 0x08)) { + BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status); + BX_PANIC("hard drive BIOS:(read/verify) expected DRQ=1\n"); + } + + sector_count = 0; + tempbx = BX; + +ASM_START + sti ;; enable higher priority interrupts +ASM_END + + while (1) { +ASM_START + ;; store temp bx in real DI register + push bp + mov bp, sp + mov di, _int13_harddisk.tempbx + 2 [bp] + pop bp + + ;; adjust if there will be an overrun + cmp di, #0xfe00 + jbe i13_f02_no_adjust +i13_f02_adjust: + sub di, #0x0200 ; sub 512 bytes from offset + mov ax, es + add ax, #0x0020 ; add 512 to segment + mov es, ax + +i13_f02_no_adjust: + mov cx, #0x0100 ;; counter (256 words = 512b) + mov dx, #0x01f0 ;; AT data read port + + rep + insw ;; CX words transferred from port(DX) to ES:[DI] + +i13_f02_done: + ;; store real DI register back to temp bx + push bp + mov bp, sp + mov _int13_harddisk.tempbx + 2 [bp], di + pop bp +ASM_END + + sector_count++; + num_sectors--; + if (num_sectors == 0) { + status = inb(PORT_ATA1_CMD_BASE + 7); + if ((status & 0xc9) != 0x40) + BX_PANIC("no sectors left to read/verify, status is %02x\n", (unsigned) status); + break; + } + else { + status = inb(PORT_ATA1_CMD_BASE + 7); + if ((status & 0xc9) != 0x48) + BX_PANIC("more sectors left to read/verify, status is %02x\n", (unsigned) status); + continue; + } + } + + SET_AH(0); + SET_DISK_RET_STATUS(0); + SET_AL(sector_count); + CLEAR_CF(); /* successful */ + return; + break; + + case 0x03: /* write disk sectors */ +BX_DEBUG_INT13_HD("int13_f03\n"); + drive = GET_ELDL (); + get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors); + + num_sectors = GET_AL(); + cylinder = GET_CH(); + cylinder |= ( ((Bit16u) GET_CL()) << 2) & 0x300; + sector = (GET_CL() & 0x3f); + head = GET_DH(); + + if (hd_cylinders > 1024) { + if (hd_cylinders <= 2048) { + cylinder <<= 1; + } + else if (hd_cylinders <= 4096) { + cylinder <<= 2; + } + else if (hd_cylinders <= 8192) { + cylinder <<= 3; + } + else { // hd_cylinders <= 16384 + cylinder <<= 4; + } + + ax = head / hd_heads; + cyl_mod = ax & 0xff; + head = ax >> 8; + cylinder |= cyl_mod; + } + + if ( (cylinder >= hd_cylinders) || + (sector > hd_sectors) || + (head >= hd_heads) ) { + SET_AH(1); + SET_DISK_RET_STATUS(1); + SET_CF(); /* error occurred */ + return; + } + + if ( (num_sectors > 128) || (num_sectors == 0) ) + BX_PANIC("int13_harddisk: num_sectors out of range!\n"); + + if (head > 15) + BX_PANIC("hard drive BIOS:(read) head > 15\n"); + + status = inb(PORT_ATA1_CMD_BASE + 7); + if (status & 0x80) { + BX_PANIC("hard drive BIOS:(read) BUSY bit set\n"); + } +// should check for Drive Ready Bit also in status reg + outb(PORT_ATA1_CMD_BASE + 2, num_sectors); + + /* activate LBA? (tomv) */ + if (hd_heads > 16) { +BX_DEBUG_INT13_HD("CHS (write): %x %x %x\n", cylinder, head, sector); + outLBA(cylinder,hd_heads,head,hd_sectors,sector,GET_ELDL()); + } + else { + outb(PORT_ATA1_CMD_BASE + 3, sector); + outb(PORT_ATA1_CMD_BASE + 4, cylinder & 0x00ff); + outb(PORT_ATA1_CMD_BASE + 5, cylinder >> 8); + outb(PORT_ATA1_CMD_BASE + 6, 0xa0 | ((GET_ELDL() & 0x01)<<4) | (head & 0x0f)); + } + outb(PORT_ATA1_CMD_BASE + 7, 0x30); + + // wait for busy bit to turn off after seeking + while (1) { + status = inb(PORT_ATA1_CMD_BASE + 7); + if (!(status & 0x80)) break; + } + + if (!(status & 0x08)) { + BX_DEBUG_INT13_HD("status was %02x\n", (unsigned) status); + BX_PANIC("hard drive BIOS:(write) data-request bit not set\n"); + } + + sector_count = 0; + tempbx = BX; + +ASM_START + sti ;; enable higher priority interrupts +ASM_END + + while (1) { +ASM_START + ;; store temp bx in real SI register + push bp + mov bp, sp + mov si, _int13_harddisk.tempbx + 2 [bp] + pop bp + + ;; adjust if there will be an overrun + cmp si, #0xfe00 + jbe i13_f03_no_adjust +i13_f03_adjust: + sub si, #0x0200 ; sub 512 bytes from offset + mov ax, es + add ax, #0x0020 ; add 512 to segment + mov es, ax + +i13_f03_no_adjust: + mov cx, #0x0100 ;; counter (256 words = 512b) + mov dx, #0x01f0 ;; AT data read port + + seg ES + rep + outsw ;; CX words tranferred from ES:[SI] to port(DX) + + ;; store real SI register back to temp bx + push bp + mov bp, sp + mov _int13_harddisk.tempbx + 2 [bp], si + pop bp +ASM_END + + sector_count++; + num_sectors--; + if (num_sectors == 0) { + status = inb(PORT_ATA1_CMD_BASE + 7); + if ((status & 0xe9) != 0x40) + BX_PANIC("no sectors left to write, status is %02x\n", (unsigned) status); + break; + } + else { + status = inb(PORT_ATA1_CMD_BASE + 7); + if ((status & 0xc9) != 0x48) + BX_PANIC("more sectors left to write, status is %02x\n", (unsigned) status); + continue; + } + } + + SET_AH(0); + SET_DISK_RET_STATUS(0); + SET_AL(sector_count); + CLEAR_CF(); /* successful */ + return; + break; + + case 0x05: /* format disk track */ +BX_DEBUG_INT13_HD("int13_f05\n"); + BX_PANIC("format disk track called\n"); + /* nop */ + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); /* successful */ + return; + break; + + case 0x08: /* read disk drive parameters */ +BX_DEBUG_INT13_HD("int13_f08\n"); + + drive = GET_ELDL (); + get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors); + + // translate CHS + // + if (hd_cylinders <= 1024) { + // hd_cylinders >>= 0; + // hd_heads <<= 0; + } + else if (hd_cylinders <= 2048) { + hd_cylinders >>= 1; + hd_heads <<= 1; + } + else if (hd_cylinders <= 4096) { + hd_cylinders >>= 2; + hd_heads <<= 2; + } + else if (hd_cylinders <= 8192) { + hd_cylinders >>= 3; + hd_heads <<= 3; + } + else { // hd_cylinders <= 16384 + hd_cylinders >>= 4; + hd_heads <<= 4; + } + + max_cylinder = hd_cylinders - 1; /* 0 based */ + SET_AL(0); + SET_CH(max_cylinder & 0xff); + SET_CL(((max_cylinder >> 2) & 0xc0) | (hd_sectors & 0x3f)); + SET_DH(hd_heads - 1); + SET_DL(n_drives); /* returns 0, 1, or 2 hard drives */ + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); /* successful */ + + return; + break; + + case 0x09: /* initialize drive parameters */ +BX_DEBUG_INT13_HD("int13_f09\n"); + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); /* successful */ + return; + break; + + case 0x0a: /* read disk sectors with ECC */ +BX_DEBUG_INT13_HD("int13_f0a\n"); + case 0x0b: /* write disk sectors with ECC */ +BX_DEBUG_INT13_HD("int13_f0b\n"); + BX_PANIC("int13h Functions 0Ah & 0Bh not implemented!\n"); + return; + break; + + case 0x0c: /* seek to specified cylinder */ +BX_DEBUG_INT13_HD("int13_f0c\n"); + BX_INFO("int13h function 0ch (seek) not implemented!\n"); + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); /* successful */ + return; + break; + + case 0x0d: /* alternate disk reset */ +BX_DEBUG_INT13_HD("int13_f0d\n"); + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); /* successful */ + return; + break; + + case 0x10: /* check drive ready */ +BX_DEBUG_INT13_HD("int13_f10\n"); + //SET_AH(0); + //SET_DISK_RET_STATUS(0); + //CLEAR_CF(); /* successful */ + //return; + //break; + + // should look at 40:8E also??? + status = inb(PORT_ATA1_CMD_BASE + 7); + if ((status & 0xc0) == 0x40) { + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); // drive ready + return; + } + else { + SET_AH(0xAA); + SET_DISK_RET_STATUS(0xAA); + SET_CF(); // not ready + return; + } + break; + + case 0x11: /* recalibrate */ +BX_DEBUG_INT13_HD("int13_f11\n"); + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); /* successful */ + return; + break; + + case 0x14: /* controller internal diagnostic */ +BX_DEBUG_INT13_HD("int13_f14\n"); + SET_AH(0); + SET_DISK_RET_STATUS(0); + CLEAR_CF(); /* successful */ + SET_AL(0); + return; + break; + + case 0x15: /* read disk drive size */ + drive = GET_ELDL(); + get_hd_geometry(drive, &hd_cylinders, &hd_heads, &hd_sectors); +ASM_START + push bp + mov bp, sp + mov al, _int13_harddisk.hd_heads + 2 [bp] + mov ah, _int13_harddisk.hd_sectors + 2 [bp] + mul al, ah ;; ax = heads * sectors + mov bx, _int13_harddisk.hd_cylinders + 2 [bp] + dec bx ;; use (cylinders - 1) ??? + mul ax, bx ;; dx:ax = (cylinders -1) * (heads * sectors) + ;; now we need to move the 32bit result dx:ax to what the + ;; BIOS wants which is cx:dx. + ;; and then into CX:DX on the stack + mov _int13_harddisk.CX + 2 [bp], dx + mov _int13_harddisk.DX + 2 [bp], ax + pop bp +ASM_END + SET_AH(3); // hard disk accessible + SET_DISK_RET_STATUS(0); // ??? should this be 0 + CLEAR_CF(); // successful + return; + break; + + case 0x18: // set media type for format + case 0x41: // IBM/MS + case 0x42: // IBM/MS + case 0x43: // IBM/MS + case 0x44: // IBM/MS + case 0x45: // IBM/MS lock/unlock drive + case 0x46: // IBM/MS eject media + case 0x47: // IBM/MS extended seek + case 0x49: // IBM/MS extended media change + case 0x50: // IBM/MS send packet command + default: + BX_INFO("int13_harddisk: unsupported AH=%02x\n", GET_AH()); + + SET_AH(1); // code=invalid function in AH or invalid parameter + SET_DISK_RET_STATUS(1); + SET_CF(); /* unsuccessful */ + return; + } +} + +static char panic_msg_reg12h[] = "HD%d cmos reg 12h not type F\n"; +static char panic_msg_reg19h[] = "HD%d cmos reg %02xh not user definable type 47\n"; + + void +get_hd_geometry(drive, hd_cylinders, hd_heads, hd_sectors) + Bit8u drive; + Bit16u *hd_cylinders; + Bit8u *hd_heads; + Bit8u *hd_sectors; +{ + Bit8u hd_type; + Bit16u ss; + Bit16u cylinders; + Bit8u iobase; + + ss = get_SS(); + if (drive == 0x80) { + hd_type = inb_cmos(0x12) & 0xf0; + if (hd_type != 0xf0) + BX_INFO(panic_msg_reg12h,0); + hd_type = inb_cmos(0x19); // HD0: extended type + if (hd_type != 47) + BX_INFO(panic_msg_reg19h,0,0x19); + iobase = 0x1b; + } else { + hd_type = inb_cmos(0x12) & 0x0f; + if (hd_type != 0x0f) + BX_INFO(panic_msg_reg12h,1); + hd_type = inb_cmos(0x1a); // HD1: extended type + if (hd_type != 47) + BX_INFO(panic_msg_reg19h,0,0x1a); + iobase = 0x24; + } + + // cylinders + cylinders = inb_cmos(iobase) | (inb_cmos(iobase+1) << 8); + write_word(ss, hd_cylinders, cylinders); + + // heads + write_byte(ss, hd_heads, inb_cmos(iobase+2)); + + // sectors per track + write_byte(ss, hd_sectors, inb_cmos(iobase+8)); +} + +#endif //else BX_USE_ATADRV + +#if BX_SUPPORT_FLOPPY + +////////////////////// +// FLOPPY functions // +////////////////////// + +void floppy_reset_controller() +{ + Bit8u val8; + + // Reset controller + val8 = inb(PORT_FD_DOR); + outb(PORT_FD_DOR, val8 & ~0x04); + outb(PORT_FD_DOR, val8 | 0x04); + + // Wait for controller to come out of reset + do { + val8 = inb(PORT_FD_STATUS); + } while ((val8 & 0xc0) != 0x80); +} + +void floppy_prepare_controller(drive) + Bit16u drive; +{ + Bit8u val8, dor, prev_reset; + + // set 40:3e bit 7 to 0 + val8 = read_byte(0x0040, 0x003e); + val8 &= 0x7f; + write_byte(0x0040, 0x003e, val8); + + // turn on motor of selected drive, DMA & int enabled, normal operation + prev_reset = inb(PORT_FD_DOR) & 0x04; + if (drive) + dor = 0x20; + else + dor = 0x10; + dor |= 0x0c; + dor |= drive; + outb(PORT_FD_DOR, dor); + + // reset the disk motor timeout value of INT 08 + write_byte(0x40,0x40, BX_FLOPPY_ON_CNT); + + // wait for drive readiness + do { + val8 = inb(PORT_FD_STATUS); + } while ( (val8 & 0xc0) != 0x80 ); + + if (prev_reset == 0) { + // turn on interrupts +ASM_START + sti +ASM_END + // wait on 40:3e bit 7 to become 1 + do { + val8 = read_byte(0x0040, 0x003e); + } while ( (val8 & 0x80) == 0 ); + val8 &= 0x7f; +ASM_START + cli +ASM_END + write_byte(0x0040, 0x003e, val8); + } +} + + bx_bool +floppy_media_known(drive) + Bit16u drive; +{ + Bit8u val8; + Bit16u media_state_offset; + + val8 = read_byte(0x0040, 0x003e); // diskette recal status + if (drive) + val8 >>= 1; + val8 &= 0x01; + if (val8 == 0) + return(0); + + media_state_offset = 0x0090; + if (drive) + media_state_offset += 1; + + val8 = read_byte(0x0040, media_state_offset); + val8 = (val8 >> 4) & 0x01; + if (val8 == 0) + return(0); + + // check pass, return KNOWN + return(1); +} + + bx_bool +floppy_media_sense(drive) + Bit16u drive; +{ + bx_bool retval; + Bit16u media_state_offset; + Bit8u drive_type, config_data, media_state; + + if (floppy_drive_recal(drive) == 0) { + return(0); + } + + // for now cheat and get drive type from CMOS, + // assume media is same as drive type + + // ** config_data ** + // Bitfields for diskette media control: + // Bit(s) Description (Table M0028) + // 7-6 last data rate set by controller + // 00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps + // 5-4 last diskette drive step rate selected + // 00=0Ch, 01=0Dh, 10=0Eh, 11=0Ah + // 3-2 {data rate at start of operation} + // 1-0 reserved + + // ** media_state ** + // Bitfields for diskette drive media state: + // Bit(s) Description (Table M0030) + // 7-6 data rate + // 00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps + // 5 double stepping required (e.g. 360kB in 1.2MB) + // 4 media type established + // 3 drive capable of supporting 4MB media + // 2-0 on exit from BIOS, contains + // 000 trying 360kB in 360kB + // 001 trying 360kB in 1.2MB + // 010 trying 1.2MB in 1.2MB + // 011 360kB in 360kB established + // 100 360kB in 1.2MB established + // 101 1.2MB in 1.2MB established + // 110 reserved + // 111 all other formats/drives + + drive_type = inb_cmos(0x10); + + if (drive == 0) + drive_type >>= 4; + else + drive_type &= 0x0f; + + if (drive_type == 1) { + // 360K 5.25" drive + config_data = 0x00; // 0000 0000 + media_state = 0x25; // 0010 0101 + retval = 1; + } + else if (drive_type == 2) { + // 1.2 MB 5.25" drive + config_data = 0x00; // 0000 0000 + media_state = 0x25; // 0010 0101 // need double stepping??? (bit 5) + retval = 1; + } + else if (drive_type == 3) { + // 720K 3.5" drive + config_data = 0x00; // 0000 0000 ??? + media_state = 0x17; // 0001 0111 + retval = 1; + } + else if (drive_type == 4) { + // 1.44 MB 3.5" drive + config_data = 0x00; // 0000 0000 + media_state = 0x17; // 0001 0111 + retval = 1; + } + else if (drive_type == 5) { + // 2.88 MB 3.5" drive + config_data = 0xCC; // 1100 1100 + media_state = 0xD7; // 1101 0111 + retval = 1; + } + // Extended floppy size uses special cmos setting + else if (drive_type == 6) { + // 160k 5.25" drive + config_data = 0x00; // 0000 0000 + media_state = 0x27; // 0010 0111 + retval = 1; + } + else if (drive_type == 7) { + // 180k 5.25" drive + config_data = 0x00; // 0000 0000 + media_state = 0x27; // 0010 0111 + retval = 1; + } + else if (drive_type == 8) { + // 320k 5.25" drive + config_data = 0x00; // 0000 0000 + media_state = 0x27; // 0010 0111 + retval = 1; + } + else { + // not recognized + config_data = 0x00; // 0000 0000 + media_state = 0x00; // 0000 0000 + retval = 0; + } + + if (drive == 0) + media_state_offset = 0x90; + else + media_state_offset = 0x91; + write_byte(0x0040, 0x008B, config_data); + write_byte(0x0040, media_state_offset, media_state); + + return(retval); +} + + bx_bool +floppy_drive_recal(drive) + Bit16u drive; +{ + Bit8u val8; + Bit16u curr_cyl_offset; + + floppy_prepare_controller(drive); + + // send Recalibrate command (2 bytes) to controller + outb(PORT_FD_DATA, 0x07); // 07: Recalibrate + outb(PORT_FD_DATA, drive); // 0=drive0, 1=drive1 + + // turn on interrupts +ASM_START + sti +ASM_END + + // wait on 40:3e bit 7 to become 1 + do { + val8 = (read_byte(0x0040, 0x003e) & 0x80); + } while ( val8 == 0 ); + + val8 = 0; // separate asm from while() loop + // turn off interrupts +ASM_START + cli +ASM_END + + // set 40:3e bit 7 to 0, and calibrated bit + val8 = read_byte(0x0040, 0x003e); + val8 &= 0x7f; + if (drive) { + val8 |= 0x02; // Drive 1 calibrated + curr_cyl_offset = 0x0095; + } else { + val8 |= 0x01; // Drive 0 calibrated + curr_cyl_offset = 0x0094; + } + write_byte(0x0040, 0x003e, val8); + write_byte(0x0040, curr_cyl_offset, 0); // current cylinder is 0 + + return(1); +} + + bx_bool +floppy_drive_exists(drive) + Bit16u drive; +{ + Bit8u drive_type; + + // check CMOS to see if drive exists + drive_type = inb_cmos(0x10); + if (drive == 0) + drive_type >>= 4; + else + drive_type &= 0x0f; + if ( drive_type == 0 ) + return(0); + else + return(1); +} + + void +int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS) + Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS; +{ + Bit8u drive, num_sectors, track, sector, head, status; + Bit16u base_address, base_count, base_es; + Bit8u page, mode_register, val8, dor; + Bit8u return_status[7]; + Bit8u drive_type, num_floppies, ah; + Bit16u es, last_addr; + + BX_DEBUG_INT13_FL("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES); + + ah = GET_AH(); + + switch ( ah ) { + case 0x00: // diskette controller reset +BX_DEBUG_INT13_FL("floppy f00\n"); + drive = GET_ELDL(); + if (drive > 1) { + SET_AH(1); // invalid param + set_diskette_ret_status(1); + SET_CF(); + return; + } + drive_type = inb_cmos(0x10); + + if (drive == 0) + drive_type >>= 4; + else + drive_type &= 0x0f; + if (drive_type == 0) { + SET_AH(0x80); // drive not responding + set_diskette_ret_status(0x80); + SET_CF(); + return; + } + SET_AH(0); + set_diskette_ret_status(0); + CLEAR_CF(); // successful + set_diskette_current_cyl(drive, 0); // current cylinder + return; + + case 0x01: // Read Diskette Status + CLEAR_CF(); + val8 = read_byte(0x0000, 0x0441); + SET_AH(val8); + if (val8) { + SET_CF(); + } + return; + + case 0x02: // Read Diskette Sectors + case 0x03: // Write Diskette Sectors + case 0x04: // Verify Diskette Sectors + num_sectors = GET_AL(); + track = GET_CH(); + sector = GET_CL(); + head = GET_DH(); + drive = GET_ELDL(); + + if ((drive > 1) || (head > 1) || (sector == 0) || + (num_sectors == 0) || (num_sectors > 72)) { + BX_INFO("int13_diskette: read/write/verify: parameter out of range\n"); + SET_AH(1); + set_diskette_ret_status(1); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + + // see if drive exists + if (floppy_drive_exists(drive) == 0) { + SET_AH(0x80); // not responding + set_diskette_ret_status(0x80); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + + // see if media in drive, and type is known + if (floppy_media_known(drive) == 0) { + if (floppy_media_sense(drive) == 0) { + SET_AH(0x0C); // Media type not found + set_diskette_ret_status(0x0C); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + } + + if (ah == 0x02) { + // Read Diskette Sectors + + //----------------------------------- + // set up DMA controller for transfer + //----------------------------------- + + // es:bx = pointer to where to place information from diskette + // port 04: DMA-1 base and current address, channel 2 + // port 05: DMA-1 base and current count, channel 2 + page = (ES >> 12); // upper 4 bits + base_es = (ES << 4); // lower 16bits contributed by ES + base_address = base_es + BX; // lower 16 bits of address + // contributed by ES:BX + if ( base_address < base_es ) { + // in case of carry, adjust page by 1 + page++; + } + base_count = (num_sectors * 512) - 1; + + // check for 64K boundary overrun + last_addr = base_address + base_count; + if (last_addr < base_address) { + SET_AH(0x09); + set_diskette_ret_status(0x09); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + + BX_DEBUG_INT13_FL("masking DMA-1 c2\n"); + outb(PORT_DMA1_MASK_REG, 0x06); + + BX_DEBUG_INT13_FL("clear flip-flop\n"); + outb(PORT_DMA1_CLEAR_FF_REG, 0x00); // clear flip-flop + outb(PORT_DMA_ADDR_2, base_address); + outb(PORT_DMA_ADDR_2, base_address>>8); + BX_DEBUG_INT13_FL("clear flip-flop\n"); + outb(PORT_DMA1_CLEAR_FF_REG, 0x00); // clear flip-flop + outb(PORT_DMA_CNT_2, base_count); + outb(PORT_DMA_CNT_2, base_count>>8); + + // port 0b: DMA-1 Mode Register + mode_register = 0x46; // single mode, increment, autoinit disable, + // transfer type=write, channel 2 + BX_DEBUG_INT13_FL("setting mode register\n"); + outb(PORT_DMA1_MODE_REG, mode_register); + + BX_DEBUG_INT13_FL("setting page register\n"); + // port 81: DMA-1 Page Register, channel 2 + outb(PORT_DMA_PAGE_2, page); + + BX_DEBUG_INT13_FL("unmask chan 2\n"); + outb(PORT_DMA1_MASK_REG, 0x02); // unmask channel 2 + + BX_DEBUG_INT13_FL("unmasking DMA-1 c2\n"); + outb(PORT_DMA1_MASK_REG, 0x02); + + //-------------------------------------- + // set up floppy controller for transfer + //-------------------------------------- + floppy_prepare_controller(drive); + + // send read-normal-data command (9 bytes) to controller + outb(PORT_FD_DATA, 0xe6); // e6: read normal data + outb(PORT_FD_DATA, (head << 2) | drive); // HD DR1 DR2 + outb(PORT_FD_DATA, track); + outb(PORT_FD_DATA, head); + outb(PORT_FD_DATA, sector); + outb(PORT_FD_DATA, 2); // 512 byte sector size + outb(PORT_FD_DATA, sector + num_sectors - 1); // last sector to read on track + outb(PORT_FD_DATA, 0); // Gap length + outb(PORT_FD_DATA, 0xff); // Gap length + + // turn on interrupts + ASM_START + sti + ASM_END + + // wait on 40:3e bit 7 to become 1 + do { + val8 = read_byte(0x0040, 0x0040); + if (val8 == 0) { + floppy_reset_controller(); + SET_AH(0x80); // drive not ready (timeout) + set_diskette_ret_status(0x80); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + val8 = (read_byte(0x0040, 0x003e) & 0x80); + } while ( val8 == 0 ); + + val8 = 0; // separate asm from while() loop + // turn off interrupts + ASM_START + cli + ASM_END + + // set 40:3e bit 7 to 0 + val8 = read_byte(0x0040, 0x003e); + val8 &= 0x7f; + write_byte(0x0040, 0x003e, val8); + + // check port 3f4 for accessibility to status bytes + val8 = inb(PORT_FD_STATUS); + if ( (val8 & 0xc0) != 0xc0 ) + BX_PANIC("int13_diskette: ctrl not ready\n"); + + // read 7 return status bytes from controller + // using loop index broken, have to unroll... + return_status[0] = inb(PORT_FD_DATA); + return_status[1] = inb(PORT_FD_DATA); + return_status[2] = inb(PORT_FD_DATA); + return_status[3] = inb(PORT_FD_DATA); + return_status[4] = inb(PORT_FD_DATA); + return_status[5] = inb(PORT_FD_DATA); + return_status[6] = inb(PORT_FD_DATA); + // record in BIOS Data Area + write_byte(0x0040, 0x0042, return_status[0]); + write_byte(0x0040, 0x0043, return_status[1]); + write_byte(0x0040, 0x0044, return_status[2]); + write_byte(0x0040, 0x0045, return_status[3]); + write_byte(0x0040, 0x0046, return_status[4]); + write_byte(0x0040, 0x0047, return_status[5]); + write_byte(0x0040, 0x0048, return_status[6]); + + if ( (return_status[0] & 0xc0) != 0 ) { + SET_AH(0x20); + set_diskette_ret_status(0x20); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + + // ??? should track be new val from return_status[3] ? + set_diskette_current_cyl(drive, track); + // AL = number of sectors read (same value as passed) + SET_AH(0x00); // success + CLEAR_CF(); // success + return; + } else if (ah == 0x03) { + // Write Diskette Sectors + + //----------------------------------- + // set up DMA controller for transfer + //----------------------------------- + + // es:bx = pointer to where to place information from diskette + // port 04: DMA-1 base and current address, channel 2 + // port 05: DMA-1 base and current count, channel 2 + page = (ES >> 12); // upper 4 bits + base_es = (ES << 4); // lower 16bits contributed by ES + base_address = base_es + BX; // lower 16 bits of address + // contributed by ES:BX + if ( base_address < base_es ) { + // in case of carry, adjust page by 1 + page++; + } + base_count = (num_sectors * 512) - 1; + + // check for 64K boundary overrun + last_addr = base_address + base_count; + if (last_addr < base_address) { + SET_AH(0x09); + set_diskette_ret_status(0x09); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + + BX_DEBUG_INT13_FL("masking DMA-1 c2\n"); + outb(PORT_DMA1_MASK_REG, 0x06); + + outb(PORT_DMA1_CLEAR_FF_REG, 0x00); // clear flip-flop + outb(PORT_DMA_ADDR_2, base_address); + outb(PORT_DMA_ADDR_2, base_address>>8); + outb(PORT_DMA1_CLEAR_FF_REG, 0x00); // clear flip-flop + outb(PORT_DMA_CNT_2, base_count); + outb(PORT_DMA_CNT_2, base_count>>8); + + // port 0b: DMA-1 Mode Register + mode_register = 0x4a; // single mode, increment, autoinit disable, + // transfer type=read, channel 2 + outb(PORT_DMA1_MODE_REG, mode_register); + + // port 81: DMA-1 Page Register, channel 2 + outb(PORT_DMA_PAGE_2, page); + + BX_DEBUG_INT13_FL("unmasking DMA-1 c2\n"); + outb(PORT_DMA1_MASK_REG, 0x02); + + //-------------------------------------- + // set up floppy controller for transfer + //-------------------------------------- + floppy_prepare_controller(drive); + + // send write-normal-data command (9 bytes) to controller + outb(PORT_FD_DATA, 0xc5); // c5: write normal data + outb(PORT_FD_DATA, (head << 2) | drive); // HD DR1 DR2 + outb(PORT_FD_DATA, track); + outb(PORT_FD_DATA, head); + outb(PORT_FD_DATA, sector); + outb(PORT_FD_DATA, 2); // 512 byte sector size + outb(PORT_FD_DATA, sector + num_sectors - 1); // last sector to write on track + outb(PORT_FD_DATA, 0); // Gap length + outb(PORT_FD_DATA, 0xff); // Gap length + + // turn on interrupts + ASM_START + sti + ASM_END + + // wait on 40:3e bit 7 to become 1 + do { + val8 = read_byte(0x0040, 0x0040); + if (val8 == 0) { + floppy_reset_controller(); + SET_AH(0x80); // drive not ready (timeout) + set_diskette_ret_status(0x80); + SET_AL(0); // no sectors written + SET_CF(); // error occurred + return; + } + val8 = (read_byte(0x0040, 0x003e) & 0x80); + } while ( val8 == 0 ); + + val8 = 0; // separate asm from while() loop + // turn off interrupts + ASM_START + cli + ASM_END + + // set 40:3e bit 7 to 0 + val8 = read_byte(0x0040, 0x003e); + val8 &= 0x7f; + write_byte(0x0040, 0x003e, val8); + + // check port 3f4 for accessibility to status bytes + val8 = inb(PORT_FD_STATUS); + if ( (val8 & 0xc0) != 0xc0 ) + BX_PANIC("int13_diskette: ctrl not ready\n"); + + // read 7 return status bytes from controller + // using loop index broken, have to unroll... + return_status[0] = inb(PORT_FD_DATA); + return_status[1] = inb(PORT_FD_DATA); + return_status[2] = inb(PORT_FD_DATA); + return_status[3] = inb(PORT_FD_DATA); + return_status[4] = inb(PORT_FD_DATA); + return_status[5] = inb(PORT_FD_DATA); + return_status[6] = inb(PORT_FD_DATA); + // record in BIOS Data Area + write_byte(0x0040, 0x0042, return_status[0]); + write_byte(0x0040, 0x0043, return_status[1]); + write_byte(0x0040, 0x0044, return_status[2]); + write_byte(0x0040, 0x0045, return_status[3]); + write_byte(0x0040, 0x0046, return_status[4]); + write_byte(0x0040, 0x0047, return_status[5]); + write_byte(0x0040, 0x0048, return_status[6]); + + if ( (return_status[0] & 0xc0) != 0 ) { + if ( (return_status[1] & 0x02) != 0 ) { + // diskette not writable. + // AH=status code=0x03 (tried to write on write-protected disk) + // AL=number of sectors written=0 + AX = 0x0300; + SET_CF(); + return; + } else { + BX_PANIC("int13_diskette_function: read error\n"); + } + } + + // ??? should track be new val from return_status[3] ? + set_diskette_current_cyl(drive, track); + // AL = number of sectors read (same value as passed) + SET_AH(0x00); // success + CLEAR_CF(); // success + return; + } else { // if (ah == 0x04) + // Verify Diskette Sectors + + // ??? should track be new val from return_status[3] ? + set_diskette_current_cyl(drive, track); + // AL = number of sectors verified (same value as passed) + CLEAR_CF(); // success + SET_AH(0x00); // success + return; + } + break; + + case 0x05: // format diskette track +BX_DEBUG_INT13_FL("floppy f05\n"); + + num_sectors = GET_AL(); + track = GET_CH(); + head = GET_DH(); + drive = GET_ELDL(); + + if ((drive > 1) || (head > 1) || (track > 79) || + (num_sectors == 0) || (num_sectors > 18)) { + SET_AH(1); + set_diskette_ret_status(1); + SET_CF(); // error occurred + } + + // see if drive exists + if (floppy_drive_exists(drive) == 0) { + SET_AH(0x80); // drive not responding + set_diskette_ret_status(0x80); + SET_CF(); // error occurred + return; + } + + // see if media in drive, and type is known + if (floppy_media_known(drive) == 0) { + if (floppy_media_sense(drive) == 0) { + SET_AH(0x0C); // Media type not found + set_diskette_ret_status(0x0C); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + } + + // set up DMA controller for transfer + page = (ES >> 12); // upper 4 bits + base_es = (ES << 4); // lower 16bits contributed by ES + base_address = base_es + BX; // lower 16 bits of address + // contributed by ES:BX + if ( base_address < base_es ) { + // in case of carry, adjust page by 1 + page++; + } + base_count = (num_sectors * 4) - 1; + + // check for 64K boundary overrun + last_addr = base_address + base_count; + if (last_addr < base_address) { + SET_AH(0x09); + set_diskette_ret_status(0x09); + SET_AL(0); // no sectors read + SET_CF(); // error occurred + return; + } + + outb(PORT_DMA1_MASK_REG, 0x06); + outb(PORT_DMA1_CLEAR_FF_REG, 0x00); // clear flip-flop + outb(PORT_DMA_ADDR_2, base_address); + outb(PORT_DMA_ADDR_2, base_address>>8); + outb(PORT_DMA1_CLEAR_FF_REG, 0x00); // clear flip-flop + outb(PORT_DMA_CNT_2, base_count); + outb(PORT_DMA_CNT_2, base_count>>8); + mode_register = 0x4a; // single mode, increment, autoinit disable, + // transfer type=read, channel 2 + outb(PORT_DMA1_MODE_REG, mode_register); + // port 81: DMA-1 Page Register, channel 2 + outb(PORT_DMA_PAGE_2, page); + outb(PORT_DMA1_MASK_REG, 0x02); + + // set up floppy controller for transfer + floppy_prepare_controller(drive); + + // send format-track command (6 bytes) to controller + outb(PORT_FD_DATA, 0x4d); // 4d: format track + outb(PORT_FD_DATA, (head << 2) | drive); // HD DR1 DR2 + outb(PORT_FD_DATA, 2); // 512 byte sector size + outb(PORT_FD_DATA, num_sectors); // number of sectors per track + outb(PORT_FD_DATA, 0); // Gap length + outb(PORT_FD_DATA, 0xf6); // Fill byte + // turn on interrupts + ASM_START + sti + ASM_END + + // wait on 40:3e bit 7 to become 1 + do { + val8 = read_byte(0x0040, 0x0040); + if (val8 == 0) { + floppy_reset_controller(); + SET_AH(0x80); // drive not ready (timeout) + set_diskette_ret_status(0x80); + SET_CF(); // error occurred + return; + } + val8 = (read_byte(0x0040, 0x003e) & 0x80); + } while ( val8 == 0 ); + + val8 = 0; // separate asm from while() loop + // turn off interrupts + ASM_START + cli + ASM_END + // set 40:3e bit 7 to 0 + val8 = read_byte(0x0040, 0x003e); + val8 &= 0x7f; + write_byte(0x0040, 0x003e, val8); + // check port 3f4 for accessibility to status bytes + val8 = inb(PORT_FD_STATUS); + if ( (val8 & 0xc0) != 0xc0 ) + BX_PANIC("int13_diskette: ctrl not ready\n"); + + // read 7 return status bytes from controller + // using loop index broken, have to unroll... + return_status[0] = inb(PORT_FD_DATA); + return_status[1] = inb(PORT_FD_DATA); + return_status[2] = inb(PORT_FD_DATA); + return_status[3] = inb(PORT_FD_DATA); + return_status[4] = inb(PORT_FD_DATA); + return_status[5] = inb(PORT_FD_DATA); + return_status[6] = inb(PORT_FD_DATA); + // record in BIOS Data Area + write_byte(0x0040, 0x0042, return_status[0]); + write_byte(0x0040, 0x0043, return_status[1]); + write_byte(0x0040, 0x0044, return_status[2]); + write_byte(0x0040, 0x0045, return_status[3]); + write_byte(0x0040, 0x0046, return_status[4]); + write_byte(0x0040, 0x0047, return_status[5]); + write_byte(0x0040, 0x0048, return_status[6]); + + if ( (return_status[0] & 0xc0) != 0 ) { + if ( (return_status[1] & 0x02) != 0 ) { + // diskette not writable. + // AH=status code=0x03 (tried to write on write-protected disk) + // AL=number of sectors written=0 + AX = 0x0300; + SET_CF(); + return; + } else { + BX_PANIC("int13_diskette_function: write error\n"); + } + } + + SET_AH(0); + set_diskette_ret_status(0); + set_diskette_current_cyl(drive, 0); + CLEAR_CF(); // successful + return; + + + case 0x08: // read diskette drive parameters +BX_DEBUG_INT13_FL("floppy f08\n"); + drive = GET_ELDL(); + + if (drive > 1) { + AX = 0; + BX = 0; + CX = 0; + DX = 0; + ES = 0; + DI = 0; + SET_DL(num_floppies); + SET_CF(); + return; + } + + drive_type = inb_cmos(0x10); + num_floppies = 0; + if (drive_type & 0xf0) + num_floppies++; + if (drive_type & 0x0f) + num_floppies++; + + if (drive == 0) + drive_type >>= 4; + else + drive_type &= 0x0f; + + SET_BH(0); + SET_BL(drive_type); + SET_AH(0); + SET_AL(0); + SET_DL(num_floppies); + + switch (drive_type) { + case 0: // none + CX = 0; + SET_DH(0); // max head # + break; + + case 1: // 360KB, 5.25" + CX = 0x2709; // 40 tracks, 9 sectors + SET_DH(1); // max head # + break; + + case 2: // 1.2MB, 5.25" + CX = 0x4f0f; // 80 tracks, 15 sectors + SET_DH(1); // max head # + break; + + case 3: // 720KB, 3.5" + CX = 0x4f09; // 80 tracks, 9 sectors + SET_DH(1); // max head # + break; + + case 4: // 1.44MB, 3.5" + CX = 0x4f12; // 80 tracks, 18 sectors + SET_DH(1); // max head # + break; + + case 5: // 2.88MB, 3.5" + CX = 0x4f24; // 80 tracks, 36 sectors + SET_DH(1); // max head # + break; + + case 6: // 160k, 5.25" + CX = 0x2708; // 40 tracks, 8 sectors + SET_DH(0); // max head # + break; + + case 7: // 180k, 5.25" + CX = 0x2709; // 40 tracks, 9 sectors + SET_DH(0); // max head # + break; + + case 8: // 320k, 5.25" + CX = 0x2708; // 40 tracks, 8 sectors + SET_DH(1); // max head # + break; + + default: // ? + BX_PANIC("floppy: int13: bad floppy type\n"); + } + + /* set es & di to point to 11 byte diskette param table in ROM */ +ASM_START + push bp + mov bp, sp + mov ax, #diskette_param_table2 + mov _int13_diskette_function.DI+2[bp], ax + mov _int13_diskette_function.ES+2[bp], cs + pop bp +ASM_END + CLEAR_CF(); // success + /* disk status not changed upon success */ + return; + + + case 0x15: // read diskette drive type +BX_DEBUG_INT13_FL("floppy f15\n"); + drive = GET_ELDL(); + if (drive > 1) { + SET_AH(0); // only 2 drives supported + // set_diskette_ret_status here ??? + SET_CF(); + return; + } + drive_type = inb_cmos(0x10); + + if (drive == 0) + drive_type >>= 4; + else + drive_type &= 0x0f; + CLEAR_CF(); // successful, not present + if (drive_type==0) { + SET_AH(0); // drive not present + } + else { + SET_AH(1); // drive present, does not support change line + } + + return; + + case 0x16: // get diskette change line status +BX_DEBUG_INT13_FL("floppy f16\n"); + drive = GET_ELDL(); + if (drive > 1) { + SET_AH(0x01); // invalid drive + set_diskette_ret_status(0x01); + SET_CF(); + return; + } + + SET_AH(0x06); // change line not supported + set_diskette_ret_status(0x06); + SET_CF(); + return; + + case 0x17: // set diskette type for format(old) +BX_DEBUG_INT13_FL("floppy f17\n"); + /* not used for 1.44M floppies */ + SET_AH(0x01); // not supported + set_diskette_ret_status(1); /* not supported */ + SET_CF(); + return; + + case 0x18: // set diskette type for format(new) +BX_DEBUG_INT13_FL("floppy f18\n"); + SET_AH(0x01); // do later + set_diskette_ret_status(1); + SET_CF(); + return; + + default: + BX_INFO("int13_diskette: unsupported AH=%02x\n", GET_AH()); + +// if ((ah==0x20) || ((ah>=0x41) && (ah<=0x49)) || (ah==0x4e)) { + SET_AH(0x01); // ??? + set_diskette_ret_status(1); + SET_CF(); + return; +// } + } +} +#else // #if BX_SUPPORT_FLOPPY + void +int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS) + Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS; +{ + Bit8u val8; + + switch (GET_AH()) { + + case 0x01: // Read Diskette Status + CLEAR_CF(); + val8 = read_byte(0x0000, 0x0441); + SET_AH(val8); + if (val8) { + SET_CF(); + } + return; + + default: + SET_CF(); + write_byte(0x0000, 0x0441, 0x01); + SET_AH(0x01); + } +} +#endif // #if BX_SUPPORT_FLOPPY + + void +set_diskette_ret_status(value) + Bit8u value; +{ + write_byte(0x0040, 0x0041, value); +} + + void +set_diskette_current_cyl(drive, cyl) + Bit8u drive; + Bit8u cyl; +{ + if (drive > 1) + BX_PANIC("set_diskette_current_cyl(): drive > 1\n"); + write_byte(0x0040, 0x0094+drive, cyl); +} + + void +determine_floppy_media(drive) + Bit16u drive; +{ +#if 0 + Bit8u val8, DOR, ctrl_info; + + ctrl_info = read_byte(0x0040, 0x008F); + if (drive==1) + ctrl_info >>= 4; + else + ctrl_info &= 0x0f; + +#if 0 + if (drive == 0) { + DOR = 0x1c; // DOR: drive0 motor on, DMA&int enabled, normal op, drive select 0 + } + else { + DOR = 0x2d; // DOR: drive1 motor on, DMA&int enabled, normal op, drive select 1 + } +#endif + + if ((ctrl_info & 0x04) != 0x04) { + // Drive not determined means no drive exists, done. + return; + } + +#if 0 + // check Main Status Register for readiness + val8 = inb(PORT_FD_STATUS) & 0x80; // Main Status Register + if (val8 != 0x80) + BX_PANIC("d_f_m: MRQ bit not set\n"); + + // change line + + // existing BDA values + + // turn on drive motor + outb(PORT_FD_DOR, DOR); // Digital Output Register + // +#endif + BX_PANIC("d_f_m: OK so far\n"); +#endif +} + + void +int17_function(regs, ds, iret_addr) + pusha_regs_t regs; // regs pushed from PUSHA instruction + Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper + iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call +{ + Bit16u addr,timeout; + Bit8u val8; + + ASM_START + sti + ASM_END + + addr = read_word(0x0040, (regs.u.r16.dx << 1) + 8); + if ((regs.u.r8.ah < 3) && (regs.u.r16.dx < 3) && (addr > 0)) { + timeout = read_byte(0x0040, 0x0078 + regs.u.r16.dx) << 8; + if (regs.u.r8.ah == 0) { + outb(addr, regs.u.r8.al); + val8 = inb(addr+2); + outb(addr+2, val8 | 0x01); // send strobe + ASM_START + nop + ASM_END + outb(addr+2, val8 & ~0x01); + while (((inb(addr+1) & 0x40) == 0x40) && (timeout)) { + timeout--; + } + } + if (regs.u.r8.ah == 1) { + val8 = inb(addr+2); + outb(addr+2, val8 & ~0x04); // send init + ASM_START + nop + ASM_END + outb(addr+2, val8 | 0x04); + } + val8 = inb(addr+1); + regs.u.r8.ah = (val8 ^ 0x48); + if (!timeout) regs.u.r8.ah |= 0x01; + ClearCF(iret_addr.flags); + } else { + SetCF(iret_addr.flags); // Unsupported + } +} + +void +int19_function(seq_nr) +Bit16u seq_nr; +{ + Bit16u ebda_seg=read_word(0x0040,0x000E); + Bit16u bootdev; + Bit8u bootdrv; + Bit8u bootchk; + Bit16u bootseg; + Bit16u bootip; + Bit16u status; + Bit16u bootfirst; + + ipl_entry_t e; + + // if BX_ELTORITO_BOOT is not defined, old behavior + // check bit 5 in CMOS reg 0x2d. load either 0x00 or 0x80 into DL + // in preparation for the initial INT 13h (0=floppy A:, 0x80=C:) + // 0: system boot sequence, first drive C: then A: + // 1: system boot sequence, first drive A: then C: + // else BX_ELTORITO_BOOT is defined + // CMOS regs 0x3D and 0x38 contain the boot sequence: + // CMOS reg 0x3D & 0x0f : 1st boot device + // CMOS reg 0x3D & 0xf0 : 2nd boot device + // CMOS reg 0x38 & 0xf0 : 3rd boot device + // boot device codes: + // 0x00 : not defined + // 0x01 : first floppy + // 0x02 : first harddrive + // 0x03 : first cdrom + // 0x04 - 0x0f : PnP expansion ROMs (e.g. Etherboot) + // else : boot failure + + // Get the boot sequence +#if BX_ELTORITO_BOOT + bootdev = inb_cmos(0x3d); + bootdev |= ((inb_cmos(0x38) & 0xf0) << 4); + bootdev >>= 4 * seq_nr; + bootdev &= 0xf; + + /* Read user selected device */ + bootfirst = read_word(IPL_SEG, IPL_BOOTFIRST_OFFSET); + if (bootfirst != 0xFFFF) { + bootdev = bootfirst; + /* User selected device not set */ + write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF); + /* Reset boot sequence */ + write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xFFFF); + } else if (bootdev == 0) BX_PANIC("No bootable device.\n"); + + /* Translate from CMOS runes to an IPL table offset by subtracting 1 */ + bootdev -= 1; +#else + if (seq_nr ==2) BX_PANIC("No more boot devices."); + if (!!(inb_cmos(0x2d) & 0x20) ^ (seq_nr == 1)) + /* Boot from floppy if the bit is set or it's the second boot */ + bootdev = 0x00; + else + bootdev = 0x01; +#endif + + /* Read the boot device from the IPL table */ + if (get_boot_vector(bootdev, &e) == 0) { + BX_INFO("Invalid boot device (0x%x)\n", bootdev); + return; + } + + /* Do the loading, and set up vector as a far pointer to the boot + * address, and bootdrv as the boot drive */ + print_boot_device(&e); + + switch(e.type) { + case IPL_TYPE_FLOPPY: /* FDD */ + case IPL_TYPE_HARDDISK: /* HDD */ + + bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00; + bootseg = 0x07c0; + status = 0; + +ASM_START + push bp + mov bp, sp + push ax + push bx + push cx + push dx + + mov dl, _int19_function.bootdrv + 2[bp] + mov ax, _int19_function.bootseg + 2[bp] + mov es, ax ;; segment + xor bx, bx ;; offset + mov ah, #0x02 ;; function 2, read diskette sector + mov al, #0x01 ;; read 1 sector + mov ch, #0x00 ;; track 0 + mov cl, #0x01 ;; sector 1 + mov dh, #0x00 ;; head 0 + int #0x13 ;; read sector + jnc int19_load_done + mov ax, #0x0001 + mov _int19_function.status + 2[bp], ax + +int19_load_done: + pop dx + pop cx + pop bx + pop ax + pop bp +ASM_END + + if (status != 0) { + print_boot_failure(e.type, 1); + return; + } + + /* Always check the signature on a HDD boot sector; on FDD, only do + * the check if the CMOS doesn't tell us to skip it */ + if ((e.type != IPL_TYPE_FLOPPY) || !((inb_cmos(0x38) & 0x01))) { + if (read_word(bootseg,0x1fe) != 0xaa55) { + print_boot_failure(e.type, 0); + return; + } + } + + /* Canonicalize bootseg:bootip */ + bootip = (bootseg & 0x0fff) << 4; + bootseg &= 0xf000; + break; + +#if BX_ELTORITO_BOOT + case IPL_TYPE_CDROM: /* CD-ROM */ + status = cdrom_boot(); + + // If failure + if ( (status & 0x00ff) !=0 ) { + print_cdromboot_failure(status); + print_boot_failure(e.type, 1); + return; + } + + bootdrv = (Bit8u)(status>>8); + bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment); + bootip = 0; + break; +#endif + + case IPL_TYPE_BEV: /* Expansion ROM with a Bootstrap Entry Vector (a far pointer) */ + bootseg = e.vector >> 16; + bootip = e.vector & 0xffff; + break; + + default: return; + } + + /* Debugging info */ + BX_INFO("Booting from %x:%x\n", bootseg, bootip); + + /* Jump to the boot vector */ +ASM_START + mov bp, sp + push cs + push #int18_handler + ;; Build an iret stack frame that will take us to the boot vector. + ;; iret pops ip, then cs, then flags, so push them in the opposite order. + pushf + mov ax, _int19_function.bootseg + 0[bp] + push ax + mov ax, _int19_function.bootip + 0[bp] + push ax + ;; Set the magic number in ax and the boot drive in dl. + mov ax, #0xaa55 + mov dl, _int19_function.bootdrv + 0[bp] + ;; Zero some of the other registers. + xor bx, bx + mov ds, bx + mov es, bx + mov bp, bx + ;; Go! + iret +ASM_END +} + + void +int1a_function(regs, ds, iret_addr) + pusha_regs_t regs; // regs pushed from PUSHA instruction + Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper + iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call +{ + Bit8u val8; + + BX_DEBUG_INT1A("int1a: AX=%04x BX=%04x CX=%04x DX=%04x DS=%04x\n", regs.u.r16.ax, regs.u.r16.bx, regs.u.r16.cx, regs.u.r16.dx, ds); + + ASM_START + sti + ASM_END + + switch (regs.u.r8.ah) { + case 0: // get current clock count + ASM_START + cli + ASM_END + regs.u.r16.cx = BiosData->ticks_high; + regs.u.r16.dx = BiosData->ticks_low; + regs.u.r8.al = BiosData->midnight_flag; + BiosData->midnight_flag = 0; // reset flag + ASM_START + sti + ASM_END + // AH already 0 + ClearCF(iret_addr.flags); // OK + break; + + case 1: // Set Current Clock Count + ASM_START + cli + ASM_END + BiosData->ticks_high = regs.u.r16.cx; + BiosData->ticks_low = regs.u.r16.dx; + BiosData->midnight_flag = 0; // reset flag + ASM_START + sti + ASM_END + regs.u.r8.ah = 0; + ClearCF(iret_addr.flags); // OK + break; + + + case 2: // Read CMOS Time + if (rtc_updating()) { + SetCF(iret_addr.flags); + break; + } + + regs.u.r8.dh = inb_cmos(0x00); // Seconds + regs.u.r8.cl = inb_cmos(0x02); // Minutes + regs.u.r8.ch = inb_cmos(0x04); // Hours + regs.u.r8.dl = inb_cmos(0x0b) & 0x01; // Stat Reg B + regs.u.r8.ah = 0; + regs.u.r8.al = regs.u.r8.ch; + ClearCF(iret_addr.flags); // OK + break; + + case 3: // Set CMOS Time + // Using a debugger, I notice the following masking/setting + // of bits in Status Register B, by setting Reg B to + // a few values and getting its value after INT 1A was called. + // + // try#1 try#2 try#3 + // before 1111 1101 0111 1101 0000 0000 + // after 0110 0010 0110 0010 0000 0010 + // + // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 + // My assumption: RegB = ((RegB & 01100000b) | 00000010b) + if (rtc_updating()) { + init_rtc(); + // fall through as if an update were not in progress + } + outb_cmos(0x00, regs.u.r8.dh); // Seconds + outb_cmos(0x02, regs.u.r8.cl); // Minutes + outb_cmos(0x04, regs.u.r8.ch); // Hours + // Set Daylight Savings time enabled bit to requested value + val8 = (inb_cmos(0x0b) & 0x60) | 0x02 | (regs.u.r8.dl & 0x01); + // (reg B already selected) + outb_cmos(0x0b, val8); + regs.u.r8.ah = 0; + regs.u.r8.al = val8; // val last written to Reg B + ClearCF(iret_addr.flags); // OK + break; + + case 4: // Read CMOS Date + regs.u.r8.ah = 0; + if (rtc_updating()) { + SetCF(iret_addr.flags); + break; + } + regs.u.r8.cl = inb_cmos(0x09); // Year + regs.u.r8.dh = inb_cmos(0x08); // Month + regs.u.r8.dl = inb_cmos(0x07); // Day of Month + regs.u.r8.ch = inb_cmos(0x32); // Century + regs.u.r8.al = regs.u.r8.ch; + ClearCF(iret_addr.flags); // OK + break; + + case 5: // Set CMOS Date + // Using a debugger, I notice the following masking/setting + // of bits in Status Register B, by setting Reg B to + // a few values and getting its value after INT 1A was called. + // + // try#1 try#2 try#3 try#4 + // before 1111 1101 0111 1101 0000 0010 0000 0000 + // after 0110 1101 0111 1101 0000 0010 0000 0000 + // + // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 + // My assumption: RegB = (RegB & 01111111b) + if (rtc_updating()) { + init_rtc(); + SetCF(iret_addr.flags); + break; + } + outb_cmos(0x09, regs.u.r8.cl); // Year + outb_cmos(0x08, regs.u.r8.dh); // Month + outb_cmos(0x07, regs.u.r8.dl); // Day of Month + outb_cmos(0x32, regs.u.r8.ch); // Century + val8 = inb_cmos(0x0b) & 0x7f; // clear halt-clock bit + outb_cmos(0x0b, val8); + regs.u.r8.ah = 0; + regs.u.r8.al = val8; // AL = val last written to Reg B + ClearCF(iret_addr.flags); // OK + break; + + case 6: // Set Alarm Time in CMOS + // Using a debugger, I notice the following masking/setting + // of bits in Status Register B, by setting Reg B to + // a few values and getting its value after INT 1A was called. + // + // try#1 try#2 try#3 + // before 1101 1111 0101 1111 0000 0000 + // after 0110 1111 0111 1111 0010 0000 + // + // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 + // My assumption: RegB = ((RegB & 01111111b) | 00100000b) + val8 = inb_cmos(0x0b); // Get Status Reg B + regs.u.r16.ax = 0; + if (val8 & 0x20) { + // Alarm interrupt enabled already + SetCF(iret_addr.flags); // Error: alarm in use + break; + } + if (rtc_updating()) { + init_rtc(); + // fall through as if an update were not in progress + } + outb_cmos(0x01, regs.u.r8.dh); // Seconds alarm + outb_cmos(0x03, regs.u.r8.cl); // Minutes alarm + outb_cmos(0x05, regs.u.r8.ch); // Hours alarm + outb(PORT_PIC2_DATA, inb(PORT_PIC2_DATA) & 0xfe); // enable IRQ 8 + // enable Status Reg B alarm bit, clear halt clock bit + outb_cmos(0x0b, (val8 & 0x7f) | 0x20); + ClearCF(iret_addr.flags); // OK + break; + + case 7: // Turn off Alarm + // Using a debugger, I notice the following masking/setting + // of bits in Status Register B, by setting Reg B to + // a few values and getting its value after INT 1A was called. + // + // try#1 try#2 try#3 try#4 + // before 1111 1101 0111 1101 0010 0000 0010 0010 + // after 0100 0101 0101 0101 0000 0000 0000 0010 + // + // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 + // My assumption: RegB = (RegB & 01010111b) + val8 = inb_cmos(0x0b); // Get Status Reg B + // clear clock-halt bit, disable alarm bit + outb_cmos(0x0b, val8 & 0x57); // disable alarm bit + regs.u.r8.ah = 0; + regs.u.r8.al = val8; // val last written to Reg B + ClearCF(iret_addr.flags); // OK + break; +#if BX_PCIBIOS + case 0xb1: + // real mode PCI BIOS functions now handled in assembler code + // this C code handles the error code for information only + if (regs.u.r8.bl == 0xff) { + BX_INFO("PCI BIOS: PCI not present\n"); + } else if (regs.u.r8.bl == 0x81) { + BX_INFO("unsupported PCI BIOS function 0x%02x\n", regs.u.r8.al); + } else if (regs.u.r8.bl == 0x83) { + BX_INFO("bad PCI vendor ID %04x\n", regs.u.r16.dx); + } else if (regs.u.r8.bl == 0x86) { + if (regs.u.r8.al == 0x02) { + BX_INFO("PCI device %04x:%04x not found at index %d\n", regs.u.r16.dx, regs.u.r16.cx, regs.u.r16.si); + } else { + BX_INFO("no PCI device with class code 0x%02x%04x found at index %d\n", regs.u.r8.cl, regs.u.r16.dx, regs.u.r16.si); + } + } + regs.u.r8.ah = regs.u.r8.bl; + SetCF(iret_addr.flags); + break; +#endif + + default: + SetCF(iret_addr.flags); // Unsupported + } +} + + void +int70_function(regs, ds, iret_addr) + pusha_regs_t regs; // regs pushed from PUSHA instruction + Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper + iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call +{ + // INT 70h: IRQ 8 - CMOS RTC interrupt from periodic or alarm modes + Bit8u registerB = 0, registerC = 0; + + // Check which modes are enabled and have occurred. + registerB = inb_cmos( 0xB ); + registerC = inb_cmos( 0xC ); + + if( ( registerB & 0x60 ) != 0 ) { + if( ( registerC & 0x20 ) != 0 ) { + // Handle Alarm Interrupt. +ASM_START + sti + int #0x4a + cli +ASM_END + } + if( ( registerC & 0x40 ) != 0 ) { + // Handle Periodic Interrupt. + + if( read_byte( 0x40, 0xA0 ) != 0 ) { + // Wait Interval (Int 15, AH=83) active. + Bit32u time, toggle; + + time = read_dword( 0x40, 0x9C ); // Time left in microseconds. + if( time < 0x3D1 ) { + // Done waiting. + Bit16u segment, offset; + + segment = read_word( 0x40, 0x98 ); + offset = read_word( 0x40, 0x9A ); + write_byte( 0x40, 0xA0, 0 ); // Turn of status byte. + outb_cmos( 0xB, registerB & 0x37 ); // Clear the Periodic Interrupt. + write_byte(segment, offset, read_byte(segment, offset) | 0x80 ); // Write to specified flag byte. + } else { + // Continue waiting. + time -= 0x3D1; + write_dword( 0x40, 0x9C, time ); + } + } + } + } + +ASM_START + call eoi_both_pics +ASM_END +} + + +ASM_START +;------------------------------------------ +;- INT74h : PS/2 mouse hardware interrupt - +;------------------------------------------ +int74_handler: + sti + pusha + push ds ;; save DS + push #0x00 ;; placeholder for status + push #0x00 ;; placeholder for X + push #0x00 ;; placeholder for Y + push #0x00 ;; placeholder for Z + push #0x00 ;; placeholder for make_far_call boolean + call _int74_function + pop cx ;; remove make_far_call from stack + jcxz int74_done + + ;; make far call to EBDA:0022 + push #0x00 + pop ds + push 0x040E ;; push 0000:040E (opcodes 0xff, 0x36, 0x0E, 0x04) + pop ds + //CALL_EP(0x0022) ;; call far routine (call_Ep DS:0022 :opcodes 0xff, 0x1e, 0x22, 0x00) + call far ptr[0x22] +int74_done: + cli + call eoi_both_pics + add sp, #8 ;; pop status, x, y, z + + pop ds ;; restore DS + popa + iret + + +;; This will perform an IRET, but will retain value of current CF +;; by altering flags on stack. Better than RETF #02. +iret_modify_cf: + jc carry_set + push bp + mov bp, sp + and BYTE [bp + 0x06], #0xfe + pop bp + iret +carry_set: + push bp + mov bp, sp + or BYTE [bp + 0x06], #0x01 + pop bp + iret + + +;---------------------- +;- INT13h (relocated) - +;---------------------- +; +; int13_relocated is a little bit messed up since I played with it +; I have to rewrite it: +; - call a function that detect which function to call +; - make all called C function get the same parameters list +; +int13_relocated: + +#if BX_ELTORITO_BOOT + ;; check for an eltorito function + cmp ah,#0x4a + jb int13_not_eltorito + cmp ah,#0x4d + ja int13_not_eltorito + + pusha + push es + push ds + push ss + pop ds + + push #int13_out + jmp _int13_eltorito ;; ELDX not used + +int13_not_eltorito: + push ax + push bx + push cx + push dx + + ;; check if emulation active + call _cdemu_isactive + cmp al,#0x00 + je int13_cdemu_inactive + + ;; check if access to the emulated drive + call _cdemu_emulated_drive + pop dx + push dx + cmp al,dl ;; int13 on emulated drive + jne int13_nocdemu + + pop dx + pop cx + pop bx + pop ax + + pusha + push es + push ds + push ss + pop ds + + push #int13_out + jmp _int13_cdemu ;; ELDX not used + +int13_nocdemu: + and dl,#0xE0 ;; mask to get device class, including cdroms + cmp al,dl ;; al is 0x00 or 0x80 + jne int13_cdemu_inactive ;; inactive for device class + + pop dx + pop cx + pop bx + pop ax + + push ax + push cx + push dx + push bx + + dec dl ;; real drive is dl - 1 + jmp int13_legacy + +int13_cdemu_inactive: + pop dx + pop cx + pop bx + pop ax + +#endif // BX_ELTORITO_BOOT + +int13_noeltorito: + + push ax + push cx + push dx + push bx + +int13_legacy: + + push dx ;; push eltorito value of dx instead of sp + + push bp + push si + push di + + push es + push ds + push ss + pop ds + + ;; now the 16-bit registers can be restored with: + ;; pop ds; pop es; popa; iret + ;; arguments passed to functions should be + ;; DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS + + test dl, #0x80 + jnz int13_notfloppy + + push #int13_out + jmp _int13_diskette_function + +int13_notfloppy: + +#if BX_USE_ATADRV + + cmp dl, #0xE0 + jb int13_notcdrom + + // ebx is modified: BSD 5.2.1 boot loader problem + // someone should figure out which 32 bit register that actually are used + + shr ebx, #16 + push bx + + call _int13_cdrom + + pop bx + shl ebx, #16 + + jmp int13_out + +int13_notcdrom: + +#endif + +int13_disk: + ;; int13_harddisk modifies high word of EAX + shr eax, #16 + push ax + call _int13_harddisk + pop ax + shl eax, #16 + +int13_out: + pop ds + pop es + popa + iret + +;---------- +;- INT18h - +;---------- +int18_handler: ;; Boot Failure recovery: try the next device. + + ;; Reset SP and SS + mov ax, #0xfffe + mov sp, ax + xor ax, ax + mov ss, ax + + ;; Get the boot sequence number out of the IPL memory + mov bx, #IPL_SEG + mov ds, bx ;; Set segment + mov bx, IPL_SEQUENCE_OFFSET ;; BX is now the sequence number + inc bx ;; ++ + mov IPL_SEQUENCE_OFFSET, bx ;; Write it back + mov ds, ax ;; and reset the segment to zero. + + ;; Carry on in the INT 19h handler, using the new sequence number + push bx + + jmp int19_next_boot + +;---------- +;- INT19h - +;---------- +int19_relocated: ;; Boot function, relocated + + ;; int19 was beginning to be really complex, so now it + ;; just calls a C function that does the work + + push bp + mov bp, sp + + ;; Reset SS and SP + mov ax, #0xfffe + mov sp, ax + xor ax, ax + mov ss, ax + + ;; Start from the first boot device (0, in AX) + mov bx, #IPL_SEG + mov ds, bx ;; Set segment to write to the IPL memory + mov IPL_SEQUENCE_OFFSET, ax ;; Save the sequence number + mov ds, ax ;; and reset the segment. + + push ax + +int19_next_boot: + + ;; Call the C code for the next boot device + call _int19_function + + ;; Boot failed: invoke the boot recovery function + int #0x18 + +;---------- +;- INT1Ch - +;---------- +int1c_handler: ;; User Timer Tick + iret + + +;---------------------- +;- POST: Floppy Drive - +;---------------------- +floppy_drive_post: + xor ax, ax + mov ds, ax + + mov al, #0x00 + mov 0x043e, al ;; drive 0 & 1 uncalibrated, no interrupt has occurred + + mov 0x043f, al ;; diskette motor status: read op, drive0, motors off + + mov 0x0440, al ;; diskette motor timeout counter: not active + mov 0x0441, al ;; diskette controller status return code + + mov 0x0442, al ;; disk & diskette controller status register 0 + mov 0x0443, al ;; diskette controller status register 1 + mov 0x0444, al ;; diskette controller status register 2 + mov 0x0445, al ;; diskette controller cylinder number + mov 0x0446, al ;; diskette controller head number + mov 0x0447, al ;; diskette controller sector number + mov 0x0448, al ;; diskette controller bytes written + + mov 0x048b, al ;; diskette configuration data + + ;; ----------------------------------------------------------------- + ;; (048F) diskette controller information + ;; + mov al, #0x10 ;; get CMOS diskette drive type + out PORT_CMOS_INDEX, AL + in AL, PORT_CMOS_DATA + mov ah, al ;; save byte to AH + +look_drive0: + shr al, #4 ;; look at top 4 bits for drive 0 + jz f0_missing ;; jump if no drive0 + mov bl, #0x07 ;; drive0 determined, multi-rate, has changed line + jmp look_drive1 +f0_missing: + mov bl, #0x00 ;; no drive0 + +look_drive1: + mov al, ah ;; restore from AH + and al, #0x0f ;; look at bottom 4 bits for drive 1 + jz f1_missing ;; jump if no drive1 + or bl, #0x70 ;; drive1 determined, multi-rate, has changed line +f1_missing: + ;; leave high bits in BL zerod + mov 0x048f, bl ;; put new val in BDA (diskette controller information) + ;; ----------------------------------------------------------------- + + mov al, #0x00 + mov 0x0490, al ;; diskette 0 media state + mov 0x0491, al ;; diskette 1 media state + + ;; diskette 0,1 operational starting state + ;; drive type has not been determined, + ;; has no changed detection line + mov 0x0492, al + mov 0x0493, al + + mov 0x0494, al ;; diskette 0 current cylinder + mov 0x0495, al ;; diskette 1 current cylinder + + mov al, #0x02 + out PORT_DMA1_MASK_REG, al ;; clear DMA-1 channel 2 mask bit + + SET_INT_VECTOR(0x1E, #0xF000, #diskette_param_table2) + SET_INT_VECTOR(0x40, #0xF000, #int13_diskette) + SET_INT_VECTOR(0x0E, #0xF000, #int0e_handler) ;; IRQ 6 + + ret + + +;-------------------- +;- POST: HARD DRIVE - +;-------------------- +; relocated here because the primary POST area isnt big enough. +hard_drive_post: + // IRQ 14 = INT 76h + // INT 76h calls INT 15h function ax=9100 + + mov al, #0x0a ; 0000 1010 = reserved, disable IRQ 14 + mov dx, #0x03f6 + out dx, al + + xor ax, ax + mov ds, ax + mov 0x0474, al /* hard disk status of last operation */ + mov 0x0477, al /* hard disk port offset (XT only ???) */ + mov 0x048c, al /* hard disk status register */ + mov 0x048d, al /* hard disk error register */ + mov 0x048e, al /* hard disk task complete flag */ + mov al, #0x01 + mov 0x0475, al /* hard disk number attached */ + mov al, #0xc0 + mov 0x0476, al /* hard disk control byte */ + SET_INT_VECTOR(0x13, #0xF000, #int13_handler) + SET_INT_VECTOR(0x76, #0xF000, #int76_handler) + ;; INT 41h: hard disk 0 configuration pointer + ;; INT 46h: hard disk 1 configuration pointer + SET_INT_VECTOR(0x41, #EBDA_SEG, #0x003D) + SET_INT_VECTOR(0x46, #EBDA_SEG, #0x004D) + + ;; move disk geometry data from CMOS to EBDA disk parameter table(s) + mov al, #0x12 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + and al, #0xf0 + cmp al, #0xf0 + je post_d0_extended + jmp check_for_hd1 +post_d0_extended: + mov al, #0x19 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + cmp al, #47 ;; decimal 47 - user definable + je post_d0_type47 + HALT(__LINE__) +post_d0_type47: + ;; CMOS purpose param table offset + ;; 1b cylinders low 0 + ;; 1c cylinders high 1 + ;; 1d heads 2 + ;; 1e write pre-comp low 5 + ;; 1f write pre-comp high 6 + ;; 20 retries/bad map/heads>8 8 + ;; 21 landing zone low C + ;; 22 landing zone high D + ;; 23 sectors/track E + + mov ax, #EBDA_SEG + mov ds, ax + + ;;; Filling EBDA table for hard disk 0. + mov al, #0x1f + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov ah, al + mov al, #0x1e + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov (0x003d + 0x05), ax ;; write precomp word + + mov al, #0x20 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov (0x003d + 0x08), al ;; drive control byte + + mov al, #0x22 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov ah, al + mov al, #0x21 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov (0x003d + 0x0C), ax ;; landing zone word + + mov al, #0x1c ;; get cylinders word in AX + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA ;; high byte + mov ah, al + mov al, #0x1b + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA ;; low byte + mov bx, ax ;; BX = cylinders + + mov al, #0x1d + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov cl, al ;; CL = heads + + mov al, #0x23 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov dl, al ;; DL = sectors + + cmp bx, #1024 + jnbe hd0_post_logical_chs ;; if cylinders > 1024, use translated style CHS + +hd0_post_physical_chs: + ;; no logical CHS mapping used, just physical CHS + ;; use Standard Fixed Disk Parameter Table (FDPT) + mov (0x003d + 0x00), bx ;; number of physical cylinders + mov (0x003d + 0x02), cl ;; number of physical heads + mov (0x003d + 0x0E), dl ;; number of physical sectors + jmp check_for_hd1 + +hd0_post_logical_chs: + ;; complies with Phoenix style Translated Fixed Disk Parameter Table (FDPT) + mov (0x003d + 0x09), bx ;; number of physical cylinders + mov (0x003d + 0x0b), cl ;; number of physical heads + mov (0x003d + 0x04), dl ;; number of physical sectors + mov (0x003d + 0x0e), dl ;; number of logical sectors (same) + mov al, #0xa0 + mov (0x003d + 0x03), al ;; A0h signature, indicates translated table + + cmp bx, #2048 + jnbe hd0_post_above_2048 + ;; 1024 < c <= 2048 cylinders + shr bx, #0x01 + shl cl, #0x01 + jmp hd0_post_store_logical + +hd0_post_above_2048: + cmp bx, #4096 + jnbe hd0_post_above_4096 + ;; 2048 < c <= 4096 cylinders + shr bx, #0x02 + shl cl, #0x02 + jmp hd0_post_store_logical + +hd0_post_above_4096: + cmp bx, #8192 + jnbe hd0_post_above_8192 + ;; 4096 < c <= 8192 cylinders + shr bx, #0x03 + shl cl, #0x03 + jmp hd0_post_store_logical + +hd0_post_above_8192: + ;; 8192 < c <= 16384 cylinders + shr bx, #0x04 + shl cl, #0x04 + +hd0_post_store_logical: + mov (0x003d + 0x00), bx ;; number of physical cylinders + mov (0x003d + 0x02), cl ;; number of physical heads + ;; checksum + mov cl, #0x0f ;; repeat count + mov si, #0x003d ;; offset to disk0 FDPT + mov al, #0x00 ;; sum +hd0_post_checksum_loop: + add al, [si] + inc si + dec cl + jnz hd0_post_checksum_loop + not al ;; now take 2s complement + inc al + mov [si], al +;;; Done filling EBDA table for hard disk 0. + + +check_for_hd1: + ;; is there really a second hard disk? if not, return now + mov al, #0x12 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + and al, #0x0f + jnz post_d1_exists + ret +post_d1_exists: + ;; check that the hd type is really 0x0f. + cmp al, #0x0f + jz post_d1_extended + HALT(__LINE__) +post_d1_extended: + ;; check that the extended type is 47 - user definable + mov al, #0x1a + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + cmp al, #47 ;; decimal 47 - user definable + je post_d1_type47 + HALT(__LINE__) +post_d1_type47: + ;; Table for disk1. + ;; CMOS purpose param table offset + ;; 0x24 cylinders low 0 + ;; 0x25 cylinders high 1 + ;; 0x26 heads 2 + ;; 0x27 write pre-comp low 5 + ;; 0x28 write pre-comp high 6 + ;; 0x29 heads>8 8 + ;; 0x2a landing zone low C + ;; 0x2b landing zone high D + ;; 0x2c sectors/track E +;;; Fill EBDA table for hard disk 1. + mov ax, #EBDA_SEG + mov ds, ax + mov al, #0x28 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov ah, al + mov al, #0x27 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov (0x004d + 0x05), ax ;; write precomp word + + mov al, #0x29 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov (0x004d + 0x08), al ;; drive control byte + + mov al, #0x2b + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov ah, al + mov al, #0x2a + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov (0x004d + 0x0C), ax ;; landing zone word + + mov al, #0x25 ;; get cylinders word in AX + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA ;; high byte + mov ah, al + mov al, #0x24 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA ;; low byte + mov bx, ax ;; BX = cylinders + + mov al, #0x26 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov cl, al ;; CL = heads + + mov al, #0x2c + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov dl, al ;; DL = sectors + + cmp bx, #1024 + jnbe hd1_post_logical_chs ;; if cylinders > 1024, use translated style CHS + +hd1_post_physical_chs: + ;; no logical CHS mapping used, just physical CHS + ;; use Standard Fixed Disk Parameter Table (FDPT) + mov (0x004d + 0x00), bx ;; number of physical cylinders + mov (0x004d + 0x02), cl ;; number of physical heads + mov (0x004d + 0x0E), dl ;; number of physical sectors + ret + +hd1_post_logical_chs: + ;; complies with Phoenix style Translated Fixed Disk Parameter Table (FDPT) + mov (0x004d + 0x09), bx ;; number of physical cylinders + mov (0x004d + 0x0b), cl ;; number of physical heads + mov (0x004d + 0x04), dl ;; number of physical sectors + mov (0x004d + 0x0e), dl ;; number of logical sectors (same) + mov al, #0xa0 + mov (0x004d + 0x03), al ;; A0h signature, indicates translated table + + cmp bx, #2048 + jnbe hd1_post_above_2048 + ;; 1024 < c <= 2048 cylinders + shr bx, #0x01 + shl cl, #0x01 + jmp hd1_post_store_logical + +hd1_post_above_2048: + cmp bx, #4096 + jnbe hd1_post_above_4096 + ;; 2048 < c <= 4096 cylinders + shr bx, #0x02 + shl cl, #0x02 + jmp hd1_post_store_logical + +hd1_post_above_4096: + cmp bx, #8192 + jnbe hd1_post_above_8192 + ;; 4096 < c <= 8192 cylinders + shr bx, #0x03 + shl cl, #0x03 + jmp hd1_post_store_logical + +hd1_post_above_8192: + ;; 8192 < c <= 16384 cylinders + shr bx, #0x04 + shl cl, #0x04 + +hd1_post_store_logical: + mov (0x004d + 0x00), bx ;; number of physical cylinders + mov (0x004d + 0x02), cl ;; number of physical heads + ;; checksum + mov cl, #0x0f ;; repeat count + mov si, #0x004d ;; offset to disk0 FDPT + mov al, #0x00 ;; sum +hd1_post_checksum_loop: + add al, [si] + inc si + dec cl + jnz hd1_post_checksum_loop + not al ;; now take 2s complement + inc al + mov [si], al +;;; Done filling EBDA table for hard disk 1. + + ret + +;-------------------- +;- POST: EBDA segment +;-------------------- +; relocated here because the primary POST area isnt big enough. +ebda_post: +#if BX_USE_EBDA + mov ax, #EBDA_SEG + mov ds, ax + mov byte ptr [0x0], #EBDA_SIZE +#endif + xor ax, ax ; mov EBDA seg into 40E + mov ds, ax + mov word ptr [0x40E], #EBDA_SEG + ret;; + +;-------------------- +;- POST: EOI + jmp via [0x40:67) +;-------------------- +; relocated here because the primary POST area isnt big enough. +eoi_jmp_post: + mov al, #0x11 ; send initialisation commands + out PORT_PIC1_CMD, al + out PORT_PIC2_CMD, al + mov al, #0x08 + out PORT_PIC1_DATA, al + mov al, #0x70 + out PORT_PIC2_DATA, al + mov al, #0x04 + out PORT_PIC1_DATA, al + mov al, #0x02 + out PORT_PIC2_DATA, al + mov al, #0x01 + out PORT_PIC1_DATA, al + out PORT_PIC2_DATA, al + mov al, #0xb8 + out PORT_PIC1_DATA, AL ;master pic: unmask IRQ 0, 1, 2, 6 +#if BX_USE_PS2_MOUSE + mov al, #0x8f +#else + mov al, #0x9f +#endif + out PORT_PIC2_DATA, AL ;slave pic: unmask IRQ 12, 13, 14 + mov al, #0x20 + out PORT_PIC2_CMD, al ;; slave PIC EOI + mov al, #0x20 + out PORT_PIC1_CMD, al ;; master PIC EOI + +jmp_post_0x467: + xor ax, ax + mov ds, ax + + jmp far ptr [0x467] + +iret_post_0x467: + xor ax, ax + mov ds, ax + + mov sp, [0x467] + mov ss, [0x469] + iret + +retf_post_0x467: + xor ax, ax + mov ds, ax + + mov sp, [0x467] + mov ss, [0x469] + retf + +s3_post: + mov sp, #0xffe +#if BX_ROMBIOS32 + call rombios32_init +#endif + call _s3_resume + mov bl, #0x00 + and ax, ax + jz normal_post + call _s3_resume_panic + +;-------------------- +eoi_both_pics: + mov al, #0x20 + out PORT_PIC2_CMD, al ;; slave PIC EOI +eoi_master_pic: + mov al, #0x20 + out PORT_PIC1_CMD, al ;; master PIC EOI + ret + +;-------------------- +BcdToBin: + ;; in: AL in BCD format + ;; out: AL in binary format, AH will always be 0 + ;; trashes BX + mov bl, al + and bl, #0x0f ;; bl has low digit + shr al, #4 ;; al has high digit + mov bh, #10 + mul al, bh ;; multiply high digit by 10 (result in AX) + add al, bl ;; then add low digit + ret + +;-------------------- +timer_tick_post: + ;; Setup the Timer Ticks Count (0x46C:dword) and + ;; Timer Ticks Roller Flag (0x470:byte) + ;; The Timer Ticks Count needs to be set according to + ;; the current CMOS time, as if ticks have been occurring + ;; at 18.2hz since midnight up to this point. Calculating + ;; this is a little complicated. Here are the factors I gather + ;; regarding this. 14,318,180 hz was the original clock speed, + ;; chosen so it could be divided by either 3 to drive the 5Mhz CPU + ;; at the time, or 4 to drive the CGA video adapter. The div3 + ;; source was divided again by 4 to feed a 1.193Mhz signal to + ;; the timer. With a maximum 16bit timer count, this is again + ;; divided down by 65536 to 18.2hz. + ;; + ;; 14,318,180 Hz clock + ;; /3 = 4,772,726 Hz fed to original 5Mhz CPU + ;; /4 = 1,193,181 Hz fed to timer + ;; /65536 (maximum timer count) = 18.20650736 ticks/second + ;; 1 second = 18.20650736 ticks + ;; 1 minute = 1092.390442 ticks + ;; 1 hour = 65543.42651 ticks + ;; + ;; Given the values in the CMOS clock, one could calculate + ;; the number of ticks by the following: + ;; ticks = (BcdToBin(seconds) * 18.206507) + + ;; (BcdToBin(minutes) * 1092.3904) + ;; (BcdToBin(hours) * 65543.427) + ;; To get a little more accuracy, since Im using integer + ;; arithmetic, I use: + ;; ticks = (BcdToBin(seconds) * 18206507) / 1000000 + + ;; (BcdToBin(minutes) * 10923904) / 10000 + + ;; (BcdToBin(hours) * 65543427) / 1000 + + ;; assuming DS=0000 + + ;; get CMOS seconds + xor eax, eax ;; clear EAX + mov al, #0x00 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA ;; AL has CMOS seconds in BCD + call BcdToBin ;; EAX now has seconds in binary + mov edx, #18206507 + mul eax, edx + mov ebx, #1000000 + xor edx, edx + div eax, ebx + mov ecx, eax ;; ECX will accumulate total ticks + + ;; get CMOS minutes + xor eax, eax ;; clear EAX + mov al, #0x02 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA ;; AL has CMOS minutes in BCD + call BcdToBin ;; EAX now has minutes in binary + mov edx, #10923904 + mul eax, edx + mov ebx, #10000 + xor edx, edx + div eax, ebx + add ecx, eax ;; add to total ticks + + ;; get CMOS hours + xor eax, eax ;; clear EAX + mov al, #0x04 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA ;; AL has CMOS hours in BCD + call BcdToBin ;; EAX now has hours in binary + mov edx, #65543427 + mul eax, edx + mov ebx, #1000 + xor edx, edx + div eax, ebx + add ecx, eax ;; add to total ticks + + mov 0x46C, ecx ;; Timer Ticks Count + xor al, al + mov 0x470, al ;; Timer Ticks Rollover Flag + ret + +;-------------------- +int76_handler: + ;; record completion in BIOS task complete flag + push ax + push ds + mov ax, #0x0040 + mov ds, ax + mov 0x008E, #0xff + call eoi_both_pics + pop ds + pop ax + iret + + +;-------------------- +#if BX_APM + +use32 386 +#define APM_PROT32 +#include "apmbios.S" + +use16 386 +#define APM_PROT16 +#include "apmbios.S" + +#define APM_REAL +#include "apmbios.S" + +#endif + +;-------------------- +#if BX_PCIBIOS +use32 386 +.align 16 +bios32_structure: + db 0x5f, 0x33, 0x32, 0x5f ;; "_32_" signature + dw bios32_entry_point, 0xf ;; 32 bit physical address + db 0 ;; revision level + ;; length in paragraphs and checksum stored in a word to prevent errors + dw (~(((bios32_entry_point >> 8) + (bios32_entry_point & 0xff) + 0x32) \ + & 0xff) << 8) + 0x01 + db 0,0,0,0,0 ;; reserved + +.align 16 +bios32_entry_point: + pushfd + cmp eax, #0x49435024 ;; "$PCI" + jne unknown_service + mov eax, #0x80000000 + mov dx, #0x0cf8 + out dx, eax + mov dx, #0x0cfc + in eax, dx +#ifdef PCI_FIXED_HOST_BRIDGE + cmp eax, #PCI_FIXED_HOST_BRIDGE + jne unknown_service +#else + ;; say ok if a device is present + cmp eax, #0xffffffff + je unknown_service +#endif + mov ebx, #0x000f0000 + mov ecx, #0 + mov edx, #pcibios_protected + xor al, al + jmp bios32_end +unknown_service: + mov al, #0x80 +bios32_end: +#ifdef BX_QEMU + and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu +#endif + popfd + retf + +.align 16 +pcibios_protected: + pushfd + cli + push esi + push edi + cmp al, #0x01 ;; installation check + jne pci_pro_f02 + mov bx, #0x0210 + mov cx, #0 + mov edx, #0x20494350 ;; "PCI " + mov al, #0x01 + jmp pci_pro_ok +pci_pro_f02: ;; find pci device + cmp al, #0x02 + jne pci_pro_f03 + shl ecx, #16 + mov cx, dx + xor bx, bx + mov di, #0x00 +pci_pro_devloop: + call pci_pro_select_reg + mov dx, #0x0cfc + in eax, dx + cmp eax, ecx + jne pci_pro_nextdev + cmp si, #0 + je pci_pro_ok + dec si +pci_pro_nextdev: + inc bx + cmp bx, #0x0100 + jne pci_pro_devloop + mov ah, #0x86 + jmp pci_pro_fail +pci_pro_f03: ;; find class code + cmp al, #0x03 + jne pci_pro_f08 + xor bx, bx + mov di, #0x08 +pci_pro_devloop2: + call pci_pro_select_reg + mov dx, #0x0cfc + in eax, dx + shr eax, #8 + cmp eax, ecx + jne pci_pro_nextdev2 + cmp si, #0 + je pci_pro_ok + dec si +pci_pro_nextdev2: + inc bx + cmp bx, #0x0100 + jne pci_pro_devloop2 + mov ah, #0x86 + jmp pci_pro_fail +pci_pro_f08: ;; read configuration byte + cmp al, #0x08 + jne pci_pro_f09 + call pci_pro_select_reg + push edx + mov dx, di + and dx, #0x03 + add dx, #0x0cfc + in al, dx + pop edx + mov cl, al + jmp pci_pro_ok +pci_pro_f09: ;; read configuration word + cmp al, #0x09 + jne pci_pro_f0a + call pci_pro_select_reg + push edx + mov dx, di + and dx, #0x02 + add dx, #0x0cfc + in ax, dx + pop edx + mov cx, ax + jmp pci_pro_ok +pci_pro_f0a: ;; read configuration dword + cmp al, #0x0a + jne pci_pro_f0b + call pci_pro_select_reg + push edx + mov dx, #0x0cfc + in eax, dx + pop edx + mov ecx, eax + jmp pci_pro_ok +pci_pro_f0b: ;; write configuration byte + cmp al, #0x0b + jne pci_pro_f0c + call pci_pro_select_reg + push edx + mov dx, di + and dx, #0x03 + add dx, #0x0cfc + mov al, cl + out dx, al + pop edx + jmp pci_pro_ok +pci_pro_f0c: ;; write configuration word + cmp al, #0x0c + jne pci_pro_f0d + call pci_pro_select_reg + push edx + mov dx, di + and dx, #0x02 + add dx, #0x0cfc + mov ax, cx + out dx, ax + pop edx + jmp pci_pro_ok +pci_pro_f0d: ;; write configuration dword + cmp al, #0x0d + jne pci_pro_unknown + call pci_pro_select_reg + push edx + mov dx, #0x0cfc + mov eax, ecx + out dx, eax + pop edx + jmp pci_pro_ok +pci_pro_unknown: + mov ah, #0x81 +pci_pro_fail: + pop edi + pop esi +#ifdef BX_QEMU + and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu +#endif + popfd + stc + retf +pci_pro_ok: + xor ah, ah + pop edi + pop esi +#ifdef BX_QEMU + and dword ptr[esp+8],0xfffffffc ;; reset CS.RPL for kqemu +#endif + popfd + clc + retf + +pci_pro_select_reg: + push edx + mov eax, #0x800000 + mov ax, bx + shl eax, #8 + and di, #0xff + or ax, di + and al, #0xfc + mov dx, #0x0cf8 + out dx, eax + pop edx + ret + +use16 386 + +pcibios_real: + push eax + push dx + mov eax, #0x80000000 + mov dx, #0x0cf8 + out dx, eax + mov dx, #0x0cfc + in eax, dx +#ifdef PCI_FIXED_HOST_BRIDGE + cmp eax, #PCI_FIXED_HOST_BRIDGE + je pci_present +#else + ;; say ok if a device is present + cmp eax, #0xffffffff + jne pci_present +#endif + pop dx + pop eax + mov ah, #0xff + stc + ret +pci_present: + pop dx + pop eax + cmp al, #0x01 ;; installation check + jne pci_real_f02 + mov ax, #0x0001 + mov bx, #0x0210 + mov cx, #0 + mov edx, #0x20494350 ;; "PCI " + mov edi, #0xf0000 + mov di, #pcibios_protected + clc + ret +pci_real_f02: ;; find pci device + push esi + push edi + cmp al, #0x02 + jne pci_real_f03 + shl ecx, #16 + mov cx, dx + xor bx, bx + mov di, #0x00 +pci_real_devloop: + call pci_real_select_reg + mov dx, #0x0cfc + in eax, dx + cmp eax, ecx + jne pci_real_nextdev + cmp si, #0 + je pci_real_ok + dec si +pci_real_nextdev: + inc bx + cmp bx, #0x0100 + jne pci_real_devloop + mov dx, cx + shr ecx, #16 + mov ax, #0x8602 + jmp pci_real_fail +pci_real_f03: ;; find class code + cmp al, #0x03 + jne pci_real_f08 + xor bx, bx + mov di, #0x08 +pci_real_devloop2: + call pci_real_select_reg + mov dx, #0x0cfc + in eax, dx + shr eax, #8 + cmp eax, ecx + jne pci_real_nextdev2 + cmp si, #0 + je pci_real_ok + dec si +pci_real_nextdev2: + inc bx + cmp bx, #0x0100 + jne pci_real_devloop2 + mov dx, cx + shr ecx, #16 + mov ax, #0x8603 + jmp pci_real_fail +pci_real_f08: ;; read configuration byte + cmp al, #0x08 + jne pci_real_f09 + call pci_real_select_reg + push dx + mov dx, di + and dx, #0x03 + add dx, #0x0cfc + in al, dx + pop dx + mov cl, al + jmp pci_real_ok +pci_real_f09: ;; read configuration word + cmp al, #0x09 + jne pci_real_f0a + call pci_real_select_reg + push dx + mov dx, di + and dx, #0x02 + add dx, #0x0cfc + in ax, dx + pop dx + mov cx, ax + jmp pci_real_ok +pci_real_f0a: ;; read configuration dword + cmp al, #0x0a + jne pci_real_f0b + call pci_real_select_reg + push dx + mov dx, #0x0cfc + in eax, dx + pop dx + mov ecx, eax + jmp pci_real_ok +pci_real_f0b: ;; write configuration byte + cmp al, #0x0b + jne pci_real_f0c + call pci_real_select_reg + push dx + mov dx, di + and dx, #0x03 + add dx, #0x0cfc + mov al, cl + out dx, al + pop dx + jmp pci_real_ok +pci_real_f0c: ;; write configuration word + cmp al, #0x0c + jne pci_real_f0d + call pci_real_select_reg + push dx + mov dx, di + and dx, #0x02 + add dx, #0x0cfc + mov ax, cx + out dx, ax + pop dx + jmp pci_real_ok +pci_real_f0d: ;; write configuration dword + cmp al, #0x0d + jne pci_real_f0e + call pci_real_select_reg + push dx + mov dx, #0x0cfc + mov eax, ecx + out dx, eax + pop dx + jmp pci_real_ok +pci_real_f0e: ;; get irq routing options + cmp al, #0x0e + jne pci_real_unknown + SEG ES + cmp word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start + jb pci_real_too_small + SEG ES + mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start + pushf + push ds + push es + push cx + push si + push di + cld + mov si, #pci_routing_table_structure_start + push cs + pop ds + SEG ES + mov cx, [di+2] + SEG ES + mov es, [di+4] + mov di, cx + mov cx, #pci_routing_table_structure_end - pci_routing_table_structure_start + rep + movsb + pop di + pop si + pop cx + pop es + pop ds + popf + mov bx, #(1 << 9) | (1 << 11) ;; irq 9 and 11 are used + jmp pci_real_ok +pci_real_too_small: + SEG ES + mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start + mov ah, #0x89 + jmp pci_real_fail + +pci_real_unknown: + mov ah, #0x81 +pci_real_fail: + pop edi + pop esi + stc + ret +pci_real_ok: + xor ah, ah + pop edi + pop esi + clc + ret + +pci_real_select_reg: + push dx + mov eax, #0x800000 + mov ax, bx + shl eax, #8 + and di, #0xff + or ax, di + and al, #0xfc + mov dx, #0x0cf8 + out dx, eax + pop dx + ret + +.align 16 +pci_routing_table_structure: + db 0x24, 0x50, 0x49, 0x52 ;; "$PIR" signature + db 0, 1 ;; version + dw 32 + (6 * 16) ;; table size + db 0 ;; PCI interrupt router bus + db 0x08 ;; PCI interrupt router DevFunc + dw 0x0000 ;; PCI exclusive IRQs + dw 0x8086 ;; compatible PCI interrupt router vendor ID + dw 0x122e ;; compatible PCI interrupt router device ID + dw 0,0 ;; Miniport data + db 0,0,0,0,0,0,0,0,0,0,0 ;; reserved + db 0x37 ;; checksum +pci_routing_table_structure_start: + ;; first slot entry PCI-to-ISA (embedded) + db 0 ;; pci bus number + db 0x08 ;; pci device number (bit 7-3) + db 0x60 ;; link value INTA#: pointer into PCI2ISA config space + dw 0xdef8 ;; IRQ bitmap INTA# + db 0x61 ;; link value INTB# + dw 0xdef8 ;; IRQ bitmap INTB# + db 0x62 ;; link value INTC# + dw 0xdef8 ;; IRQ bitmap INTC# + db 0x63 ;; link value INTD# + dw 0xdef8 ;; IRQ bitmap INTD# + db 0 ;; physical slot (0 = embedded) + db 0 ;; reserved + ;; second slot entry: 1st PCI slot + db 0 ;; pci bus number + db 0x10 ;; pci device number (bit 7-3) + db 0x61 ;; link value INTA# + dw 0xdef8 ;; IRQ bitmap INTA# + db 0x62 ;; link value INTB# + dw 0xdef8 ;; IRQ bitmap INTB# + db 0x63 ;; link value INTC# + dw 0xdef8 ;; IRQ bitmap INTC# + db 0x60 ;; link value INTD# + dw 0xdef8 ;; IRQ bitmap INTD# + db 1 ;; physical slot (0 = embedded) + db 0 ;; reserved + ;; third slot entry: 2nd PCI slot + db 0 ;; pci bus number + db 0x18 ;; pci device number (bit 7-3) + db 0x62 ;; link value INTA# + dw 0xdef8 ;; IRQ bitmap INTA# + db 0x63 ;; link value INTB# + dw 0xdef8 ;; IRQ bitmap INTB# + db 0x60 ;; link value INTC# + dw 0xdef8 ;; IRQ bitmap INTC# + db 0x61 ;; link value INTD# + dw 0xdef8 ;; IRQ bitmap INTD# + db 2 ;; physical slot (0 = embedded) + db 0 ;; reserved + ;; 4th slot entry: 3rd PCI slot + db 0 ;; pci bus number + db 0x20 ;; pci device number (bit 7-3) + db 0x63 ;; link value INTA# + dw 0xdef8 ;; IRQ bitmap INTA# + db 0x60 ;; link value INTB# + dw 0xdef8 ;; IRQ bitmap INTB# + db 0x61 ;; link value INTC# + dw 0xdef8 ;; IRQ bitmap INTC# + db 0x62 ;; link value INTD# + dw 0xdef8 ;; IRQ bitmap INTD# + db 3 ;; physical slot (0 = embedded) + db 0 ;; reserved + ;; 5th slot entry: 4rd PCI slot + db 0 ;; pci bus number + db 0x28 ;; pci device number (bit 7-3) + db 0x60 ;; link value INTA# + dw 0xdef8 ;; IRQ bitmap INTA# + db 0x61 ;; link value INTB# + dw 0xdef8 ;; IRQ bitmap INTB# + db 0x62 ;; link value INTC# + dw 0xdef8 ;; IRQ bitmap INTC# + db 0x63 ;; link value INTD# + dw 0xdef8 ;; IRQ bitmap INTD# + db 4 ;; physical slot (0 = embedded) + db 0 ;; reserved + ;; 6th slot entry: 5rd PCI slot + db 0 ;; pci bus number + db 0x30 ;; pci device number (bit 7-3) + db 0x61 ;; link value INTA# + dw 0xdef8 ;; IRQ bitmap INTA# + db 0x62 ;; link value INTB# + dw 0xdef8 ;; IRQ bitmap INTB# + db 0x63 ;; link value INTC# + dw 0xdef8 ;; IRQ bitmap INTC# + db 0x60 ;; link value INTD# + dw 0xdef8 ;; IRQ bitmap INTD# + db 5 ;; physical slot (0 = embedded) + db 0 ;; reserved +pci_routing_table_structure_end: + +#if !BX_ROMBIOS32 +pci_irq_list: + db 11, 10, 9, 5; + +pcibios_init_sel_reg: + push eax + mov eax, #0x800000 + mov ax, bx + shl eax, #8 + and dl, #0xfc + or al, dl + mov dx, #0x0cf8 + out dx, eax + pop eax + ret + +pcibios_init_iomem_bases: + push bp + mov bp, sp + mov eax, #0xc0000000 ;; base for memory init + push eax + mov ax, #0xc000 ;; base for i/o init + push ax + mov ax, #0x0010 ;; start at base address #0 + push ax + mov bx, #0x0008 +pci_init_io_loop1: + mov dl, #0x00 + call pcibios_init_sel_reg + mov dx, #0x0cfc + in ax, dx + cmp ax, #0xffff + jz next_pci_dev + mov dl, #0x04 ;; disable i/o and memory space access + call pcibios_init_sel_reg + mov dx, #0x0cfc + in al, dx + and al, #0xfc + out dx, al +pci_init_io_loop2: + mov dl, [bp-8] + call pcibios_init_sel_reg + mov dx, #0x0cfc + in eax, dx + test al, #0x01 + jnz init_io_base + mov ecx, eax + mov eax, #0xffffffff + out dx, eax + in eax, dx + cmp eax, ecx + je next_pci_base + xor eax, #0xffffffff + mov ecx, eax + mov eax, [bp-4] + out dx, eax + add eax, ecx ;; calculate next free mem base + add eax, #0x01000000 + and eax, #0xff000000 + mov [bp-4], eax + jmp next_pci_base +init_io_base: + mov cx, ax + mov ax, #0xffff + out dx, ax + in ax, dx + cmp ax, cx + je next_pci_base + xor ax, #0xfffe + mov cx, ax + mov ax, [bp-6] + out dx, ax + add ax, cx ;; calculate next free i/o base + add ax, #0x0100 + and ax, #0xff00 + mov [bp-6], ax +next_pci_base: + mov al, [bp-8] + add al, #0x04 + cmp al, #0x28 + je enable_iomem_space + mov byte ptr[bp-8], al + jmp pci_init_io_loop2 +enable_iomem_space: + mov dl, #0x04 ;; enable i/o and memory space access if available + call pcibios_init_sel_reg + mov dx, #0x0cfc + in al, dx + or al, #0x07 + out dx, al +next_pci_dev: + mov byte ptr[bp-8], #0x10 + inc bx + cmp bx, #0x0100 + jne pci_init_io_loop1 + mov sp, bp + pop bp + ret + +pcibios_init_set_elcr: + push ax + push cx + mov dx, #0x04d0 + test al, #0x08 + jz is_master_pic + inc dx + and al, #0x07 +is_master_pic: + mov cl, al + mov bl, #0x01 + shl bl, cl + in al, dx + or al, bl + out dx, al + pop cx + pop ax + ret + +pcibios_init_irqs: + push ds + push bp + mov ax, #0xf000 + mov ds, ax + mov dx, #0x04d0 ;; reset ELCR1 + ELCR2 + mov al, #0x00 + out dx, al + inc dx + out dx, al + mov si, #pci_routing_table_structure + mov bh, [si+8] + mov bl, [si+9] + mov dl, #0x00 + call pcibios_init_sel_reg + mov dx, #0x0cfc + in ax, dx + cmp ax, [si+12] ;; check irq router + jne pci_init_end + mov dl, [si+34] + call pcibios_init_sel_reg + push bx ;; save irq router bus + devfunc + mov dx, #0x0cfc + mov ax, #0x8080 + out dx, ax ;; reset PIRQ route control + add dx, #2 + out dx, ax + mov ax, [si+6] + sub ax, #0x20 + shr ax, #4 + mov cx, ax + add si, #0x20 ;; set pointer to 1st entry + mov bp, sp + mov ax, #pci_irq_list + push ax + xor ax, ax + push ax +pci_init_irq_loop1: + mov bh, [si] + mov bl, [si+1] +pci_init_irq_loop2: + mov dl, #0x00 + call pcibios_init_sel_reg + mov dx, #0x0cfc + in ax, dx + cmp ax, #0xffff + jnz pci_test_int_pin + test bl, #0x07 + jz next_pir_entry + jmp next_pci_func +pci_test_int_pin: + mov dl, #0x3c + call pcibios_init_sel_reg + mov dx, #0x0cfd + in al, dx + and al, #0x07 + jz next_pci_func + dec al ;; determine pirq reg + mov dl, #0x03 + mul al, dl + add al, #0x02 + xor ah, ah + mov bx, ax + mov al, [si+bx] + mov dl, al + mov bx, [bp] + call pcibios_init_sel_reg + mov dx, #0x0cfc + and al, #0x03 + add dl, al + in al, dx + cmp al, #0x80 + jb pirq_found + mov bx, [bp-2] ;; pci irq list pointer + mov al, [bx] + out dx, al + inc bx + mov [bp-2], bx + call pcibios_init_set_elcr +pirq_found: + mov bh, [si] + mov bl, [si+1] + add bl, [bp-3] ;; pci function number + mov dl, #0x3c + call pcibios_init_sel_reg + mov dx, #0x0cfc + out dx, al +next_pci_func: + inc byte ptr[bp-3] + inc bl + test bl, #0x07 + jnz pci_init_irq_loop2 +next_pir_entry: + add si, #0x10 + mov byte ptr[bp-3], #0x00 + loop pci_init_irq_loop1 + mov sp, bp + pop bx +pci_init_end: + pop bp + pop ds + ret +#endif // !BX_ROMBIOS32 +#endif // BX_PCIBIOS + +#if BX_ROMBIOS32 +rombios32_init: + ;; save a20 and enable it + in al, PORT_A20 + push ax + or al, #0x02 + out PORT_A20, al + + ;; save SS:SP to the BDA + xor ax, ax + mov ds, ax + mov 0x0469, ss + mov 0x0467, sp + + SEG CS + lidt [pmode_IDT_info] + SEG CS + lgdt [rombios32_gdt_48] + ;; set PE bit in CR0 + mov eax, cr0 + or al, #0x01 + mov cr0, eax + ;; start protected mode code: ljmpl 0x10:rombios32_init1 + db 0x66, 0xea + dw rombios32_05 + dw 0x000f ;; high 16 bit address + dw 0x0010 + +use32 386 +rombios32_05: + ;; init data segments + mov eax, #0x18 + mov ds, ax + mov es, ax + mov ss, ax + xor eax, eax + mov fs, ax + mov gs, ax + cld + + ;; init the stack pointer to point below EBDA + mov ax, [0x040e] + shl eax, #4 + mov esp, #-0x10 + add esp, eax + + ;; pass pointer to s3_resume_flag and s3_resume_vector to rombios32 + push #0x04b0 + push #0x04b2 + + ;; call rombios32 code + mov eax, #0x000e0000 + call eax + + ;; return to 16 bit protected mode first + db 0xea + dd rombios32_10 + dw 0x20 + +use16 386 +rombios32_10: + ;; restore data segment limits to 0xffff + mov ax, #0x28 + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax + + ;; reset PE bit in CR0 + mov eax, cr0 + and al, #0xFE + mov cr0, eax + + ;; far jump to flush CPU queue after transition to real mode + JMP_AP(0xf000, rombios32_real_mode) + +rombios32_real_mode: + ;; restore IDT to normal real-mode defaults + SEG CS + lidt [rmode_IDT_info] + + xor ax, ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ;; restore SS:SP from the BDA + mov ss, 0x0469 + xor esp, esp + mov sp, 0x0467 + ;; restore a20 + pop ax + out PORT_A20, al + ret + +rombios32_gdt_48: + dw 0x30 + dw rombios32_gdt + dw 0x000f + +rombios32_gdt: + dw 0, 0, 0, 0 + dw 0, 0, 0, 0 + dw 0xffff, 0, 0x9b00, 0x00cf ; 32 bit flat code segment (0x10) + dw 0xffff, 0, 0x9300, 0x00cf ; 32 bit flat data segment (0x18) + dw 0xffff, 0, 0x9b0f, 0x0000 ; 16 bit code segment base=0xf0000 limit=0xffff + dw 0xffff, 0, 0x9300, 0x0000 ; 16 bit data segment base=0x0 limit=0xffff +#endif // BX_ROMBIOS32 + + +; parallel port detection: base address in DX, index in BX, timeout in CL +detect_parport: + push dx + add dx, #2 + in al, dx + and al, #0xdf ; clear input mode + out dx, al + pop dx + mov al, #0xaa + out dx, al + in al, dx + cmp al, #0xaa + jne no_parport + push bx + shl bx, #1 + mov [bx+0x408], dx ; Parallel I/O address + pop bx + mov [bx+0x478], cl ; Parallel printer timeout + inc bx +no_parport: + ret + +; serial port detection: base address in DX, index in BX, timeout in CL +detect_serial: + push dx + inc dx + mov al, #0x02 + out dx, al + in al, dx + cmp al, #0x02 + jne no_serial + inc dx + in al, dx + cmp al, #0x02 + jne no_serial + dec dx + xor al, al + out dx, al + pop dx + push bx + shl bx, #1 + mov [bx+0x400], dx ; Serial I/O address + pop bx + mov [bx+0x47c], cl ; Serial timeout + inc bx + ret +no_serial: + pop dx + ret + +rom_checksum: + pusha + push ds + + xor ax, ax + xor bx, bx + xor cx, cx + xor dx, dx + + mov ch, [2] + shl cx, #1 + + jnc checksum_loop + jz checksum_loop + xchg dx, cx + dec cx + +checksum_loop: + add al, [bx] + inc bx + loop checksum_loop + + test dx, dx + je checksum_out + + add al, [bx] + mov cx, dx + mov dx, ds + add dh, #0x10 + mov ds, dx + xor dx, dx + xor bx, bx + + jmp checksum_loop + +checksum_out: + and al, #0xff + pop ds + popa + ret + + +.align 16 +#if !BX_PNPBIOS +;; Make sure the pnpbios structure is *not* aligned, so OSes will not see it if +;; they scan. + db 0 +#endif +pnpbios_structure: + .ascii "$PnP" + db 0x10 ;; version + db 0x21 ;; length + dw 0x0 ;; control field + db 0xd1 ;; checksum + dd 0xf0000 ;; event notification flag address + dw pnpbios_real ;; real mode 16 bit offset + dw 0xf000 ;; real mode 16 bit segment + dw pnpbios_prot ;; 16 bit protected mode offset + dd 0xf0000 ;; 16 bit protected mode segment base + dd 0x0 ;; OEM device identifier + dw 0xf000 ;; real mode 16 bit data segment + dd 0xf0000 ;; 16 bit protected mode segment base + +pnpbios_prot: + push ebp + mov ebp, esp + jmp pnpbios_code +pnpbios_real: + push ebp + movzx ebp, sp +pnpbios_code: + mov ax, 8[ebp] + cmp ax, #0x60 ;; Get Version and Installation Check + jnz pnpbios_fail + push ds + push di + mov ds, 12[bp] + mov di, 10[bp] + mov ax, #0x0101 + mov [di], ax + pop di + pop ds + xor ax, ax ;; SUCCESS + jmp pnpbios_exit +pnpbios_fail: + mov ax, #0x82 ;; FUNCTION_NOT_SUPPORTED +pnpbios_exit: + pop ebp + retf + +rom_scan: + ;; Scan for existence of valid expansion ROMS. + ;; Video ROM: from 0xC0000..0xC7FFF in 2k increments + ;; General ROM: from 0xC8000..0xDFFFF in 2k increments + ;; System ROM: only 0xE0000 + ;; + ;; Header: + ;; Offset Value + ;; 0 0x55 + ;; 1 0xAA + ;; 2 ROM length in 512-byte blocks + ;; 3 ROM initialization entry point (FAR CALL) + +rom_scan_loop: + push ax ;; Save AX + mov ds, cx + mov ax, #0x0004 ;; start with increment of 4 (512-byte) blocks = 2k + cmp [0], #0xAA55 ;; look for signature + jne rom_scan_increment + call rom_checksum + jnz rom_scan_increment + mov al, [2] ;; change increment to ROM length in 512-byte blocks + + ;; We want our increment in 512-byte quantities, rounded to + ;; the nearest 2k quantity, since we only scan at 2k intervals. + test al, #0x03 + jz block_count_rounded + and al, #0xfc ;; needs rounding up + add al, #0x04 +block_count_rounded: + + xor bx, bx ;; Restore DS back to 0000: + mov ds, bx + push ax ;; Save AX + push di ;; Save DI + ;; Push addr of ROM entry point + push cx ;; Push seg + push #0x0003 ;; Push offset + + ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS. + ;; That should stop it grabbing INT 19h; we will use its BEV instead. + mov ax, #0xf000 + mov es, ax + lea di, pnpbios_structure + + mov bp, sp ;; Call ROM init routine using seg:off on stack + db 0xff ;; call_far ss:[bp+0] + db 0x5e + db 0 + cli ;; In case expansion ROM BIOS turns IF on + add sp, #2 ;; Pop offset value + pop cx ;; Pop seg value (restore CX) + + ;; Look at the ROM's PnP Expansion header. Properly, we're supposed + ;; to init all the ROMs and then go back and build an IPL table of + ;; all the bootable devices, but we can get away with one pass. + mov ds, cx ;; ROM base + mov bx, 0x001a ;; 0x1A is the offset into ROM header that contains... + mov ax, [bx] ;; the offset of PnP expansion header, where... + cmp ax, #0x5024 ;; we look for signature "$PnP" + jne no_bev + mov ax, 2[bx] + cmp ax, #0x506e + jne no_bev + + mov ax, 0x16[bx] ;; 0x16 is the offset of Boot Connection Vector + cmp ax, #0x0000 + je no_bcv + + ;; Option ROM has BCV. Run it now. + push cx ;; Push seg + push ax ;; Push offset + + ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS. + mov bx, #0xf000 + mov es, bx + lea di, pnpbios_structure + /* jump to BCV function entry pointer */ + mov bp, sp ;; Call ROM BCV routine using seg:off on stack + db 0xff ;; call_far ss:[bp+0] + db 0x5e + db 0 + cli ;; In case expansion ROM BIOS turns IF on + add sp, #2 ;; Pop offset value + pop cx ;; Pop seg value (restore CX) + jmp no_bev + +no_bcv: + mov ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of... + cmp ax, #0x0000 ;; the Bootstrap Entry Vector, or zero if there is none. + je no_bev + + ;; Found a device that thinks it can boot the system. Record its BEV and product name string. + mov di, 0x10[bx] ;; Pointer to the product name string or zero if none + mov bx, #IPL_SEG ;; Go to the segment where the IPL table lives + mov ds, bx + mov bx, IPL_COUNT_OFFSET ;; Read the number of entries so far + cmp bx, #IPL_TABLE_ENTRIES + je no_bev ;; Get out if the table is full + shl bx, #0x4 ;; Turn count into offset (entries are 16 bytes) + mov 0[bx], #IPL_TYPE_BEV ;; This entry is a BEV device + mov 6[bx], cx ;; Build a far pointer from the segment... + mov 4[bx], ax ;; and the offset + cmp di, #0x0000 + je no_prod_str + mov 0xA[bx], cx ;; Build a far pointer from the segment... + mov 8[bx], di ;; and the offset +no_prod_str: + shr bx, #0x4 ;; Turn the offset back into a count + inc bx ;; We have one more entry now + mov IPL_COUNT_OFFSET, bx ;; Remember that. + +no_bev: + pop di ;; Restore DI + pop ax ;; Restore AX +rom_scan_increment: + shl ax, #5 ;; convert 512-bytes blocks to 16-byte increments + ;; because the segment selector is shifted left 4 bits. + add cx, ax + pop ax ;; Restore AX + cmp cx, ax + jbe rom_scan_loop + + xor ax, ax ;; Restore DS back to 0000: + mov ds, ax + ret + +post_init_pic: + mov al, #0x11 ; send initialisation commands + out PORT_PIC1_CMD, al + out PORT_PIC2_CMD, al + mov al, #0x08 + out PORT_PIC1_DATA, al + mov al, #0x70 + out PORT_PIC2_DATA, al + mov al, #0x04 + out PORT_PIC1_DATA, al + mov al, #0x02 + out PORT_PIC2_DATA, al + mov al, #0x01 + out PORT_PIC1_DATA, al + out PORT_PIC2_DATA, al + mov al, #0xb8 + out PORT_PIC1_DATA, AL ;master pic: unmask IRQ 0, 1, 2, 6 +#if BX_USE_PS2_MOUSE + mov al, #0x8f +#else + mov al, #0x9f +#endif + out PORT_PIC2_DATA, AL ;slave pic: unmask IRQ 12, 13, 14 + ret + +post_init_ivt: + ;; set all interrupts to default handler + xor bx, bx ;; offset index + mov cx, #0x0100 ;; counter (256 interrupts) + mov ax, #dummy_iret_handler + mov dx, #0xF000 + +post_default_ints: + mov [bx], ax + add bx, #2 + mov [bx], dx + add bx, #2 + loop post_default_ints + + ;; Printer Services vector + SET_INT_VECTOR(0x17, #0xF000, #int17_handler) + + ;; Bootstrap failure vector + SET_INT_VECTOR(0x18, #0xF000, #int18_handler) + + ;; Bootstrap Loader vector + SET_INT_VECTOR(0x19, #0xF000, #int19_handler) + + ;; User Timer Tick vector + SET_INT_VECTOR(0x1c, #0xF000, #int1c_handler) + + ;; Memory Size Check vector + SET_INT_VECTOR(0x12, #0xF000, #int12_handler) + + ;; Equipment Configuration Check vector + SET_INT_VECTOR(0x11, #0xF000, #int11_handler) + + ;; System Services + SET_INT_VECTOR(0x15, #0xF000, #int15_handler) + + ;; set vectors 0x60 - 0x66h to zero (0:180..0:19b) + xor ax, ax + mov cx, #0x000E ;; 14 words + mov di, #0x0180 + cld + rep + stosw + + ;; set vector 0x79 to zero + ;; this is used by 'guardian angel' protection system + SET_INT_VECTOR(0x79, #0, #0) + + ret + +;; the following area can be used to write dynamically generated tables + .align 16 +bios_table_area_start: + dd 0xaafb4442 + dd bios_table_area_end - bios_table_area_start - 8; + +;-------- +;- POST - +;-------- +.org 0xe05b ; POST Entry Point +post: + + xor ax, ax + + ;; first reset the DMA controllers + out PORT_DMA1_MASTER_CLEAR,al + out PORT_DMA2_MASTER_CLEAR,al + + ;; then initialize the DMA controllers + mov al, #0xC0 + out PORT_DMA2_MODE_REG, al ; cascade mode of channel 4 enabled + mov al, #0x00 + out PORT_DMA2_MASK_REG, al ; unmask channel 4 + + ;; Examine CMOS shutdown status. + mov AL, #0x0f + out PORT_CMOS_INDEX, AL + in AL, PORT_CMOS_DATA + + ;; backup status + mov bl, al + + ;; Reset CMOS shutdown status. + mov AL, #0x0f + out PORT_CMOS_INDEX, AL ; select CMOS register Fh + mov AL, #0x00 + out PORT_CMOS_DATA, AL ; set shutdown action to normal + + ;; Examine CMOS shutdown status. + mov al, bl + + ;; 0x00, 0x0D+ = normal startup + cmp AL, #0x00 + jz normal_post + cmp AL, #0x0d + jae normal_post + + ;; 0x05 = eoi + jmp via [0x40:0x67] jump + cmp al, #0x05 + je eoi_jmp_post + + ;; 0x0A = jmp via [0x40:0x67] jump + cmp al, #0x0a + je jmp_post_0x467 + + ;; 0x0B = iret via [0x40:0x67] + cmp al, #0x0b + je iret_post_0x467 + + ;; 0x0C = retf via [0x40:0x67] + cmp al, #0x0c + je retf_post_0x467 + + ;; Examine CMOS shutdown status. + ;; 0x01,0x02,0x03,0x04,0x06,0x07,0x08,0x09 = Unimplemented shutdown status. + push bx + call _shutdown_status_panic + +#if 0 + HALT(__LINE__) + ; + ;#if 0 + ; 0xb0, 0x20, /* mov al, #0x20 */ + ; 0xe6, 0x20, /* out PORT_PIC1_CMD, al ;send EOI to PIC */ + ;#endif + ; + pop es + pop ds + popa + iret +#endif + +normal_post: + ; case 0: normal startup + + cli + mov ax, #0xfffe + mov sp, ax + xor ax, ax + mov ds, ax + mov ss, ax + + ;; Save shutdown status + mov 0x04b0, bl + + cmp bl, #0xfe + jz s3_post + + ;; zero out BIOS data area (40:00..40:ff) + mov es, ax + mov cx, #0x0080 ;; 128 words + mov di, #0x0400 + cld + rep + stosw + + call _log_bios_start + + call post_init_ivt + + ;; base memory in K 40:13 (word) + mov ax, #BASE_MEM_IN_K + mov 0x0413, ax + + ;; Manufacturing Test 40:12 + ;; zerod out above + + ;; Warm Boot Flag 0040:0072 + ;; value of 1234h = skip memory checks + ;; zerod out above + + ;; EBDA setup + call ebda_post + + ;; PIT setup + SET_INT_VECTOR(0x08, #0xF000, #int08_handler) + ;; int 1C already points at dummy_iret_handler (above) + mov al, #0x34 ; timer0: binary count, 16bit count, mode 2 + out PORT_PIT_MODE, al + mov al, #0x00 ; maximum count of 0000H = 18.2Hz + out PORT_PIT_COUNTER0, al + out PORT_PIT_COUNTER0, al + + ;; Keyboard + SET_INT_VECTOR(0x09, #0xF000, #int09_handler) + SET_INT_VECTOR(0x16, #0xF000, #int16_handler) + + xor ax, ax + mov ds, ax + mov 0x0417, al /* keyboard shift flags, set 1 */ + mov 0x0418, al /* keyboard shift flags, set 2 */ + mov 0x0419, al /* keyboard alt-numpad work area */ + mov 0x0471, al /* keyboard ctrl-break flag */ + mov 0x0497, al /* keyboard status flags 4 */ + mov al, #0x10 + mov 0x0496, al /* keyboard status flags 3 */ + + + /* keyboard head of buffer pointer */ + mov bx, #0x001E + mov 0x041A, bx + + /* keyboard end of buffer pointer */ + mov 0x041C, bx + + /* keyboard pointer to start of buffer */ + mov bx, #0x001E + mov 0x0480, bx + + /* keyboard pointer to end of buffer */ + mov bx, #0x003E + mov 0x0482, bx + + /* init the keyboard */ + call _keyboard_init + + ;; mov CMOS Equipment Byte to BDA Equipment Word + mov ax, 0x0410 + mov al, #0x14 + out PORT_CMOS_INDEX, al + in al, PORT_CMOS_DATA + mov 0x0410, ax + + + ;; Parallel setup + SET_INT_VECTOR(0x0F, #0xF000, #dummy_iret_handler) + xor ax, ax + mov ds, ax + xor bx, bx + mov cl, #0x14 ; timeout value + mov dx, #0x378 ; Parallel I/O address, port 1 + call detect_parport + mov dx, #0x278 ; Parallel I/O address, port 2 + call detect_parport + shl bx, #0x0e + mov ax, 0x410 ; Equipment word bits 14..15 determine # parallel ports + and ax, #0x3fff + or ax, bx ; set number of parallel ports + mov 0x410, ax + + ;; Serial setup + SET_INT_VECTOR(0x0C, #0xF000, #dummy_iret_handler) + SET_INT_VECTOR(0x14, #0xF000, #int14_handler) + xor bx, bx + mov cl, #0x0a ; timeout value + mov dx, #0x03f8 ; Serial I/O address, port 1 + call detect_serial + mov dx, #0x02f8 ; Serial I/O address, port 2 + call detect_serial + mov dx, #0x03e8 ; Serial I/O address, port 3 + call detect_serial + mov dx, #0x02e8 ; Serial I/O address, port 4 + call detect_serial + shl bx, #0x09 + mov ax, 0x410 ; Equipment word bits 9..11 determine # serial ports + and ax, #0xf1ff + or ax, bx ; set number of serial port + mov 0x410, ax + + ;; CMOS RTC + SET_INT_VECTOR(0x1A, #0xF000, #int1a_handler) + SET_INT_VECTOR(0x4A, #0xF000, #dummy_iret_handler) + SET_INT_VECTOR(0x70, #0xF000, #int70_handler) + ;; BIOS DATA AREA 0x4CE ??? + call timer_tick_post + + ;; PS/2 mouse setup + SET_INT_VECTOR(0x74, #0xF000, #int74_handler) + + ;; IRQ13 (FPU exception) setup + SET_INT_VECTOR(0x75, #0xF000, #int75_handler) + + ;; Video setup + SET_INT_VECTOR(0x10, #0xF000, #int10_handler) + + ;; PIC + call post_init_pic + + mov cx, #0xc000 ;; init vga bios + mov ax, #0xc780 + call rom_scan + + call _print_bios_banner + +#if BX_ROMBIOS32 + call rombios32_init +#else +#if BX_PCIBIOS + call pcibios_init_iomem_bases + call pcibios_init_irqs +#endif //BX_PCIBIOS +#endif + + ;; + ;; Floppy setup + ;; + call floppy_drive_post + + ;; + ;; Hard Drive setup + ;; + call hard_drive_post + +#if BX_USE_ATADRV + + ;; + ;; ATA/ATAPI driver setup + ;; + call _ata_init + call _ata_detect + ;; + +#endif // BX_USE_ATADRV + +#if BX_ELTORITO_BOOT + ;; + ;; eltorito floppy/harddisk emulation from cd + ;; + call _cdemu_init + ;; +#endif // BX_ELTORITO_BOOT + + call _init_boot_vectors + + mov cx, #0xc800 ;; init option roms + mov ax, #0xe000 + call rom_scan + +#if BX_ELTORITO_BOOT + call _interactive_bootkey +#endif // BX_ELTORITO_BOOT + + sti ;; enable interrupts + int #0x19 + +.org 0xe2c3 ; NMI Handler Entry Point +nmi: + ;; FIXME the NMI handler should not panic + ;; but iret when called from int75 (fpu exception) + call _nmi_handler_msg + iret + +int75_handler: + out 0xf0, al // clear irq13 + call eoi_both_pics // clear interrupt + int 2 // legacy nmi call + iret + +;------------------------------------------- +;- INT 13h Fixed Disk Services Entry Point - +;------------------------------------------- +.org 0xe3fe ; INT 13h Fixed Disk Services Entry Point +int13_handler: + //JMPL(int13_relocated) + jmp int13_relocated + +.org 0xe401 ; Fixed Disk Parameter Table + +;---------- +;- INT19h - +;---------- +.org 0xe6f2 ; INT 19h Boot Load Service Entry Point +int19_handler: + + jmp int19_relocated +;------------------------------------------- +;- System BIOS Configuration Data Table +;------------------------------------------- +.org BIOS_CONFIG_TABLE +db 0x08 ; Table size (bytes) -Lo +db 0x00 ; Table size (bytes) -Hi +db SYS_MODEL_ID +db SYS_SUBMODEL_ID +db BIOS_REVISION +; Feature byte 1 +; b7: 1=DMA channel 3 used by hard disk +; b6: 1=2 interrupt controllers present +; b5: 1=RTC present +; b4: 1=BIOS calls int 15h/4Fh every key +; b3: 1=wait for extern event supported (Int 15h/41h) +; b2: 1=extended BIOS data area used +; b1: 0=AT or ESDI bus, 1=MicroChannel +; b0: 1=Dual bus (MicroChannel + ISA) +db (0 << 7) | \ + (1 << 6) | \ + (1 << 5) | \ + (BX_CALL_INT15_4F << 4) | \ + (0 << 3) | \ + (BX_USE_EBDA << 2) | \ + (0 << 1) | \ + (0 << 0) +; Feature byte 2 +; b7: 1=32-bit DMA supported +; b6: 1=int16h, function 9 supported +; b5: 1=int15h/C6h (get POS data) supported +; b4: 1=int15h/C7h (get mem map info) supported +; b3: 1=int15h/C8h (en/dis CPU) supported +; b2: 1=non-8042 kb controller +; b1: 1=data streaming supported +; b0: reserved +db (0 << 7) | \ + (1 << 6) | \ + (0 << 5) | \ + (0 << 4) | \ + (0 << 3) | \ + (0 << 2) | \ + (0 << 1) | \ + (0 << 0) +; Feature byte 3 +; b7: not used +; b6: reserved +; b5: reserved +; b4: POST supports ROM-to-RAM enable/disable +; b3: SCSI on system board +; b2: info panel installed +; b1: Initial Machine Load (IML) system - BIOS on disk +; b0: SCSI supported in IML +db 0x00 +; Feature byte 4 +; b7: IBM private +; b6: EEPROM present +; b5-3: ABIOS presence (011 = not supported) +; b2: private +; b1: memory split above 16Mb supported +; b0: POSTEXT directly supported by POST +db 0x00 +; Feature byte 5 (IBM) +; b1: enhanced mouse +; b0: flash EPROM +db 0x00 + + + +.org 0xe729 ; Baud Rate Generator Table + +;---------- +;- INT14h - +;---------- +.org 0xe739 ; INT 14h Serial Communications Service Entry Point +int14_handler: + push ds + pusha + xor ax, ax + mov ds, ax + call _int14_function + popa + pop ds + iret + + +;---------------------------------------- +;- INT 16h Keyboard Service Entry Point - +;---------------------------------------- +.org 0xe82e +int16_handler: + + sti + push ds + pushf + pusha + + cmp ah, #0x00 + je int16_F00 + cmp ah, #0x10 + je int16_F00 + + mov bx, #0xf000 + mov ds, bx + call _int16_function + popa + popf + pop ds + jz int16_zero_set + +int16_zero_clear: + push bp + mov bp, sp + //SEG SS + and BYTE [bp + 0x06], #0xbf + pop bp + iret + +int16_zero_set: + push bp + mov bp, sp + //SEG SS + or BYTE [bp + 0x06], #0x40 + pop bp + iret + +int16_F00: + mov bx, #0x0040 + mov ds, bx + +int16_wait_for_key: + cli + mov bx, 0x001a + cmp bx, 0x001c + jne int16_key_found + sti + nop +#if 0 + /* no key yet, call int 15h, function AX=9002 */ + 0x50, /* push AX */ + 0xb8, 0x02, 0x90, /* mov AX, #0x9002 */ + 0xcd, 0x15, /* int 15h */ + 0x58, /* pop AX */ + 0xeb, 0xea, /* jmp WAIT_FOR_KEY */ +#endif + jmp int16_wait_for_key + +int16_key_found: + mov bx, #0xf000 + mov ds, bx + call _int16_function + popa + popf + pop ds +#if 0 + /* notify int16 complete w/ int 15h, function AX=9102 */ + 0x50, /* push AX */ + 0xb8, 0x02, 0x91, /* mov AX, #0x9102 */ + 0xcd, 0x15, /* int 15h */ + 0x58, /* pop AX */ +#endif + iret + + + +;------------------------------------------------- +;- INT09h : Keyboard Hardware Service Entry Point - +;------------------------------------------------- +.org 0xe987 +int09_handler: + cli + push ax + + mov al, #0xAD ;;disable keyboard + out PORT_PS2_STATUS, al + + mov al, #0x0B + out PORT_PIC1_CMD, al + in al, PORT_PIC1_CMD + and al, #0x02 + jz int09_finish + + in al, PORT_PS2_DATA ;;read key from keyboard controller + sti + push ds + pusha +#ifdef BX_CALL_INT15_4F + mov ah, #0x4f ;; allow for keyboard intercept + stc + int #0x15 + jnc int09_done +#endif + + ;; check for extended key + cmp al, #0xe0 + jne int09_check_pause + xor ax, ax + mov ds, ax + mov al, BYTE [0x496] ;; mf2_state |= 0x02 + or al, #0x02 + mov BYTE [0x496], al + jmp int09_done + +int09_check_pause: ;; check for pause key + cmp al, #0xe1 + jne int09_process_key + xor ax, ax + mov ds, ax + mov al, BYTE [0x496] ;; mf2_state |= 0x01 + or al, #0x01 + mov BYTE [0x496], al + jmp int09_done + +int09_process_key: + mov bx, #0xf000 + mov ds, bx + call _int09_function + +int09_done: + popa + pop ds + cli + call eoi_master_pic + +int09_finish: + mov al, #0xAE ;;enable keyboard + out PORT_PS2_STATUS, al + pop ax + iret + + +;---------------------------------------- +;- INT 13h Diskette Service Entry Point - +;---------------------------------------- +.org 0xec59 +int13_diskette: + jmp int13_noeltorito + +;--------------------------------------------- +;- INT 0Eh Diskette Hardware ISR Entry Point - +;--------------------------------------------- +.org 0xef57 ; INT 0Eh Diskette Hardware ISR Entry Point +int0e_handler: + push ax + push dx + mov dx, #0x03f4 + in al, dx + and al, #0xc0 + cmp al, #0xc0 + je int0e_normal + mov dx, #0x03f5 + mov al, #0x08 ; sense interrupt status + out dx, al +int0e_loop1: + mov dx, #0x03f4 + in al, dx + and al, #0xc0 + cmp al, #0xc0 + jne int0e_loop1 +int0e_loop2: + mov dx, #0x03f5 + in al, dx + mov dx, #0x03f4 + in al, dx + and al, #0xc0 + cmp al, #0xc0 + je int0e_loop2 +int0e_normal: + push ds + xor ax, ax ;; segment 0000 + mov ds, ax + call eoi_master_pic + mov al, 0x043e + or al, #0x80 ;; diskette interrupt has occurred + mov 0x043e, al + pop ds + pop dx + pop ax + iret + + +.org 0xefc7 ; Diskette Controller Parameter Table +diskette_param_table: +;; Since no provisions are made for multiple drive types, most +;; values in this table are ignored. I set parameters for 1.44M +;; floppy here +db 0xAF +db 0x02 ;; head load time 0000001, DMA used +db 0x25 +db 0x02 +db 18 +db 0x1B +db 0xFF +db 0x6C +db 0xF6 +db 0x0F +db 0x08 + + +;---------------------------------------- +;- INT17h : Printer Service Entry Point - +;---------------------------------------- +.org 0xefd2 +int17_handler: + push ds + pusha + xor ax, ax + mov ds, ax + call _int17_function + popa + pop ds + iret + +diskette_param_table2: +;; New diskette parameter table adding 3 parameters from IBM +;; Since no provisions are made for multiple drive types, most +;; values in this table are ignored. I set parameters for 1.44M +;; floppy here +db 0xAF +db 0x02 ;; head load time 0000001, DMA used +db 0x25 +db 0x02 +db 18 +db 0x1B +db 0xFF +db 0x6C +db 0xF6 +db 0x0F +db 0x08 +db 79 ;; maximum track +db 0 ;; data transfer rate +db 4 ;; drive type in cmos + +.org 0xf045 ; INT 10 Functions 0-Fh Entry Point + HALT(__LINE__) + iret + +;---------- +;- INT10h - +;---------- +.org 0xf065 ; INT 10h Video Support Service Entry Point +int10_handler: + ;; dont do anything, since the VGA BIOS handles int10h requests + iret + +.org 0xf0a4 ; MDA/CGA Video Parameter Table (INT 1Dh) + +;---------- +;- INT12h - +;---------- +.org 0xf841 ; INT 12h Memory Size Service Entry Point +; ??? different for Pentium (machine check)? +int12_handler: + push ds + mov ax, #0x0040 + mov ds, ax + mov ax, 0x0013 + pop ds + iret + +;---------- +;- INT11h - +;---------- +.org 0xf84d ; INT 11h Equipment List Service Entry Point +int11_handler: + push ds + mov ax, #0x0040 + mov ds, ax + mov ax, 0x0010 + pop ds + iret + +;---------- +;- INT15h - +;---------- +.org 0xf859 ; INT 15h System Services Entry Point +int15_handler: + pushf +#if BX_APM + cmp ah, #0x53 + je apm_call +#endif + push ds + push es + cmp ah, #0x86 + je int15_handler32 + cmp ah, #0xE8 + je int15_handler32 + pusha +#if BX_USE_PS2_MOUSE + cmp ah, #0xC2 + je int15_handler_mouse +#endif + call _int15_function +int15_handler_mouse_ret: + popa +int15_handler32_ret: + pop es + pop ds + popf + jmp iret_modify_cf +#if BX_APM +apm_call: + jmp _apmreal_entry +#endif + +#if BX_USE_PS2_MOUSE +int15_handler_mouse: + call _int15_function_mouse + jmp int15_handler_mouse_ret +#endif + +int15_handler32: + pushad + call _int15_function32 + popad + jmp int15_handler32_ret + +;; Protected mode IDT descriptor +;; +;; I just make the limit 0, so the machine will shutdown +;; if an exception occurs during protected mode memory +;; transfers. +;; +;; Set base to f0000 to correspond to beginning of BIOS, +;; in case I actually define an IDT later +;; Set limit to 0 + +pmode_IDT_info: +dw 0x0000 ;; limit 15:00 +dw 0x0000 ;; base 15:00 +db 0x0f ;; base 23:16 + +;; Real mode IDT descriptor +;; +;; Set to typical real-mode values. +;; base = 000000 +;; limit = 03ff + +rmode_IDT_info: +dw 0x03ff ;; limit 15:00 +dw 0x0000 ;; base 15:00 +db 0x00 ;; base 23:16 + + +;---------- +;- INT1Ah - +;---------- +.org 0xfe6e ; INT 1Ah Time-of-day Service Entry Point +int1a_handler: +#if BX_PCIBIOS + cmp ah, #0xb1 + jne int1a_normal + call pcibios_real + jc pcibios_error + retf 2 +pcibios_error: + mov bl, ah + mov ah, #0xb1 + push ds + pusha + mov ax, ss ; set readable descriptor to ds, for calling pcibios + mov ds, ax ; on 16bit protected mode. + jmp int1a_callfunction +int1a_normal: +#endif + push ds + pusha + xor ax, ax + mov ds, ax +int1a_callfunction: + call _int1a_function + popa + pop ds + iret + +;; +;; int70h: IRQ8 - CMOS RTC +;; +int70_handler: + push ds + pushad + xor ax, ax + mov ds, ax + call _int70_function + popad + pop ds + iret + +;--------- +;- INT08 - +;--------- +.org 0xfea5 ; INT 08h System Timer ISR Entry Point +int08_handler: + sti + push eax + push ds + xor ax, ax + mov ds, ax + + ;; time to turn off drive(s)? + mov al,0x0440 + or al,al + jz int08_floppy_off + dec al + mov 0x0440,al + jnz int08_floppy_off + ;; turn motor(s) off + push dx + mov dx,#0x03f2 + in al,dx + and al,#0xcf + out dx,al + pop dx +int08_floppy_off: + + mov eax, 0x046c ;; get ticks dword + inc eax + + ;; compare eax to one days worth of timer ticks at 18.2 hz + cmp eax, #0x001800B0 + jb int08_store_ticks + ;; there has been a midnight rollover at this point + xor eax, eax ;; zero out counter + inc BYTE 0x0470 ;; increment rollover flag + +int08_store_ticks: + mov 0x046c, eax ;; store new ticks dword + ;; chain to user timer tick INT #0x1c + //pushf + //;; call_ep [ds:loc] + //CALL_EP( 0x1c << 2 ) + int #0x1c + cli + call eoi_master_pic + pop ds + pop eax + iret + +.org 0xfef3 ; Initial Interrupt Vector Offsets Loaded by POST + + +.org 0xff00 +.ascii BIOS_COPYRIGHT_STRING + +;------------------------------------------------ +;- IRET Instruction for Dummy Interrupt Handler - +;------------------------------------------------ +.org 0xff53 ; IRET Instruction for Dummy Interrupt Handler +dummy_iret_handler: + iret + +.org 0xff54 ; INT 05h Print Screen Service Entry Point + HALT(__LINE__) + iret + +.org 0xfff0 ; Power-up Entry Point + jmp 0xf000:post + +.org 0xfff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY +.ascii BIOS_BUILD_DATE + +.org 0xfffe ; System Model ID +db SYS_MODEL_ID +db 0x00 ; filler + +.org 0xfa6e ;; Character Font for 320x200 & 640x200 Graphics (lower 128 characters) +ASM_END +/* + * This font comes from the fntcol16.zip package (c) by Joseph Gil + * found at ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip + * This font is public domain + */ +static Bit8u vgafont8[128*8]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, + 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, + 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, + 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, + 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, + 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, + 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, + 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, + 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, + 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, + 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, + 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, + 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, + 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, + 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, + 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, + 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, + 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, + 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, + 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, + 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, + 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, + 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, + 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, + 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, + 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, + 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, + 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, + 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, + 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, + 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, + 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, + 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, + 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, + 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, + 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, + 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, + 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, + 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, +}; + +ASM_START +.org 0xcc00 +bios_table_area_end: +// bcc-generated data will be placed here +ASM_END diff --git a/bochs/bios/rombios.h b/bochs/bios/rombios.h new file mode 100644 index 00000000..1b8e2ba0 --- /dev/null +++ b/bochs/bios/rombios.h @@ -0,0 +1,248 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2006 Volker Ruppert +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/* define it to include QEMU specific code */ +//#define BX_QEMU + +#ifndef LEGACY +# define BX_ROMBIOS32 1 +#else +# define BX_ROMBIOS32 0 +#endif + +#define DEBUG_ROMBIOS 0 +#define DEBUG_ATA 0 +#define DEBUG_INT13_HD 0 +#define DEBUG_INT13_CD 0 +#define DEBUG_INT13_ET 0 +#define DEBUG_INT13_FL 0 +#define DEBUG_INT15 0 +#define DEBUG_INT16 0 +#define DEBUG_INT1A 0 +#define DEBUG_INT74 0 +#define DEBUG_APM 0 + +#define PANIC_PORT 0x400 +#define PANIC_PORT2 0x401 +#define INFO_PORT 0x402 +#define DEBUG_PORT 0x403 + +#define BIOS_PRINTF_HALT 1 +#define BIOS_PRINTF_SCREEN 2 +#define BIOS_PRINTF_INFO 4 +#define BIOS_PRINTF_DEBUG 8 +#define BIOS_PRINTF_ALL (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO) +#define BIOS_PRINTF_DEBHALT (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO | BIOS_PRINTF_HALT) + +#define printf(format, p...) bios_printf(BIOS_PRINTF_SCREEN, format, ##p) + +// Defines the output macros. +// BX_DEBUG goes to INFO port until we can easily choose debug info on a +// per-device basis. Debug info are sent only in debug mode +#if DEBUG_ROMBIOS +# define BX_DEBUG(format, p...) bios_printf(BIOS_PRINTF_INFO, format, ##p) +#else +# define BX_DEBUG(format, p...) +#endif +#define BX_INFO(format, p...) bios_printf(BIOS_PRINTF_INFO, format, ##p) +#define BX_PANIC(format, p...) bios_printf(BIOS_PRINTF_DEBHALT, format, ##p) + +/* put the MP float table and ACPI RSDP in EBDA and the MP and ACPI tables in + high memory. Linux kernels < 2.6.30 might not work with this configuration */ +//#define BX_USE_EBDA_TABLES + +#define ACPI_DATA_SIZE 0x00010000L +#define MPTABLE_MAX_SIZE 0x00002000 +#define PM_IO_BASE 0xb000 +#define SMB_IO_BASE 0xb100 +#define SMP_MSR_ADDR 0x0510 + + // Define the application NAME +#if defined(BX_QEMU) +# define BX_APPNAME "QEMU" +# define BX_APPVENDOR "QEMU" +#else +# define BX_APPNAME "Bochs" +# define BX_APPVENDOR "The Bochs Project" +#endif + +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + +#define BX_CPU 3 +#define BX_USE_PS2_MOUSE 1 +#define BX_CALL_INT15_4F 1 +#define BX_USE_EBDA 1 +#define BX_SUPPORT_FLOPPY 1 +#define BX_FLOPPY_ON_CNT 37 /* 2 seconds */ +#define BX_PCIBIOS 1 +#define BX_APM 1 +#define BX_PNPBIOS 1 +/* define it if the (emulated) hardware supports SMM mode */ +#define BX_USE_SMM + +#define BX_USE_ATADRV 1 +#define BX_ELTORITO_BOOT 1 + +#define BX_MAX_ATA_INTERFACES 4 +#define BX_MAX_ATA_DEVICES (BX_MAX_ATA_INTERFACES*2) + +#define BX_VIRTUAL_PORTS 1 /* normal output to Bochs ports */ +#define BX_DEBUG_SERIAL 0 /* output to COM1 */ + + /* model byte 0xFC = AT */ +#define SYS_MODEL_ID 0xFC +#define SYS_SUBMODEL_ID 0x00 +#define BIOS_REVISION 1 +#define BIOS_CONFIG_TABLE 0xe6f5 + +#ifndef BIOS_BUILD_DATE +# define BIOS_BUILD_DATE "06/23/99" +#endif + + // 1K of base memory used for Extended Bios Data Area (EBDA) + // EBDA is used for PS/2 mouse support, and IDE BIOS, etc. +#define EBDA_SEG 0x9FC0 +#define EBDA_SIZE 1 // In KiB +#define BASE_MEM_IN_K (640 - EBDA_SIZE) + +/* IPL_SIZE bytes at 0x9ff00 are used for the IPL boot table. */ +#define IPL_SEG 0x9ff0 +#define IPL_TABLE_OFFSET 0x0000 +#define IPL_TABLE_ENTRIES 8 +#define IPL_COUNT_OFFSET 0x0080 /* u16: number of valid table entries */ +#define IPL_SEQUENCE_OFFSET 0x0082 /* u16: next boot device */ +#define IPL_BOOTFIRST_OFFSET 0x0084 /* u16: user selected device */ +#define IPL_SIZE 0x86 +#define IPL_TYPE_FLOPPY 0x01 +#define IPL_TYPE_HARDDISK 0x02 +#define IPL_TYPE_CDROM 0x03 +#define IPL_TYPE_BEV 0x80 + +/* Ports */ +#define PORT_DMA_ADDR_2 0x0004 +#define PORT_DMA_CNT_2 0x0005 +#define PORT_DMA1_MASK_REG 0x000a +#define PORT_DMA1_MODE_REG 0x000b +#define PORT_DMA1_CLEAR_FF_REG 0x000c +#define PORT_DMA1_MASTER_CLEAR 0x000d +#define PORT_PIC1_CMD 0x0020 +#define PORT_PIC1_DATA 0x0021 +#define PORT_PIT_COUNTER0 0x0040 +#define PORT_PIT_MODE 0x0043 +#define PORT_PS2_DATA 0x0060 +#define PORT_PS2_CTRLB 0x0061 +#define PORT_PS2_STATUS 0x0064 +#define PORT_CMOS_INDEX 0x0070 +#define PORT_CMOS_DATA 0x0071 +#define PORT_DIAG 0x0080 +#define PORT_DMA_PAGE_2 0x0081 +#define PORT_A20 0x0092 +#define PORT_PIC2_CMD 0x00a0 +#define PORT_PIC2_DATA 0x00a1 +#define PORT_DMA2_MASK_REG 0x00d4 +#define PORT_DMA2_MODE_REG 0x00d6 +#define PORT_DMA2_MASTER_CLEAR 0x00da +#define PORT_ATA2_CMD_BASE 0x0170 +#define PORT_ATA1_CMD_BASE 0x01f0 +#define PORT_FD_DOR 0x03f2 +#define PORT_FD_STATUS 0x03f4 +#define PORT_FD_DATA 0x03f5 + +#define CPUID_MSR (1 << 5) +#define CPUID_APIC (1 << 9) +#define CPUID_MTRR (1 << 12) + +#define APIC_BASE ((uint8_t *)0xfee00000) +#define APIC_ICR_LOW 0x300 +#define APIC_SVR 0x0F0 +#define APIC_ID 0x020 +#define APIC_LVT3 0x370 + +#define APIC_ENABLED 0x0100 + +#define AP_BOOT_ADDR 0x9f000 + +#define SMI_CMD_IO_ADDR 0xb2 + +#define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */ + +#define MSR_MTRRcap 0x000000fe +#define MSR_MTRRfix64K_00000 0x00000250 +#define MSR_MTRRfix16K_80000 0x00000258 +#define MSR_MTRRfix16K_A0000 0x00000259 +#define MSR_MTRRfix4K_C0000 0x00000268 +#define MSR_MTRRfix4K_C8000 0x00000269 +#define MSR_MTRRfix4K_D0000 0x0000026a +#define MSR_MTRRfix4K_D8000 0x0000026b +#define MSR_MTRRfix4K_E0000 0x0000026c +#define MSR_MTRRfix4K_E8000 0x0000026d +#define MSR_MTRRfix4K_F0000 0x0000026e +#define MSR_MTRRfix4K_F8000 0x0000026f +#define MSR_MTRRdefType 0x000002ff + +#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) +#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) + +#define MTRR_MEMTYPE_UC 0 +#define MTRR_MEMTYPE_WC 1 +#define MTRR_MEMTYPE_WT 4 +#define MTRR_MEMTYPE_WP 5 +#define MTRR_MEMTYPE_WB 6 + +#define QEMU_CFG_CTL_PORT 0x510 +#define QEMU_CFG_DATA_PORT 0x511 +#define QEMU_CFG_SIGNATURE 0x00 +#define QEMU_CFG_ID 0x01 +#define QEMU_CFG_UUID 0x02 + +#define PCI_ADDRESS_SPACE_MEM 0x00 +#define PCI_ADDRESS_SPACE_IO 0x01 +#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 + +#define PCI_ROM_SLOT 6 +#define PCI_NUM_REGIONS 7 + +#define PCI_DEVICES_MAX 64 + +#define PCI_VENDOR_ID 0x00 /* 16 bits */ +#define PCI_DEVICE_ID 0x02 /* 16 bits */ +#define PCI_COMMAND 0x04 /* 16 bits */ +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ +#define PCI_CLASS_DEVICE 0x0a /* Device class */ +#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ +#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ +#define PCI_MIN_GNT 0x3e /* 8 bits */ +#define PCI_MAX_LAT 0x3f /* 8 bits */ + +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 +#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 +#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 +#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 +#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 + +#define PCI_VENDOR_ID_IBM 0x1014 +#define PCI_VENDOR_ID_APPLE 0x106b diff --git a/bochs/bios/rombios32.c b/bochs/bios/rombios32.c new file mode 100644 index 00000000..7659e36f --- /dev/null +++ b/bochs/bios/rombios32.c @@ -0,0 +1,2328 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// 32 bit Bochs BIOS init code +// Copyright (C) 2006 Fabrice Bellard +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include +#include + +#include "rombios.h" + +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +#define cpuid(index, eax, ebx, ecx, edx) \ + asm volatile ("cpuid" \ + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \ + : "0" (index)) + +#define wbinvd() asm volatile("wbinvd") + +static inline void outl(int addr, int val) +{ + asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val)); +} + +static inline void outw(int addr, int val) +{ + asm volatile ("outw %w1, %w0" : : "d" (addr), "a" (val)); +} + +static inline void outb(int addr, int val) +{ + asm volatile ("outb %b1, %w0" : : "d" (addr), "a" (val)); +} + +static inline uint32_t inl(int addr) +{ + uint32_t val; + asm volatile ("inl %w1, %0" : "=a" (val) : "d" (addr)); + return val; +} + +static inline uint16_t inw(int addr) +{ + uint16_t val; + asm volatile ("inw %w1, %w0" : "=a" (val) : "d" (addr)); + return val; +} + +static inline uint8_t inb(int addr) +{ + uint8_t val; + asm volatile ("inb %w1, %b0" : "=a" (val) : "d" (addr)); + return val; +} + +static inline void writel(void *addr, uint32_t val) +{ + *(volatile uint32_t *)addr = val; +} + +static inline void writew(void *addr, uint16_t val) +{ + *(volatile uint16_t *)addr = val; +} + +static inline void writeb(void *addr, uint8_t val) +{ + *(volatile uint8_t *)addr = val; +} + +static inline uint32_t readl(const void *addr) +{ + return *(volatile const uint32_t *)addr; +} + +static inline uint16_t readw(const void *addr) +{ + return *(volatile const uint16_t *)addr; +} + +static inline uint8_t readb(const void *addr) +{ + return *(volatile const uint8_t *)addr; +} + +static inline void putch(int c) +{ + outb(INFO_PORT, c); +} + +static uint64_t rdmsr(unsigned index) +{ + unsigned long long ret; + + asm ("rdmsr" : "=A"(ret) : "c"(index)); + return ret; +} + +static void wrmsr(unsigned index, uint64_t val) +{ + asm volatile ("wrmsr" : : "c"(index), "A"(val)); +} + +static inline int isdigit(int c) +{ + return c >= '0' && c <= '9'; +} + +void *memset(void *d1, int val, size_t len) +{ + uint8_t *d = d1; + + while (len--) { + *d++ = val; + } + return d1; +} + +void *memcpy(void *d1, const void *s1, size_t len) +{ + uint8_t *d = d1; + const uint8_t *s = s1; + + while (len--) { + *d++ = *s++; + } + return d1; +} + +void *memmove(void *d1, const void *s1, size_t len) +{ + uint8_t *d = d1; + const uint8_t *s = s1; + + if (d <= s) { + while (len--) { + *d++ = *s++; + } + } else { + d += len; + s += len; + while (len--) { + *--d = *--s; + } + } + return d1; +} + +int memcmp(const void *s1, const void *s2, size_t len) +{ + const int8_t *p1 = s1; + const int8_t *p2 = s2; + + while (len--) { + int r = *p1++ - *p2++; + if(r) + return r; + } + + return 0; +} + +size_t strlen(const char *s) +{ + const char *s1; + for(s1 = s; *s1 != '\0'; s1++); + return s1 - s; +} + +/* from BSD ppp sources */ +int vsnprintf(char *buf, int buflen, const char *fmt, va_list args) +{ + int c, i, n; + int width, prec, fillch; + int base, len, neg; + unsigned long val = 0; + const char *f; + char *str, *buf0; + char num[32]; + static const char hexchars[] = "0123456789abcdef"; + + buf0 = buf; + --buflen; + while (buflen > 0) { + for (f = fmt; *f != '%' && *f != 0; ++f) + ; + if (f > fmt) { + len = f - fmt; + if (len > buflen) + len = buflen; + memcpy(buf, fmt, len); + buf += len; + buflen -= len; + fmt = f; + } + if (*fmt == 0) + break; + c = *++fmt; + width = prec = 0; + fillch = ' '; + if (c == '0') { + fillch = '0'; + c = *++fmt; + } + if (c == '*') { + width = va_arg(args, int); + c = *++fmt; + } else { + while (isdigit(c)) { + width = width * 10 + c - '0'; + c = *++fmt; + } + } + if (c == '.') { + c = *++fmt; + if (c == '*') { + prec = va_arg(args, int); + c = *++fmt; + } else { + while (isdigit(c)) { + prec = prec * 10 + c - '0'; + c = *++fmt; + } + } + } + /* modifiers */ + switch(c) { + case 'l': + c = *++fmt; + break; + default: + break; + } + str = 0; + base = 0; + neg = 0; + ++fmt; + switch (c) { + case 'd': + i = va_arg(args, int); + if (i < 0) { + neg = 1; + val = -i; + } else + val = i; + base = 10; + break; + case 'o': + val = va_arg(args, unsigned int); + base = 8; + break; + case 'x': + case 'X': + val = va_arg(args, unsigned int); + base = 16; + break; + case 'p': + val = (unsigned long) va_arg(args, void *); + base = 16; + neg = 2; + break; + case 's': + str = va_arg(args, char *); + break; + case 'c': + num[0] = va_arg(args, int); + num[1] = 0; + str = num; + break; + default: + *buf++ = '%'; + if (c != '%') + --fmt; /* so %z outputs %z etc. */ + --buflen; + continue; + } + if (base != 0) { + str = num + sizeof(num); + *--str = 0; + while (str > num + neg) { + *--str = hexchars[val % base]; + val = val / base; + if (--prec <= 0 && val == 0) + break; + } + switch (neg) { + case 1: + *--str = '-'; + break; + case 2: + *--str = 'x'; + *--str = '0'; + break; + } + len = num + sizeof(num) - 1 - str; + } else { + len = strlen(str); + if (prec > 0 && len > prec) + len = prec; + } + if (width > 0) { + if (width > buflen) + width = buflen; + if ((n = width - len) > 0) { + buflen -= n; + for (; n > 0; --n) + *buf++ = fillch; + } + } + if (len > buflen) + len = buflen; + memcpy(buf, str, len); + buf += len; + buflen -= len; + } + *buf = 0; + return buf - buf0; +} + +int snprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = vsnprintf(buf, size, fmt, args); + va_end(args); + return i; +} + +void bios_printf(int flags, const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + const char *s; + + if ((flags & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT) + outb(PANIC_PORT2, 0x00); + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + s = buf; + while (*s) + putch(*s++); + va_end(ap); +} + +void delay_ms(int n) +{ + int i, j; + for(i = 0; i < n; i++) { +#ifdef BX_QEMU + volatile int k; + /* approximative ! */ + for(j = 0; j < 1000000; j++) { + k++; + } +#else + { + int r1, r2; + j = 66; + r1 = inb(0x61) & 0x10; + do { + r2 = inb(0x61) & 0x10; + if (r1 != r2) { + j--; + r1 = r2; + } + } while (j > 0); + } +#endif + } +} + +uint16_t smp_cpus; +uint32_t cpuid_signature; +uint32_t cpuid_features; +uint32_t cpuid_ext_features; +unsigned long ram_size; +uint64_t ram_end; +uint8_t bios_uuid[16]; +#ifdef BX_USE_EBDA_TABLES +unsigned long ebda_cur_addr; +#endif +int acpi_enabled; +uint32_t pm_io_base, smb_io_base; +int pm_sci_int; +unsigned long bios_table_cur_addr; +unsigned long bios_table_end_addr; + +void wrmsr_smp(uint32_t index, uint64_t val) +{ + static struct { uint32_t ecx, eax, edx; } *p = (void *)SMP_MSR_ADDR; + + wrmsr(index, val); + p->ecx = index; + p->eax = val; + p->edx = val >> 32; + ++p; + p->ecx = 0; +} + +#ifdef BX_QEMU +int qemu_cfg_port; + +void qemu_cfg_select(int f) +{ + outw(QEMU_CFG_CTL_PORT, f); +} + +int qemu_cfg_port_probe() +{ + char *sig = "QEMU"; + int i; + + qemu_cfg_select(QEMU_CFG_SIGNATURE); + + for (i = 0; i < 4; i++) + if (inb(QEMU_CFG_DATA_PORT) != sig[i]) + return 0; + + return 1; +} + +void qemu_cfg_read(uint8_t *buf, int len) +{ + while (len--) + *(buf++) = inb(QEMU_CFG_DATA_PORT); +} +#endif + +void uuid_probe(void) +{ +#ifdef BX_QEMU + if(qemu_cfg_port) { + qemu_cfg_select(QEMU_CFG_UUID); + qemu_cfg_read(bios_uuid, 16); + return; + } +#endif + memset(bios_uuid, 0, 16); +} + +void cpu_probe(void) +{ + uint32_t eax, ebx, ecx, edx; + cpuid(1, eax, ebx, ecx, edx); + cpuid_signature = eax; + cpuid_features = edx; + cpuid_ext_features = ecx; +} + +static int cmos_readb(int addr) +{ + outb(0x70, addr); + return inb(0x71); +} + +void setup_mtrr(void) +{ + int i, vcnt, fix, wc; + uint32_t mtrr_cap; + union { + uint8_t valb[8]; + uint64_t val; + } u; + + *(uint32_t *)SMP_MSR_ADDR = 0; + + if (!(cpuid_features & CPUID_MTRR)) + return; + + if (!(cpuid_features & CPUID_MSR)) + return; + + mtrr_cap = rdmsr(MSR_MTRRcap); + vcnt = mtrr_cap & 0xff; + fix = mtrr_cap & 0x100; + wc = mtrr_cap & 0x400; + if (!vcnt || !fix) + return; + + u.val = 0; + for (i = 0; i < 8; ++i) + if (ram_size >= 65536 * (i + 1)) + u.valb[i] = 6; + wrmsr_smp(MSR_MTRRfix64K_00000, u.val); + u.val = 0; + for (i = 0; i < 8; ++i) + if (ram_size >= 65536 * 8 + 16384 * (i + 1)) + u.valb[i] = 6; + wrmsr_smp(MSR_MTRRfix16K_80000, u.val); + wrmsr_smp(MSR_MTRRfix16K_A0000, 0); + wrmsr_smp(MSR_MTRRfix4K_C0000, 0); + wrmsr_smp(MSR_MTRRfix4K_C8000, 0); + wrmsr_smp(MSR_MTRRfix4K_D0000, 0); + wrmsr_smp(MSR_MTRRfix4K_D8000, 0); + wrmsr_smp(MSR_MTRRfix4K_E0000, 0); + wrmsr_smp(MSR_MTRRfix4K_E8000, 0); + wrmsr_smp(MSR_MTRRfix4K_F0000, 0); + wrmsr_smp(MSR_MTRRfix4K_F8000, 0); + /* Mark 3-4GB as UC, anything not specified defaults to WB */ + wrmsr_smp(MTRRphysBase_MSR(0), 0xc0000000 | MTRR_MEMTYPE_UC); + /* Make sure no reserved bit set to '1 in MTRRphysMask_MSR */ + wrmsr_smp(MTRRphysMask_MSR(0), (uint32_t)(~(0x40000000 - 1)) | 0x800); + wrmsr_smp(MSR_MTRRdefType, 0xc00 | MTRR_MEMTYPE_WB); +} + +void ram_probe(void) +{ + if (cmos_readb(0x34) | cmos_readb(0x35)) + ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 + + 16 * 1024 * 1024; + else + ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 + + 1 * 1024 * 1024; + BX_INFO("ram_size=0x%08lx\n", ram_size); + + if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d)) + ram_end = (((uint64_t)cmos_readb(0x5b) << 16) | + ((uint64_t)cmos_readb(0x5c) << 24) | + ((uint64_t)cmos_readb(0x5d) << 32)) + (1ull << 32); + else + ram_end = ram_size; + BX_INFO("ram_end=%ldMB\n", ram_end >> 20); +#ifdef BX_USE_EBDA_TABLES + ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x386; + BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); +#endif +} + +/****************************************************/ +/* SMP probe */ + +extern uint8_t smp_ap_boot_code_start; +extern uint8_t smp_ap_boot_code_end; + +/* find the number of CPUs by launching a SIPI to them */ +void smp_probe(void) +{ + uint32_t val, sipi_vector; + + writew(&smp_cpus, 1); + if (cpuid_features & CPUID_APIC) { + + /* enable local APIC */ + val = readl(APIC_BASE + APIC_SVR); + val |= APIC_ENABLED; + writel(APIC_BASE + APIC_SVR, val); + + /* copy AP boot code */ + memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start, + &smp_ap_boot_code_end - &smp_ap_boot_code_start); + + /* broadcast SIPI */ + writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500); + sipi_vector = AP_BOOT_ADDR >> 12; + writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector); + +#ifndef BX_QEMU + delay_ms(10); +#else + while (cmos_readb(0x5f) + 1 != readw(&smp_cpus)) + ; +#endif + } + BX_INFO("Found %d cpu(s)\n", readw(&smp_cpus)); +} + +/****************************************************/ +/* PCI init */ + +typedef struct PCIDevice { + int bus; + int devfn; +} PCIDevice; + +static uint32_t pci_bios_io_addr; +static uint32_t pci_bios_mem_addr; +/* host irqs corresponding to PCI irqs A-D */ +static uint8_t pci_irqs[4] = { 11, 9, 11, 9 }; +static PCIDevice i440_pcidev = {-1, -1}; + +static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val) +{ + outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); + outl(0xcfc, val); +} + +static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val) +{ + outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); + outw(0xcfc + (addr & 2), val); +} + +static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val) +{ + outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); + outb(0xcfc + (addr & 3), val); +} + +static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); + return inl(0xcfc); +} + +static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); + return inw(0xcfc + (addr & 2)); +} + +static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc)); + return inb(0xcfc + (addr & 3)); +} + +static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr) +{ + uint16_t cmd; + uint32_t ofs, old_addr; + + if ( region_num == PCI_ROM_SLOT ) { + ofs = 0x30; + }else{ + ofs = 0x10 + region_num * 4; + } + + old_addr = pci_config_readl(d, ofs); + + pci_config_writel(d, ofs, addr); + BX_INFO("region %d: 0x%08x\n", region_num, addr); + + /* enable memory mappings */ + cmd = pci_config_readw(d, PCI_COMMAND); + if ( region_num == PCI_ROM_SLOT ) + cmd |= 2; + else if (old_addr & PCI_ADDRESS_SPACE_IO) + cmd |= 1; + else + cmd |= 2; + pci_config_writew(d, PCI_COMMAND, cmd); +} + +/* return the global irq number corresponding to a given device irq + pin. We could also use the bus number to have a more precise + mapping. */ +static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) +{ + int slot_addend; + slot_addend = (pci_dev->devfn >> 3) - 1; + return (irq_num + slot_addend) & 3; +} + +static void find_bios_table_area(void) +{ + unsigned long addr; + for(addr = 0xf0000; addr < 0x100000; addr += 16) { + if (*(uint32_t *)addr == 0xaafb4442) { + bios_table_cur_addr = addr + 8; + bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4); + BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n", + bios_table_cur_addr, bios_table_end_addr); + return; + } + } + return; +} + +static void bios_shadow_init(PCIDevice *d) +{ + int v; + + if (bios_table_cur_addr == 0) + return; + + /* remap the BIOS to shadow RAM an keep it read/write while we + are writing tables */ + v = pci_config_readb(d, 0x59); + v &= 0xcf; + pci_config_writeb(d, 0x59, v); + memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000); + v |= 0x30; + pci_config_writeb(d, 0x59, v); + memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000); + + i440_pcidev = *d; +} + +static void bios_lock_shadow_ram(void) +{ + PCIDevice *d = &i440_pcidev; + int v; + + wbinvd(); + v = pci_config_readb(d, 0x59); + v = (v & 0x0f) | (0x10); + pci_config_writeb(d, 0x59, v); +} + +static void pci_bios_init_bridges(PCIDevice *d) +{ + uint16_t vendor_id, device_id; + + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); + device_id = pci_config_readw(d, PCI_DEVICE_ID); + + if (vendor_id == PCI_VENDOR_ID_INTEL && + (device_id == PCI_DEVICE_ID_INTEL_82371SB_0 || + device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) { + int i, irq; + uint8_t elcr[2]; + + /* PIIX3/PIIX4 PCI to ISA bridge */ + + elcr[0] = 0x00; + elcr[1] = 0x00; + for(i = 0; i < 4; i++) { + irq = pci_irqs[i]; + /* set to trigger level */ + elcr[irq >> 3] |= (1 << (irq & 7)); + /* activate irq remapping in PIIX */ + pci_config_writeb(d, 0x60 + i, irq); + } + outb(0x4d0, elcr[0]); + outb(0x4d1, elcr[1]); + BX_INFO("PIIX3/PIIX4 init: elcr=%02x %02x\n", + elcr[0], elcr[1]); + } else if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441) { + /* i440 PCI bridge */ + bios_shadow_init(d); + } +} + +extern uint8_t smm_relocation_start, smm_relocation_end; +extern uint8_t smm_code_start, smm_code_end; + +#ifdef BX_USE_SMM +static void smm_init(PCIDevice *d) +{ + uint32_t value; + + /* check if SMM init is already done */ + value = pci_config_readl(d, 0x58); + if ((value & (1 << 25)) == 0) { + + /* enable the SMM memory window */ + pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x48); + + /* save original memory content */ + memcpy((void *)0xa8000, (void *)0x38000, 0x8000); + + /* copy the SMM relocation code */ + memcpy((void *)0x38000, &smm_relocation_start, + &smm_relocation_end - &smm_relocation_start); + + /* enable SMI generation when writing to the APMC register */ + pci_config_writel(d, 0x58, value | (1 << 25)); + + /* init APM status port */ + outb(0xb3, 0x01); + + /* raise an SMI interrupt */ + outb(0xb2, 0x00); + + /* wait until SMM code executed */ + while (inb(0xb3) != 0x00); + + /* restore original memory content */ + memcpy((void *)0x38000, (void *)0xa8000, 0x8000); + + /* copy the SMM code */ + memcpy((void *)0xa8000, &smm_code_start, + &smm_code_end - &smm_code_start); + wbinvd(); + + /* close the SMM memory window and enable normal SMM */ + pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x08); + } +} +#endif + +static void piix4_pm_enable(PCIDevice *d) +{ + /* PIIX4 Power Management device (for ACPI) */ + pci_config_writel(d, 0x40, PM_IO_BASE | 1); + pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */ + pci_config_writel(d, 0x90, SMB_IO_BASE | 1); + pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */ +#ifdef BX_USE_SMM + smm_init(d); +#endif +} + +static void pci_bios_init_device(PCIDevice *d) +{ + int class; + uint32_t *paddr; + int i, pin, pic_irq, vendor_id, device_id; + + class = pci_config_readw(d, PCI_CLASS_DEVICE); + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); + device_id = pci_config_readw(d, PCI_DEVICE_ID); + BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x class=0x%04x\n", + d->bus, d->devfn, vendor_id, device_id, class); + switch(class) { + case 0x0101: /* Mass storage controller - IDE interface */ + if (vendor_id == PCI_VENDOR_ID_INTEL && + (device_id == PCI_DEVICE_ID_INTEL_82371SB_1 || + device_id == PCI_DEVICE_ID_INTEL_82371AB)) { + /* PIIX3/PIIX4 IDE */ + pci_config_writew(d, 0x40, 0x8000); // enable IDE0 + pci_config_writew(d, 0x42, 0x8000); // enable IDE1 + goto default_map; + } else { + /* IDE: we map it as in ISA mode */ + pci_set_io_region_addr(d, 0, 0x1f0); + pci_set_io_region_addr(d, 1, 0x3f4); + pci_set_io_region_addr(d, 2, 0x170); + pci_set_io_region_addr(d, 3, 0x374); + } + break; + case 0x0800: /* Generic system peripheral - PIC */ + if (vendor_id == PCI_VENDOR_ID_IBM) { + /* IBM */ + if (device_id == 0x0046 || device_id == 0xFFFF) { + /* MPIC & MPIC2 */ + pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000); + } + } + break; + case 0xff00: + if (vendor_id == PCI_VENDOR_ID_APPLE && + (device_id == 0x0017 || device_id == 0x0022)) { + /* macio bridge */ + pci_set_io_region_addr(d, 0, 0x80800000); + } + break; + default: + default_map: + /* default memory mappings */ + for(i = 0; i < PCI_NUM_REGIONS; i++) { + int ofs; + uint32_t val, size ; + + if (i == PCI_ROM_SLOT) { + ofs = 0x30; + pci_config_writel(d, ofs, 0xfffffffe); + } else { + ofs = 0x10 + i * 4; + pci_config_writel(d, ofs, 0xffffffff); + } + val = pci_config_readl(d, ofs); + if (val != 0) { + size = (~(val & ~0xf)) + 1; + if (val & PCI_ADDRESS_SPACE_IO) + paddr = &pci_bios_io_addr; + else + paddr = &pci_bios_mem_addr; + *paddr = (*paddr + size - 1) & ~(size - 1); + pci_set_io_region_addr(d, i, *paddr); + *paddr += size; + } + } + break; + } + + /* map the interrupt */ + pin = pci_config_readb(d, PCI_INTERRUPT_PIN); + if (pin != 0) { + pin = pci_slot_get_pirq(d, pin - 1); + pic_irq = pci_irqs[pin]; + pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq); + } + + if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3) { + /* PIIX4 Power Management device (for ACPI) */ + pm_io_base = PM_IO_BASE; + smb_io_base = SMB_IO_BASE; + // acpi sci is hardwired to 9 + pci_config_writeb(d, PCI_INTERRUPT_LINE, 9); + pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE); + piix4_pm_enable(d); + acpi_enabled = 1; + } +} + +void pci_for_each_device(void (*init_func)(PCIDevice *d)) +{ + PCIDevice d1, *d = &d1; + int bus, devfn; + uint16_t vendor_id, device_id; + + for(bus = 0; bus < 1; bus++) { + for(devfn = 0; devfn < 256; devfn++) { + d->bus = bus; + d->devfn = devfn; + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); + device_id = pci_config_readw(d, PCI_DEVICE_ID); + if (vendor_id != 0xffff || device_id != 0xffff) { + init_func(d); + } + } + } +} + +void pci_bios_init(void) +{ + pci_bios_io_addr = 0xc000; + pci_bios_mem_addr = 0xc0000000; + + pci_for_each_device(pci_bios_init_bridges); + + pci_for_each_device(pci_bios_init_device); +} + +/****************************************************/ +/* Multi Processor table init */ + +static void putb(uint8_t **pp, int val) +{ + uint8_t *q; + q = *pp; + *q++ = val; + *pp = q; +} + +static void putstr(uint8_t **pp, const char *str) +{ + uint8_t *q; + q = *pp; + while (*str) + *q++ = *str++; + *pp = q; +} + +static void putle16(uint8_t **pp, int val) +{ + uint8_t *q; + q = *pp; + *q++ = val; + *q++ = val >> 8; + *pp = q; +} + +static void putle32(uint8_t **pp, int val) +{ + uint8_t *q; + q = *pp; + *q++ = val; + *q++ = val >> 8; + *q++ = val >> 16; + *q++ = val >> 24; + *pp = q; +} + +static int mpf_checksum(const uint8_t *data, int len) +{ + int sum, i; + sum = 0; + for(i = 0; i < len; i++) + sum += data[i]; + return sum & 0xff; +} + +static unsigned long align(unsigned long addr, unsigned long v) +{ + return (addr + v - 1) & ~(v - 1); +} + +static void mptable_init(void) +{ + uint8_t *mp_config_table, *q, *float_pointer_struct; + int ioapic_id, i, len; + int mp_config_table_size; + +#ifdef BX_USE_EBDA_TABLES + if (ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE < 0x100000) { + BX_INFO("Not enough memory for MPC table\n"); + return; + } + mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE); +#else + bios_table_cur_addr = align(bios_table_cur_addr, 16); + mp_config_table = (uint8_t *)bios_table_cur_addr; +#endif + q = mp_config_table; + putstr(&q, "PCMP"); /* "PCMP signature */ + putle16(&q, 0); /* table length (patched later) */ + putb(&q, 4); /* spec rev */ + putb(&q, 0); /* checksum (patched later) */ +#ifdef BX_QEMU + putstr(&q, "QEMUCPU "); /* OEM id */ +#else + putstr(&q, "BOCHSCPU"); +#endif + putstr(&q, "0.1 "); /* vendor id */ + putle32(&q, 0); /* OEM table ptr */ + putle16(&q, 0); /* OEM table size */ + putle16(&q, smp_cpus + 18); /* entry count */ + putle32(&q, 0xfee00000); /* local APIC addr */ + putle16(&q, 0); /* ext table length */ + putb(&q, 0); /* ext table checksum */ + putb(&q, 0); /* reserved */ + + for(i = 0; i < smp_cpus; i++) { + putb(&q, 0); /* entry type = processor */ + putb(&q, i); /* APIC id */ + putb(&q, 0x11); /* local APIC version number */ + if (i == 0) + putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */ + else + putb(&q, 1); /* cpu flags: enabled */ + if (cpuid_signature) { + putle32(&q, cpuid_signature); + putle32(&q, cpuid_features); + } else { + putb(&q, 0); /* cpu signature */ + putb(&q, 6); + putb(&q, 0); + putb(&q, 0); + putle16(&q, 0x201); /* feature flags */ + putle16(&q, 0); + } + putle16(&q, 0); /* reserved */ + putle16(&q, 0); + putle16(&q, 0); + putle16(&q, 0); + } + + /* isa bus */ + putb(&q, 1); /* entry type = bus */ + putb(&q, 0); /* bus ID */ + putstr(&q, "ISA "); + + /* ioapic */ + ioapic_id = smp_cpus; + putb(&q, 2); /* entry type = I/O APIC */ + putb(&q, ioapic_id); /* apic ID */ + putb(&q, 0x11); /* I/O APIC version number */ + putb(&q, 1); /* enable */ + putle32(&q, 0xfec00000); /* I/O APIC addr */ + + /* irqs */ + for(i = 0; i < 16; i++) { +#ifdef BX_QEMU + /* One entry per ioapic input. Input 2 is covered by + irq0->inti2 override (i == 0). irq 2 is unused */ + if (i == 2) + continue; +#endif + putb(&q, 3); /* entry type = I/O interrupt */ + putb(&q, 0); /* interrupt type = vectored interrupt */ + putb(&q, 0); /* flags: po=0, el=0 */ + putb(&q, 0); + putb(&q, 0); /* source bus ID = ISA */ + putb(&q, i); /* source bus IRQ */ + putb(&q, ioapic_id); /* dest I/O APIC ID */ +#ifdef BX_QEMU + putb(&q, i == 0 ? 2 : i); /* dest I/O APIC interrupt in */ +#else + putb(&q, i); /* dest I/O APIC interrupt in */ +#endif + } + /* patch length */ + len = q - mp_config_table; + mp_config_table[4] = len; + mp_config_table[5] = len >> 8; + + mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table); + + mp_config_table_size = q - mp_config_table; + +#ifndef BX_USE_EBDA_TABLES + bios_table_cur_addr += mp_config_table_size; +#endif + + /* floating pointer structure */ +#ifdef BX_USE_EBDA_TABLES + ebda_cur_addr = align(ebda_cur_addr, 16); + float_pointer_struct = (uint8_t *)ebda_cur_addr; +#else + bios_table_cur_addr = align(bios_table_cur_addr, 16); + float_pointer_struct = (uint8_t *)bios_table_cur_addr; +#endif + q = float_pointer_struct; + putstr(&q, "_MP_"); + /* pointer to MP config table */ + putle32(&q, (unsigned long)mp_config_table); + + putb(&q, 1); /* length in 16 byte units */ + putb(&q, 4); /* MP spec revision */ + putb(&q, 0); /* checksum (patched later) */ + putb(&q, 0); /* MP feature byte 1 */ + + putb(&q, 0); + putb(&q, 0); + putb(&q, 0); + putb(&q, 0); + float_pointer_struct[10] = + -mpf_checksum(float_pointer_struct, q - float_pointer_struct); +#ifdef BX_USE_EBDA_TABLES + ebda_cur_addr += (q - float_pointer_struct); +#else + bios_table_cur_addr += (q - float_pointer_struct); +#endif + BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n", + (unsigned long)float_pointer_struct, + (unsigned long)mp_config_table, + mp_config_table_size); +} + +/****************************************************/ +/* ACPI tables init */ + +/* Table structure from Linux kernel (the ACPI tables are under the + BSD license) */ + +/* + * All tables must be byte-packed to match the ACPI specification, since + * the tables are provided by the system BIOS. + */ + +#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \ + uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\ + uint32_t length; /* Length of table, in bytes, including header */\ + uint8_t revision; /* ACPI Specification minor version # */\ + uint8_t checksum; /* To make sum of entire table == 0 */\ + uint8_t oem_id [6]; /* OEM identification */\ + uint8_t oem_table_id [8]; /* OEM table identification */\ + uint32_t oem_revision; /* OEM revision number */\ + uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\ + uint32_t asl_compiler_revision; /* ASL compiler revision number */ + + +struct acpi_table_header /* ACPI common table header */ +{ + ACPI_TABLE_HEADER_DEF +} __attribute__((__packed__)); + +struct rsdp_descriptor /* Root System Descriptor Pointer */ +{ + uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */ + uint8_t checksum; /* To make sum of struct == 0 */ + uint8_t oem_id [6]; /* OEM identification */ + uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */ + uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */ + uint32_t length; /* XSDT Length in bytes including hdr */ + uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */ + uint8_t extended_checksum; /* Checksum of entire table */ + uint8_t reserved [3]; /* Reserved field must be 0 */ +} __attribute__((__packed__)); + +/* + * ACPI 1.0 Root System Description Table (RSDT) + */ +struct rsdt_descriptor_rev1 +{ + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ +#ifdef BX_QEMU + uint32_t table_offset_entry [4]; /* Array of pointers to other */ +#else + uint32_t table_offset_entry [3]; /* Array of pointers to other */ +#endif + /* ACPI tables */ +} __attribute__((__packed__)); + +/* + * ACPI 1.0 Firmware ACPI Control Structure (FACS) + */ +struct facs_descriptor_rev1 +{ + uint8_t signature[4]; /* ACPI Signature */ + uint32_t length; /* Length of structure, in bytes */ + uint32_t hardware_signature; /* Hardware configuration signature */ + uint32_t firmware_waking_vector; /* ACPI OS waking vector */ + uint32_t global_lock; /* Global Lock */ + uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */ + uint32_t reserved1 : 31; /* Must be 0 */ + uint8_t resverved3 [40]; /* Reserved - must be zero */ +} __attribute__((__packed__)); + + +/* + * ACPI 1.0 Fixed ACPI Description Table (FADT) + */ +struct fadt_descriptor_rev1 +{ + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ + uint32_t firmware_ctrl; /* Physical address of FACS */ + uint32_t dsdt; /* Physical address of DSDT */ + uint8_t model; /* System Interrupt Model */ + uint8_t reserved1; /* Reserved */ + uint16_t sci_int; /* System vector of SCI interrupt */ + uint32_t smi_cmd; /* Port address of SMI command port */ + uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */ + uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */ + uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ + uint8_t reserved2; /* Reserved - must be zero */ + uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ + uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ + uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ + uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ + uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ + uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ + uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */ + uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ + uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */ + uint8_t reserved3; /* Reserved */ + uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ + uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ + uint16_t flush_size; /* Size of area read to flush caches */ + uint16_t flush_stride; /* Stride used in flushing caches */ + uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */ + uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */ + uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ + uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ + uint8_t century; /* Index to century in RTC CMOS RAM */ + uint8_t reserved4; /* Reserved */ + uint8_t reserved4a; /* Reserved */ + uint8_t reserved4b; /* Reserved */ +#if 0 + uint32_t wb_invd : 1; /* The wbinvd instruction works properly */ + uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ + uint32_t proc_c1 : 1; /* All processors support C1 state */ + uint32_t plvl2_up : 1; /* C2 state works on MP system */ + uint32_t pwr_button : 1; /* Power button is handled as a generic feature */ + uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */ + uint32_t reserved5 : 23; /* Reserved - must be zero */ +#else + uint32_t flags; +#endif +} __attribute__((__packed__)); + +/* + * MADT values and structures + */ + +/* Values for MADT PCATCompat */ + +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 + + +/* Master MADT */ + +struct multiple_apic_table +{ + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ + uint32_t local_apic_address; /* Physical address of local APIC */ +#if 0 + uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */ + uint32_t reserved1 : 31; +#else + uint32_t flags; +#endif +} __attribute__((__packed__)); + + +/* Values for Type in APIC_HEADER_DEF */ + +#define APIC_PROCESSOR 0 +#define APIC_IO 1 +#define APIC_XRUPT_OVERRIDE 2 +#define APIC_NMI 3 +#define APIC_LOCAL_NMI 4 +#define APIC_ADDRESS_OVERRIDE 5 +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 +#define APIC_XRUPT_SOURCE 8 +#define APIC_RESERVED 9 /* 9 and greater are reserved */ + +/* + * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE) + */ +#define APIC_HEADER_DEF /* Common APIC sub-structure header */\ + uint8_t type; \ + uint8_t length; + +/* Sub-structures for MADT */ + +struct madt_processor_apic +{ + APIC_HEADER_DEF + uint8_t processor_id; /* ACPI processor id */ + uint8_t local_apic_id; /* Processor's local APIC id */ +#if 0 + uint32_t processor_enabled: 1; /* Processor is usable if set */ + uint32_t reserved2 : 31; /* Reserved, must be zero */ +#else + uint32_t flags; +#endif +} __attribute__((__packed__)); + +#ifdef BX_QEMU +/* + * * ACPI 2.0 Generic Address Space definition. + * */ +struct acpi_20_generic_address { + uint8_t address_space_id; + uint8_t register_bit_width; + uint8_t register_bit_offset; + uint8_t reserved; + uint64_t address; +} __attribute__((__packed__)); + +/* + * * HPET Description Table + * */ +struct acpi_20_hpet { + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ + uint32_t timer_block_id; + struct acpi_20_generic_address addr; + uint8_t hpet_number; + uint16_t min_tick; + uint8_t page_protect; +} __attribute__((__packed__)); +#define ACPI_HPET_ADDRESS 0xFED00000UL +#endif + +struct madt_io_apic +{ + APIC_HEADER_DEF + uint8_t io_apic_id; /* I/O APIC ID */ + uint8_t reserved; /* Reserved - must be zero */ + uint32_t address; /* APIC physical address */ + uint32_t interrupt; /* Global system interrupt where INTI + * lines start */ +} __attribute__((__packed__)); + +#ifdef BX_QEMU +struct madt_int_override +{ + APIC_HEADER_DEF + uint8_t bus; /* Identifies ISA Bus */ + uint8_t source; /* Bus-relative interrupt source */ + uint32_t gsi; /* GSI that source will signal */ + uint16_t flags; /* MPS INTI flags */ +} __attribute__((__packed__)); +#endif + +#include "acpi-dsdt.hex" + +static inline uint16_t cpu_to_le16(uint16_t x) +{ + return x; +} + +static inline uint32_t cpu_to_le32(uint32_t x) +{ + return x; +} + +static int acpi_checksum(const uint8_t *data, int len) +{ + int sum, i; + sum = 0; + for(i = 0; i < len; i++) + sum += data[i]; + return (-sum) & 0xff; +} + +static void acpi_build_table_header(struct acpi_table_header *h, + char *sig, int len, uint8_t rev) +{ + memcpy(h->signature, sig, 4); + h->length = cpu_to_le32(len); + h->revision = rev; +#ifdef BX_QEMU + memcpy(h->oem_id, "QEMU ", 6); + memcpy(h->oem_table_id, "QEMU", 4); +#else + memcpy(h->oem_id, "BOCHS ", 6); + memcpy(h->oem_table_id, "BXPC", 4); +#endif + memcpy(h->oem_table_id + 4, sig, 4); + h->oem_revision = cpu_to_le32(1); +#ifdef BX_QEMU + memcpy(h->asl_compiler_id, "QEMU", 4); +#else + memcpy(h->asl_compiler_id, "BXPC", 4); +#endif + h->asl_compiler_revision = cpu_to_le32(1); + h->checksum = acpi_checksum((void *)h, len); +} + +int acpi_build_processor_ssdt(uint8_t *ssdt) +{ + uint8_t *ssdt_ptr = ssdt; + int i, length; + int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus; + + ssdt_ptr[9] = 0; // checksum; + ssdt_ptr += sizeof(struct acpi_table_header); + + // caluculate the length of processor block and scope block excluding PkgLength + length = 0x0d * acpi_cpus + 4; + + // build processor scope header + *(ssdt_ptr++) = 0x10; // ScopeOp + if (length <= 0x3e) { + /* Handle 1-4 CPUs with one byte encoding */ + *(ssdt_ptr++) = length + 1; + } else { + /* Handle 5-314 CPUs with two byte encoding */ + *(ssdt_ptr++) = 0x40 | ((length + 2) & 0xf); + *(ssdt_ptr++) = (length + 2) >> 4; + } + *(ssdt_ptr++) = '_'; // Name + *(ssdt_ptr++) = 'P'; + *(ssdt_ptr++) = 'R'; + *(ssdt_ptr++) = '_'; + + // build object for each processor + for(i=0;i> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa; + else + *(ssdt_ptr++) = 'U'; + *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa; + *(ssdt_ptr++) = i; + *(ssdt_ptr++) = 0x10; // Processor block address + *(ssdt_ptr++) = 0xb0; + *(ssdt_ptr++) = 0; + *(ssdt_ptr++) = 0; + *(ssdt_ptr++) = 6; // Processor block length + } + + acpi_build_table_header((struct acpi_table_header *)ssdt, + "SSDT", ssdt_ptr - ssdt, 1); + + return ssdt_ptr - ssdt; +} + +/* base_addr must be a multiple of 4KB */ +void acpi_bios_init(void) +{ + struct rsdp_descriptor *rsdp; + struct rsdt_descriptor_rev1 *rsdt; + struct fadt_descriptor_rev1 *fadt; + struct facs_descriptor_rev1 *facs; + struct multiple_apic_table *madt; + uint8_t *dsdt, *ssdt; +#ifdef BX_QEMU + struct acpi_20_hpet *hpet; + uint32_t hpet_addr; +#endif + uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr; + uint32_t acpi_tables_size, madt_addr, madt_size; + int i; + + if (ram_size - ACPI_DATA_SIZE < 0x100000) { + BX_INFO("Not enough memory for ACPI tables\n"); + return; + } + + /* reserve memory space for tables */ +#ifdef BX_USE_EBDA_TABLES + ebda_cur_addr = align(ebda_cur_addr, 16); + rsdp = (void *)(ebda_cur_addr); + ebda_cur_addr += sizeof(*rsdp); +#else + bios_table_cur_addr = align(bios_table_cur_addr, 16); + rsdp = (void *)(bios_table_cur_addr); + bios_table_cur_addr += sizeof(*rsdp); +#endif + + addr = base_addr = ram_size - ACPI_DATA_SIZE; + rsdt_addr = addr; + rsdt = (void *)(addr); + addr += sizeof(*rsdt); + + fadt_addr = addr; + fadt = (void *)(addr); + addr += sizeof(*fadt); + + /* XXX: FACS should be in RAM */ + addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */ + facs_addr = addr; + facs = (void *)(addr); + addr += sizeof(*facs); + + dsdt_addr = addr; + dsdt = (void *)(addr); + addr += sizeof(AmlCode); + + ssdt_addr = addr; + ssdt = (void *)(addr); + addr += acpi_build_processor_ssdt(ssdt); + + addr = (addr + 7) & ~7; + madt_addr = addr; + madt_size = sizeof(*madt) + + sizeof(struct madt_processor_apic) * smp_cpus + +#ifdef BX_QEMU + sizeof(struct madt_io_apic) + sizeof(struct madt_int_override); +#else + sizeof(struct madt_io_apic); +#endif + madt = (void *)(addr); + addr += madt_size; + +#ifdef BX_QEMU + addr = (addr + 7) & ~7; + hpet_addr = addr; + hpet = (void *)(addr); + addr += sizeof(*hpet); +#endif + + acpi_tables_size = addr - base_addr; + + BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n", + (unsigned long)rsdp, + (unsigned long)rsdt, acpi_tables_size); + + /* RSDP */ + memset(rsdp, 0, sizeof(*rsdp)); + memcpy(rsdp->signature, "RSD PTR ", 8); +#ifdef BX_QEMU + memcpy(rsdp->oem_id, "QEMU ", 6); +#else + memcpy(rsdp->oem_id, "BOCHS ", 6); +#endif + rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr); + rsdp->checksum = acpi_checksum((void *)rsdp, 20); + + /* RSDT */ + memset(rsdt, 0, sizeof(*rsdt)); + rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr); + rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr); + rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr); +#ifdef BX_QEMU + rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr); +#endif + acpi_build_table_header((struct acpi_table_header *)rsdt, + "RSDT", sizeof(*rsdt), 1); + + /* FADT */ + memset(fadt, 0, sizeof(*fadt)); + fadt->firmware_ctrl = cpu_to_le32(facs_addr); + fadt->dsdt = cpu_to_le32(dsdt_addr); + fadt->model = 1; + fadt->reserved1 = 0; + fadt->sci_int = cpu_to_le16(pm_sci_int); + fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR); + fadt->acpi_enable = 0xf1; + fadt->acpi_disable = 0xf0; + fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base); + fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04); + fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08); + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; + fadt->pm_tmr_len = 4; + fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported + fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported + /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */ + fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6)); + acpi_build_table_header((struct acpi_table_header *)fadt, "FACP", + sizeof(*fadt), 1); + + /* FACS */ + memset(facs, 0, sizeof(*facs)); + memcpy(facs->signature, "FACS", 4); + facs->length = cpu_to_le32(sizeof(*facs)); + BX_INFO("Firmware waking vector %p\n", &facs->firmware_waking_vector); + + /* DSDT */ + memcpy(dsdt, AmlCode, sizeof(AmlCode)); + + /* MADT */ + { + struct madt_processor_apic *apic; + struct madt_io_apic *io_apic; +#ifdef BX_QEMU + struct madt_int_override *int_override; +#endif + + memset(madt, 0, madt_size); + madt->local_apic_address = cpu_to_le32(0xfee00000); + madt->flags = cpu_to_le32(1); + apic = (void *)(madt + 1); + for(i=0;itype = APIC_PROCESSOR; + apic->length = sizeof(*apic); + apic->processor_id = i; + apic->local_apic_id = i; + apic->flags = cpu_to_le32(1); + apic++; + } + io_apic = (void *)apic; + io_apic->type = APIC_IO; + io_apic->length = sizeof(*io_apic); + io_apic->io_apic_id = smp_cpus; + io_apic->address = cpu_to_le32(0xfec00000); + io_apic->interrupt = cpu_to_le32(0); +#ifdef BX_QEMU + io_apic++; + + int_override = (void *)io_apic; + int_override->type = APIC_XRUPT_OVERRIDE; + int_override->length = sizeof(*int_override); + int_override->bus = cpu_to_le32(0); + int_override->source = cpu_to_le32(0); + int_override->gsi = cpu_to_le32(2); + int_override->flags = cpu_to_le32(0); +#endif + + acpi_build_table_header((struct acpi_table_header *)madt, + "APIC", madt_size, 1); + } + +#ifdef BX_QEMU + /* HPET */ + memset(hpet, 0, sizeof(*hpet)); + /* Note timer_block_id value must be kept in sync with value advertised by + * emulated hpet + */ + hpet->timer_block_id = cpu_to_le32(0x8086a201); + hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS); + acpi_build_table_header((struct acpi_table_header *)hpet, + "HPET", sizeof(*hpet), 1); +#endif + +} + +/* SMBIOS entry point -- must be written to a 16-bit aligned address + between 0xf0000 and 0xfffff. + */ +struct smbios_entry_point { + char anchor_string[4]; + uint8_t checksum; + uint8_t length; + uint8_t smbios_major_version; + uint8_t smbios_minor_version; + uint16_t max_structure_size; + uint8_t entry_point_revision; + uint8_t formatted_area[5]; + char intermediate_anchor_string[5]; + uint8_t intermediate_checksum; + uint16_t structure_table_length; + uint32_t structure_table_address; + uint16_t number_of_structures; + uint8_t smbios_bcd_revision; +} __attribute__((__packed__)); + +/* This goes at the beginning of every SMBIOS structure. */ +struct smbios_structure_header { + uint8_t type; + uint8_t length; + uint16_t handle; +} __attribute__((__packed__)); + +/* SMBIOS type 0 - BIOS Information */ +struct smbios_type_0 { + struct smbios_structure_header header; + uint8_t vendor_str; + uint8_t bios_version_str; + uint16_t bios_starting_address_segment; + uint8_t bios_release_date_str; + uint8_t bios_rom_size; + uint8_t bios_characteristics[8]; + uint8_t bios_characteristics_extension_bytes[2]; + uint8_t system_bios_major_release; + uint8_t system_bios_minor_release; + uint8_t embedded_controller_major_release; + uint8_t embedded_controller_minor_release; +} __attribute__((__packed__)); + +/* SMBIOS type 1 - System Information */ +struct smbios_type_1 { + struct smbios_structure_header header; + uint8_t manufacturer_str; + uint8_t product_name_str; + uint8_t version_str; + uint8_t serial_number_str; + uint8_t uuid[16]; + uint8_t wake_up_type; + uint8_t sku_number_str; + uint8_t family_str; +} __attribute__((__packed__)); + +/* SMBIOS type 3 - System Enclosure (v2.3) */ +struct smbios_type_3 { + struct smbios_structure_header header; + uint8_t manufacturer_str; + uint8_t type; + uint8_t version_str; + uint8_t serial_number_str; + uint8_t asset_tag_number_str; + uint8_t boot_up_state; + uint8_t power_supply_state; + uint8_t thermal_state; + uint8_t security_status; + uint32_t oem_defined; + uint8_t height; + uint8_t number_of_power_cords; + uint8_t contained_element_count; + // contained elements follow +} __attribute__((__packed__)); + +/* SMBIOS type 4 - Processor Information (v2.0) */ +struct smbios_type_4 { + struct smbios_structure_header header; + uint8_t socket_designation_str; + uint8_t processor_type; + uint8_t processor_family; + uint8_t processor_manufacturer_str; + uint32_t processor_id[2]; + uint8_t processor_version_str; + uint8_t voltage; + uint16_t external_clock; + uint16_t max_speed; + uint16_t current_speed; + uint8_t status; + uint8_t processor_upgrade; + uint16_t l1_cache_handle; + uint16_t l2_cache_handle; + uint16_t l3_cache_handle; +} __attribute__((__packed__)); + +/* SMBIOS type 16 - Physical Memory Array + * Associated with one type 17 (Memory Device). + */ +struct smbios_type_16 { + struct smbios_structure_header header; + uint8_t location; + uint8_t use; + uint8_t error_correction; + uint32_t maximum_capacity; + uint16_t memory_error_information_handle; + uint16_t number_of_memory_devices; +} __attribute__((__packed__)); + +/* SMBIOS type 17 - Memory Device + * Associated with one type 19 + */ +struct smbios_type_17 { + struct smbios_structure_header header; + uint16_t physical_memory_array_handle; + uint16_t memory_error_information_handle; + uint16_t total_width; + uint16_t data_width; + uint16_t size; + uint8_t form_factor; + uint8_t device_set; + uint8_t device_locator_str; + uint8_t bank_locator_str; + uint8_t memory_type; + uint16_t type_detail; +} __attribute__((__packed__)); + +/* SMBIOS type 19 - Memory Array Mapped Address */ +struct smbios_type_19 { + struct smbios_structure_header header; + uint32_t starting_address; + uint32_t ending_address; + uint16_t memory_array_handle; + uint8_t partition_width; +} __attribute__((__packed__)); + +/* SMBIOS type 20 - Memory Device Mapped Address */ +struct smbios_type_20 { + struct smbios_structure_header header; + uint32_t starting_address; + uint32_t ending_address; + uint16_t memory_device_handle; + uint16_t memory_array_mapped_address_handle; + uint8_t partition_row_position; + uint8_t interleave_position; + uint8_t interleaved_data_depth; +} __attribute__((__packed__)); + +/* SMBIOS type 32 - System Boot Information */ +struct smbios_type_32 { + struct smbios_structure_header header; + uint8_t reserved[6]; + uint8_t boot_status; +} __attribute__((__packed__)); + +/* SMBIOS type 127 -- End-of-table */ +struct smbios_type_127 { + struct smbios_structure_header header; +} __attribute__((__packed__)); + +static void +smbios_entry_point_init(void *start, + uint16_t max_structure_size, + uint16_t structure_table_length, + uint32_t structure_table_address, + uint16_t number_of_structures) +{ + uint8_t sum; + int i; + struct smbios_entry_point *ep = (struct smbios_entry_point *)start; + + memcpy(ep->anchor_string, "_SM_", 4); + ep->length = 0x1f; + ep->smbios_major_version = 2; + ep->smbios_minor_version = 4; + ep->max_structure_size = max_structure_size; + ep->entry_point_revision = 0; + memset(ep->formatted_area, 0, 5); + memcpy(ep->intermediate_anchor_string, "_DMI_", 5); + + ep->structure_table_length = structure_table_length; + ep->structure_table_address = structure_table_address; + ep->number_of_structures = number_of_structures; + ep->smbios_bcd_revision = 0x24; + + ep->checksum = 0; + ep->intermediate_checksum = 0; + + sum = 0; + for (i = 0; i < 0x10; i++) + sum += ((int8_t *)start)[i]; + ep->checksum = -sum; + + sum = 0; + for (i = 0x10; i < ep->length; i++) + sum += ((int8_t *)start)[i]; + ep->intermediate_checksum = -sum; + } + +/* Type 0 -- BIOS Information */ +#define RELEASE_DATE_STR "01/01/2007" +static void * +smbios_type_0_init(void *start) +{ + struct smbios_type_0 *p = (struct smbios_type_0 *)start; + + p->header.type = 0; + p->header.length = sizeof(struct smbios_type_0); + p->header.handle = 0; + + p->vendor_str = 1; + p->bios_version_str = 2; + p->bios_starting_address_segment = 0xe000; + p->bios_release_date_str = 3; + p->bios_rom_size = 1; /* 128 kB */ + + memset(p->bios_characteristics, 0, 8); + p->bios_characteristics[0] |= 1 << 4; /* Bit 4 - ISA is supported */ +#if BX_PCIBIOS + p->bios_characteristics[0] |= 1 << 7; /* Bit 7 - PCI is supported */ +#endif +#if BX_APM + p->bios_characteristics[1] |= 1 << 2; /* Bit 10 - APM is supported */ +#endif + p->bios_characteristics[1] |= 1 << 3; /* Bit 11 - BIOS is Upgradeable (Flash) */ + p->bios_characteristics[1] |= 1 << 4; /* Bit 12 - BIOS shadowing is allowed */ +#if BX_ELTORITO_BOOT && BX_USE_ATADRV + p->bios_characteristics[1] |= 1 << 7; /* Bit 15 - Boot from CD is supported */ + p->bios_characteristics[2] |= 1 << 0; /* Bit 16 - Selectable Boot is supported */ +#endif +#if BX_USE_ATADRV + p->bios_characteristics[2] |= 1 << 3; /* Bit 19 - EDD (Enhanced Disk Drive) Specification is supported */ +#endif +#if BX_SUPPORT_FLOPPY + p->bios_characteristics[2] |= 1 << 6; /* Bit 22 - Int 13h - 5.25" / 360 KB Floppy Services are supported */ + p->bios_characteristics[2] |= 1 << 7; /* Bit 23 - Int 13h - 5.25" / 1.2 MB Floppy Services are supported */ + p->bios_characteristics[3] |= 1 << 0; /* Bit 24 - Int 13h - 3.5" / 720 KB Floppy Services are supported */ + p->bios_characteristics[3] |= 1 << 1; /* Bit 25 - Int 13h - 3.5" / 2.88 MB Floppy Services are supported */ +#endif + p->bios_characteristics[3] |= 1 << 3; /* Bit 27 - Int 9h, 8042 Keyboard services are supported */ + p->bios_characteristics[3] |= 1 << 4; /* Bit 28 - Int 14h, Serial Services are supported */ + p->bios_characteristics[3] |= 1 << 5; /* Bit 29 - Int 17h, Printer Services are supported */ + p->bios_characteristics_extension_bytes[0] = 1; /* Bit 0 - ACPI supported */ + p->bios_characteristics_extension_bytes[1] = 0; + + p->system_bios_major_release = 1; + p->system_bios_minor_release = 0; + p->embedded_controller_major_release = 0xff; + p->embedded_controller_minor_release = 0xff; + + start += sizeof(struct smbios_type_0); + memcpy((char *)start, BX_APPVENDOR, sizeof(BX_APPVENDOR)); + start += sizeof(BX_APPVENDOR); + memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME)); + start += sizeof(BX_APPNAME); + memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR)); + start += sizeof(RELEASE_DATE_STR); + *((uint8_t *)start) = 0; + + return start+1; +} + +/* Type 1 -- System Information */ +static void * +smbios_type_1_init(void *start) +{ + struct smbios_type_1 *p = (struct smbios_type_1 *)start; + p->header.type = 1; + p->header.length = sizeof(struct smbios_type_1); + p->header.handle = 0x100; + + p->manufacturer_str = 0; + p->product_name_str = 0; + p->version_str = 0; + p->serial_number_str = 0; + + memcpy(p->uuid, bios_uuid, 16); + + p->wake_up_type = 0x06; /* power switch */ + p->sku_number_str = 0; + p->family_str = 0; + + start += sizeof(struct smbios_type_1); + *((uint16_t *)start) = 0; + + return start+2; +} + +/* Type 3 -- System Enclosure */ +static void * +smbios_type_3_init(void *start) +{ + struct smbios_type_3 *p = (struct smbios_type_3 *)start; + + p->header.type = 3; + p->header.length = sizeof(struct smbios_type_3); + p->header.handle = 0x300; + + p->manufacturer_str = 0; + p->type = 0x01; /* other */ + p->version_str = 0; + p->serial_number_str = 0; + p->asset_tag_number_str = 0; + p->boot_up_state = 0x03; /* safe */ + p->power_supply_state = 0x03; /* safe */ + p->thermal_state = 0x03; /* safe */ + p->security_status = 0x02; /* unknown */ + p->oem_defined = 0; + p->height = 0; + p->number_of_power_cords = 0; + p->contained_element_count = 0; + + start += sizeof(struct smbios_type_3); + *((uint16_t *)start) = 0; + + return start+2; +} + +/* Type 4 -- Processor Information */ +static void * +smbios_type_4_init(void *start, unsigned int cpu_number) +{ + struct smbios_type_4 *p = (struct smbios_type_4 *)start; + + p->header.type = 4; + p->header.length = sizeof(struct smbios_type_4); + p->header.handle = 0x400 + cpu_number; + + p->socket_designation_str = 1; + p->processor_type = 0x03; /* CPU */ + p->processor_family = 0x01; /* other */ + p->processor_manufacturer_str = 0; + + p->processor_id[0] = cpuid_signature; + p->processor_id[1] = cpuid_features; + + p->processor_version_str = 0; + p->voltage = 0; + p->external_clock = 0; + + p->max_speed = 0; /* unknown */ + p->current_speed = 0; /* unknown */ + + p->status = 0x41; /* socket populated, CPU enabled */ + p->processor_upgrade = 0x01; /* other */ + + p->l1_cache_handle = 0xffff; /* cache information structure not provided */ + p->l2_cache_handle = 0xffff; + p->l3_cache_handle = 0xffff; + + start += sizeof(struct smbios_type_4); + + memcpy((char *)start, "CPU " "\0" "" "\0" "", 7); + ((char *)start)[4] = cpu_number + '0'; + + return start+7; +} + +/* Type 16 -- Physical Memory Array */ +static void * +smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs) +{ + struct smbios_type_16 *p = (struct smbios_type_16*)start; + + p->header.type = 16; + p->header.length = sizeof(struct smbios_type_16); + p->header.handle = 0x1000; + + p->location = 0x03; /* system board or motherboard */ + p->use = 0x03; /* system memory */ + p->error_correction = 0x01; /* other */ + p->maximum_capacity = memsize * 1024; + p->memory_error_information_handle = 0xfffe; /* none provided */ + p->number_of_memory_devices = nr_mem_devs; + + start += sizeof(struct smbios_type_16); + *((uint16_t *)start) = 0; + + return start + 2; +} + +/* Type 17 -- Memory Device */ +static void * +smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance) +{ + struct smbios_type_17 *p = (struct smbios_type_17 *)start; + + p->header.type = 17; + p->header.length = sizeof(struct smbios_type_17); + p->header.handle = 0x1100 + instance; + + p->physical_memory_array_handle = 0x1000; + p->memory_error_information_handle = 0xfffe; /* none provided */ + p->total_width = 64; + p->data_width = 64; +/* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */ + p->size = memory_size_mb; + p->form_factor = 0x09; /* DIMM */ + p->device_set = 0; + p->device_locator_str = 1; + p->bank_locator_str = 0; + p->memory_type = 0x07; /* RAM */ + p->type_detail = 0; + + start += sizeof(struct smbios_type_17); + snprintf(start, 8, "DIMM %d", instance); + start += strlen(start) + 1; + *((uint8_t *)start) = 0; + + return start+1; +} + +/* Type 19 -- Memory Array Mapped Address */ +static void * +smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance) +{ + struct smbios_type_19 *p = (struct smbios_type_19 *)start; + + p->header.type = 19; + p->header.length = sizeof(struct smbios_type_19); + p->header.handle = 0x1300 + instance; + + p->starting_address = instance << 24; + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; + p->memory_array_handle = 0x1000; + p->partition_width = 1; + + start += sizeof(struct smbios_type_19); + *((uint16_t *)start) = 0; + + return start + 2; +} + +/* Type 20 -- Memory Device Mapped Address */ +static void * +smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance) +{ + struct smbios_type_20 *p = (struct smbios_type_20 *)start; + + p->header.type = 20; + p->header.length = sizeof(struct smbios_type_20); + p->header.handle = 0x1400 + instance; + + p->starting_address = instance << 24; + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; + p->memory_device_handle = 0x1100 + instance; + p->memory_array_mapped_address_handle = 0x1300 + instance; + p->partition_row_position = 1; + p->interleave_position = 0; + p->interleaved_data_depth = 0; + + start += sizeof(struct smbios_type_20); + + *((uint16_t *)start) = 0; + return start+2; +} + +/* Type 32 -- System Boot Information */ +static void * +smbios_type_32_init(void *start) +{ + struct smbios_type_32 *p = (struct smbios_type_32 *)start; + + p->header.type = 32; + p->header.length = sizeof(struct smbios_type_32); + p->header.handle = 0x2000; + memset(p->reserved, 0, 6); + p->boot_status = 0; /* no errors detected */ + + start += sizeof(struct smbios_type_32); + *((uint16_t *)start) = 0; + + return start+2; +} + +/* Type 127 -- End of Table */ +static void * +smbios_type_127_init(void *start) +{ + struct smbios_type_127 *p = (struct smbios_type_127 *)start; + + p->header.type = 127; + p->header.length = sizeof(struct smbios_type_127); + p->header.handle = 0x7f00; + + start += sizeof(struct smbios_type_127); + *((uint16_t *)start) = 0; + + return start + 2; +} + +void smbios_init(void) +{ + unsigned cpu_num, nr_structs = 0, max_struct_size = 0; + char *start, *p, *q; + int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) : + (ram_end - (1ull << 32) + ram_size) / (1024 * 1024); + int i, nr_mem_devs; + + bios_table_cur_addr = align(bios_table_cur_addr, 16); + start = (void *)(bios_table_cur_addr); + + p = (char *)start + sizeof(struct smbios_entry_point); + +#define add_struct(fn) do { \ + q = (fn); \ + nr_structs++; \ + if ((q - p) > max_struct_size) \ + max_struct_size = q - p; \ + p = q; \ +} while (0) + + add_struct(smbios_type_0_init(p)); + add_struct(smbios_type_1_init(p)); + add_struct(smbios_type_3_init(p)); + for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++) + add_struct(smbios_type_4_init(p, cpu_num)); + + /* Each 'memory device' covers up to 16GB of address space. */ + nr_mem_devs = (memsize + 0x3fff) >> 14; + add_struct(smbios_type_16_init(p, memsize, nr_mem_devs)); + for ( i = 0; i < nr_mem_devs; i++ ) + { + uint32_t dev_memsize = ((i == (nr_mem_devs - 1)) + ? (((memsize - 1) & 0x3fff) + 1) : 0x4000); + add_struct(smbios_type_17_init(p, dev_memsize, i)); + add_struct(smbios_type_19_init(p, dev_memsize, i)); + add_struct(smbios_type_20_init(p, dev_memsize, i)); + } + + add_struct(smbios_type_32_init(p)); + add_struct(smbios_type_127_init(p)); + +#undef add_struct + + smbios_entry_point_init( + start, max_struct_size, + (p - (char *)start) - sizeof(struct smbios_entry_point), + (uint32_t)(start + sizeof(struct smbios_entry_point)), + nr_structs); + + bios_table_cur_addr += (p - (char *)start); + + BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start); +} + +static uint32_t find_resume_vector(void) +{ + unsigned long addr, start, end; + +#ifdef BX_USE_EBDA_TABLES + start = align(ebda_cur_addr, 16); + end = 0xa000 << 4; +#else + if (bios_table_cur_addr == 0) + return 0; + start = align(bios_table_cur_addr, 16); + end = bios_table_end_addr; +#endif + + for (addr = start; addr < end; addr += 16) { + if (!memcmp((void*)addr, "RSD PTR ", 8)) { + struct rsdp_descriptor *rsdp = (void*)addr; + struct rsdt_descriptor_rev1 *rsdt = (void*)rsdp->rsdt_physical_address; + struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[0]; + struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; + return facs->firmware_waking_vector; + } + } + + return 0; +} + +static void find_440fx(PCIDevice *d) +{ + uint16_t vendor_id, device_id; + + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); + device_id = pci_config_readw(d, PCI_DEVICE_ID); + + if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441) + i440_pcidev = *d; +} + +static void reinit_piix4_pm(PCIDevice *d) +{ + uint16_t vendor_id, device_id; + + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); + device_id = pci_config_readw(d, PCI_DEVICE_ID); + + if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3) + piix4_pm_enable(d); +} + +void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag) +{ + BX_INFO("Starting rombios32\n"); + BX_INFO("Shutdown flag %x\n", *shutdown_flag); + +#ifdef BX_QEMU + qemu_cfg_port = qemu_cfg_port_probe(); +#endif + + ram_probe(); + + cpu_probe(); + + setup_mtrr(); + + smp_probe(); + + find_bios_table_area(); + + if (*shutdown_flag == 0xfe) { + /* redirect bios read access to RAM */ + pci_for_each_device(find_440fx); + bios_lock_shadow_ram(); /* bios is already copied */ + *s3_resume_vector = find_resume_vector(); + if (!*s3_resume_vector) { + BX_INFO("This is S3 resume but wakeup vector is NULL\n"); + } else { + BX_INFO("S3 resume vector %p\n", *s3_resume_vector); + pci_for_each_device(reinit_piix4_pm); + } + return; + } + + pci_bios_init(); + +#ifndef BX_USE_EBDA_TABLES + if (bios_table_cur_addr != 0 && i440_pcidev.bus != -1) { + + mptable_init(); + + uuid_probe(); + + smbios_init(); + + if (acpi_enabled) + acpi_bios_init(); + + bios_lock_shadow_ram(); + + } +#else + mptable_init(); + + if (bios_table_cur_addr != 0 && i440_pcidev.bus != -1) { + + uuid_probe(); + + smbios_init(); + } + + if (acpi_enabled) + acpi_bios_init(); + + BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); + if (ebda_cur_addr > 0xA0000) + BX_PANIC("ebda_cur_addr overflow!\n"); +#endif + BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr); + if (bios_table_cur_addr > bios_table_end_addr) + BX_PANIC("bios_table_end_addr overflow!\n"); +} diff --git a/bochs/bios/rombios32.ld b/bochs/bios/rombios32.ld new file mode 100644 index 00000000..ff765c8b --- /dev/null +++ b/bochs/bios/rombios32.ld @@ -0,0 +1,17 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start); +SECTIONS +{ + . = 0x000e0000; + .text : { *(.text) } + .rodata : { *(.rodata*) } + _end = . ; + .data 0x700 : AT (_end) { __data_start = .; *(.data); __data_end = .;} + .bss : { __bss_start = .; *(.bss) *(COMMON); __bss_end = .;} + /DISCARD/ : { *(.stab) + *(.stabstr) + *(.comment) + *(.note) + } +} diff --git a/bochs/bios/rombios32start.S b/bochs/bios/rombios32start.S new file mode 100644 index 00000000..65dd0eb3 --- /dev/null +++ b/bochs/bios/rombios32start.S @@ -0,0 +1,119 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// 32 bit Bochs BIOS init code +// Copyright (C) 2006 Fabrice Bellard +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include "rombios.h" + +.globl _start +.globl smp_ap_boot_code_start +.globl smp_ap_boot_code_end +.global smm_relocation_start +.global smm_relocation_end +.global smm_code_start +.global smm_code_end + +_start: + /* clear bss section */ + xor %eax, %eax + mov $__bss_start, %edi + mov $__bss_end, %ecx + sub %edi, %ecx + rep stosb + + /* copy data section */ + mov $_end, %esi + mov $__data_start, %edi + mov $__data_end, %ecx + sub %edi, %ecx + rep movsb + + jmp rombios32_init + + .code16 +smp_ap_boot_code_start: + cli + xor %ax, %ax + mov %ax, %ds + + mov $SMP_MSR_ADDR, %ebx +11: + mov 0(%ebx), %ecx + test %ecx, %ecx + jz 12f + mov 4(%ebx), %eax + mov 8(%ebx), %edx + wrmsr + add $12, %ebx + jmp 11b +12: + + lock incw smp_cpus +1: + hlt + jmp 1b +smp_ap_boot_code_end: + +/* code to relocate SMBASE to 0xa0000 */ +smm_relocation_start: + mov $0x38000 + 0x7efc, %ebx + addr32 mov (%ebx), %al /* revision ID to see if x86_64 or x86 */ + cmp $0x64, %al + je 1f + mov $0x38000 + 0x7ef8, %ebx + jmp 2f +1: + mov $0x38000 + 0x7f00, %ebx +2: + movl $0xa0000, %eax + addr32 movl %eax, (%ebx) + /* indicate to the BIOS that the SMM code was executed */ + mov $0x00, %al + movw $0xb3, %dx + outb %al, %dx + rsm +smm_relocation_end: + +/* minimal SMM code to enable or disable ACPI */ +smm_code_start: + movw $0xb2, %dx + inb %dx, %al + cmp $0xf0, %al + jne 1f + + /* ACPI disable */ + mov $PM_IO_BASE + 0x04, %dx /* PMCNTRL */ + inw %dx, %ax + andw $~1, %ax + outw %ax, %dx + + jmp 2f + +1: + cmp $0xf1, %al + jne 2f + + /* ACPI enable */ + mov $PM_IO_BASE + 0x04, %dx /* PMCNTRL */ + inw %dx, %ax + orw $1, %ax + outw %ax, %dx + +2: + rsm +smm_code_end: diff --git a/bochs/bios/usage.cc b/bochs/bios/usage.cc new file mode 100644 index 00000000..a99248a6 --- /dev/null +++ b/bochs/bios/usage.cc @@ -0,0 +1,99 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001 MandrakeSoft S.A. +// +// MandrakeSoft S.A. +// 43, rue d'Aboukir +// 75002 Paris - France +// http://www.linux-mandrake.com/ +// http://www.mandrakesoft.com/ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#include +#include +#include +#include +#include +#include + + +unsigned char bios[65536]; + + int +main(int argc, char *argv[]) +{ + int bios_file; + FILE * org_file; + unsigned org, last_org, offset; + int retval; + unsigned int to_read, index; + double elements, ratio; + + if (argc !=3 ) { + fprintf(stderr, "Usage: usage bios-file org-file\n"); + exit(1); + } + + bios_file = open(argv[1], O_RDONLY); + org_file = fopen(argv[2], "r"); + + if ( (bios_file<0) | (org_file==NULL) ) { + fprintf(stderr, "problems opening files.\n"); + exit(1); + } + + printf("files opened OK\n"); + + to_read = 65536; + index = 0; + while (to_read > 0) { + retval = read(bios_file, &bios[index], to_read); + if (retval <= 0) { + fprintf(stderr, "problem reading bios file\n"); + exit(1); + } + to_read -= retval; + index += retval; + } + printf("bios file read in OK\n"); + + last_org = 0; + + while (1) { + retval = fscanf(org_file, "0x%x\n", &org); + if (retval <= 0) break; + printf("%04x .. %04x ", last_org, org-1); + for (offset=org-1; offset>last_org; offset--) { + if (bios[offset] != 0) break; + } + if (offset > last_org) { + elements = (1.0 + double(offset) - double(last_org)); + } + else { + if (bios[last_org] == 0) + elements = 0.0; + else + elements = 1.0; + } + + ratio = elements / (double(org) - double(last_org)); + ratio *= 100.0; + printf("%6.2lf\n", ratio); + last_org = org; + } +} diff --git a/bochs/bochs.h b/bochs/bochs.h new file mode 100644 index 00000000..72a69d2f --- /dev/null +++ b/bochs/bochs.h @@ -0,0 +1,626 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2010 The Bochs Project +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA + +// +// bochs.h is the master header file for all C++ code. It includes all +// the system header files needed by bochs, and also includes all the bochs +// C++ header files. Because bochs.h and the files that it includes has +// structure and class definitions, it cannot be called from C code. +// + +#ifndef BX_BOCHS_H +# define BX_BOCHS_H 1 + +#include "config.h" /* generated by configure script from config.h.in */ + +#include "../core/SAL/bochs/failbochs.hpp" + +#ifndef __QNXNTO__ +extern "C" { +#endif + +#ifdef WIN32 +// In a win32 compile (including cygwin), windows.h is required for several +// files in gui and iodev. It is important to include it here in a header +// file so that WIN32-specific data types can be used in fields of classes. +#include +#endif + +#include +#include +#include +#if defined(__sun__) +#undef EAX +#undef ECX +#undef EDX +#undef EBX +#undef ESP +#undef EBP +#undef ESI +#undef EDI +#undef EIP +#undef CS +#undef DS +#undef ES +#undef SS +#undef FS +#undef GS +#endif +#include +#include + +#ifndef WIN32 +# include +#else +# include +#endif +#include +#if BX_WITH_MACOS +# include +# include +# include +# include +#elif BX_WITH_CARBON +# include +# include +# include /* for MAXPATHLEN */ +# include +# include +#else +# ifndef WIN32 +# include +# endif +# include +# include +#endif +#include +#include +#include +#include +#ifdef macintosh +# define SuperDrive "[fd:]" +#endif + +#ifndef __QNXNTO__ +} +#endif + +#include "osdep.h" /* platform dependent includes and defines */ +#include "bx_debug/debug.h" +#include "bxversion.h" + +#include "gui/siminterface.h" + +// BX_SHARE_PATH should be defined by the makefile. If not, give it +// a value of NULL to avoid compile problems. +#ifndef BX_SHARE_PATH +#define BX_SHARE_PATH NULL +#endif + +// prototypes +int bx_begin_simulation(int argc, char *argv[]); +void bx_stop_simulation(); +char *bx_find_bochsrc(void); +int bx_parse_cmdline(int arg, int argc, char *argv[]); +int bx_read_configuration(const char *rcfile); +int bx_write_configuration(const char *rcfile, int overwrite); +void bx_reset_options(void); +Bit32u crc32(const Bit8u *buf, int len); +// for param-tree testing only +void print_tree(bx_param_c *node, int level = 0); + +// +// some macros to interface the CPU and memory to external environment +// so that these functions can be redirected to the debugger when +// needed. +// + +#define BXRS_PARAM_SPECIAL(parent, name, maxvalue, save_handler, restore_handler) \ +{ \ + bx_param_num_c *param = new bx_param_num_c(parent, #name, "", "", 0, maxvalue, 0); \ + param->set_base(BASE_HEX); \ + param->set_sr_handlers(this, save_handler, restore_handler); \ +} + +#define BXRS_PARAM_SPECIAL64(parent, name, save_handler, restore_handler) \ + BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT64U, save_handler, restore_handler) +#define BXRS_PARAM_SPECIAL32(parent, name, save_handler, restore_handler) \ + BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT32U, save_handler, restore_handler) +#define BXRS_PARAM_SPECIAL16(parent, name, save_handler, restore_handler) \ + BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT16U, save_handler, restore_handler) +#define BXRS_PARAM_SPECIAL8(parent, name, save_handler, restore_handler) \ + BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT8U, save_handler, restore_handler) + +#define BXRS_HEX_PARAM_SIMPLE32(parent, name) \ + new bx_shadow_num_c(parent, #name, (Bit32u*)&(name), BASE_HEX) +#define BXRS_HEX_PARAM_SIMPLE64(parent, name) \ + new bx_shadow_num_c(parent, #name, (Bit64u*)&(name), BASE_HEX) + +#define BXRS_HEX_PARAM_SIMPLE(parent, name) \ + new bx_shadow_num_c(parent, #name, &(name), BASE_HEX) +#define BXRS_HEX_PARAM_FIELD(parent, name, field) \ + new bx_shadow_num_c(parent, #name, &(field), BASE_HEX) + +#define BXRS_DEC_PARAM_SIMPLE(parent, name) \ + new bx_shadow_num_c(parent, #name, &(name), BASE_DEC) +#define BXRS_DEC_PARAM_FIELD(parent, name, field) \ + new bx_shadow_num_c(parent, #name, &(field), BASE_DEC) + +#define BXRS_PARAM_BOOL(parent, name, field) \ + new bx_shadow_bool_c(parent, #name, (bx_bool*)(&(field))) + +// =-=-=-=-=-=-=- Normal optimized use -=-=-=-=-=-=-=-=-=-=-=-=-=-= +// some pc_systems functions just redirect to the IO devices so optimize +// by eliminating call here +// +// #define BX_INP(addr, len) bx_pc_system.inp(addr, len) +// #define BX_OUTP(addr, val, len) bx_pc_system.outp(addr, val, len) +#define BX_INP(addr, len) bx_devices.inp(addr, len) +#define BX_OUTP(addr, val, len) bx_devices.outp(addr, val, len) +#define BX_TICK1() bx_pc_system.tick1() +#define BX_TICKN(n) bx_pc_system.tickn(n) +#define BX_INTR bx_pc_system.INTR +#define BX_SET_INTR(b) bx_pc_system.set_INTR(b) +#define BX_CPU_C bx_cpu_c +#define BX_MEM_C bx_mem_c +#define BX_HRQ (bx_pc_system.HRQ) + +#if BX_SUPPORT_SMP +#define BX_CPU(x) (bx_cpu_array[x]) +#else +#define BX_CPU(x) (&bx_cpu) +#endif + +#define BX_MEM(x) (&bx_mem) + +#define BX_SET_ENABLE_A20(enabled) bx_pc_system.set_enable_a20(enabled) +#define BX_GET_ENABLE_A20() bx_pc_system.get_enable_a20() + +#if BX_SUPPORT_A20 +# define A20ADDR(x) ((bx_phy_address)(x) & bx_pc_system.a20_mask) +#else +# define A20ADDR(x) ((bx_phy_address)(x)) +#endif + +#if BX_SUPPORT_SMP +# define BX_TICK1_IF_SINGLE_PROCESSOR() \ + if (BX_SMP_PROCESSORS == 1) BX_TICK1() +# define BX_TICKN_IF_SINGLE_PROCESSOR(n) \ + if (BX_SMP_PROCESSORS == 1) BX_TICKN(n) +#else +# define BX_TICK1_IF_SINGLE_PROCESSOR() BX_TICK1() +# define BX_TICKN_IF_SINGLE_PROCESSOR(n) BX_TICKN(n) +#endif + +// you can't use static member functions on the CPU, if there are going +// to be 2 cpus. Check this early on. +#if BX_SUPPORT_SMP +# if BX_USE_CPU_SMF +# error For SMP simulation, BX_USE_CPU_SMF must be 0. +# endif +#endif + +// +// Ways for the the external environment to report back information +// to the debugger. +// + +#if BX_DEBUGGER +# define BX_DBG_ASYNC_INTR bx_guard.async.irq +# define BX_DBG_ASYNC_DMA bx_guard.async.dma + +# define BX_DBG_DMA_REPORT(addr, len, what, val) \ + if (bx_guard.report.dma) bx_dbg_dma_report(addr, len, what, val) +# define BX_DBG_IAC_REPORT(vector, irq) \ + if (bx_guard.report.irq) bx_dbg_iac_report(vector, irq) +# define BX_DBG_A20_REPORT(val) \ + if (bx_guard.report.a20) bx_dbg_a20_report(val) +# define BX_DBG_IO_REPORT(port, size, op, val) \ + if (bx_guard.report.io) bx_dbg_io_report(port, size, op, val) +# define BX_DBG_LIN_MEMORY_ACCESS(cpu, lin, phy, len, pl, rw, data) \ + bx_dbg_lin_memory_access(cpu, lin, phy, len, pl, rw, data) +# define BX_DBG_PHY_MEMORY_ACCESS(cpu, phy, len, rw, data) \ + bx_dbg_phy_memory_access(cpu, phy, len, rw, data) +#else // #if BX_DEBUGGER +// debugger not compiled in, use empty stubs +# define BX_DBG_ASYNC_INTR 1 +# define BX_DBG_ASYNC_DMA 1 +# define BX_DBG_DMA_REPORT(addr, len, what, val) /* empty */ +# define BX_DBG_IAC_REPORT(vector, irq) /* empty */ +# define BX_DBG_A20_REPORT(val) /* empty */ +# define BX_DBG_IO_REPORT(port, size, op, val) /* empty */ +# define BX_DBG_LIN_MEMORY_ACCESS(cpu, lin, phy, len, pl, rw, data) /* empty */ +# define BX_DBG_PHY_MEMORY_ACCESS(cpu, phy, len, rw, data) /* empty */ +#endif // #if BX_DEBUGGER + +#define MAGIC_LOGNUM 0x12345678 + +typedef class BOCHSAPI logfunctions +{ + char *prefix; +// values of onoff: 0=ignore, 1=report, 2=ask, 3=fatal +#define ACT_IGNORE 0 +#define ACT_REPORT 1 +#define ACT_ASK 2 +#define ACT_FATAL 3 +#define N_ACT 4 + int onoff[N_LOGLEV]; + class iofunctions *logio; + // default log actions for all devices, declared and initialized + // in logio.cc. + BOCHSAPI_CYGONLY static int default_onoff[N_LOGLEV]; +public: + logfunctions(void); + logfunctions(class iofunctions *); + ~logfunctions(void); + + void info(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); + void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); + void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); + void pass(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); + void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3); + void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status); + void ask (int level, const char *prefix, const char *fmt, va_list ap); + void put(const char *); + void setio(class iofunctions *); + void setonoff(int loglev, int value) { + assert (loglev >= 0 && loglev < N_LOGLEV); + onoff[loglev] = value; + } + char *getprefix () { return prefix; } + int getonoff(int level) { + assert (level>=0 && level= 0 && loglev < N_LOGLEV); + assert (action >= 0 && action < N_ACT); + default_onoff[loglev] = action; + } + static int get_default_action (int loglev) { + assert (loglev >= 0 && loglev < N_LOGLEV); + return default_onoff[loglev]; + } +} logfunc_t; + +#define BX_LOGPREFIX_SIZE 51 + +class BOCHSAPI iofunctions { + int magic; + char logprefix[BX_LOGPREFIX_SIZE]; + FILE *logfd; + class logfunctions *log; + void init(void); + void flush(void); + +// Log Class types +public: + iofunctions(void); + iofunctions(FILE *); + iofunctions(int); + iofunctions(const char *); + ~iofunctions(void); + + void out(int level, const char *pre, const char *fmt, va_list ap); + + void init_log(const char *fn); + void init_log(int fd); + void init_log(FILE *fs); + void exit_log(); + void set_log_prefix(const char *prefix); + int get_n_logfns() { return n_logfn; } + logfunc_t *get_logfn(int index) { return logfn_list[index]; } + void add_logfn(logfunc_t *fn); + void remove_logfn(logfunc_t *fn); + void set_log_action(int loglevel, int action); + const char *getlevel(int i); + char *getaction(int i); + +protected: + int n_logfn; +#define MAX_LOGFNS 512 + logfunc_t *logfn_list[MAX_LOGFNS]; + const char *logfn; +}; + +typedef class BOCHSAPI iofunctions iofunc_t; + +#define SAFE_GET_IOFUNC() \ + ((io==NULL)? (io=new iofunc_t("/dev/stderr")) : io) +#define SAFE_GET_GENLOG() \ + ((genlog==NULL)? (genlog=new logfunc_t(SAFE_GET_IOFUNC())) : genlog) + +#if BX_NO_LOGGING + +#define BX_INFO(x) +#define BX_DEBUG(x) +#define BX_ERROR(x) +#define BX_PANIC(x) (LOG_THIS panic) x +#define BX_PASS(x) (LOG_THIS pass) x + +#define BX_ASSERT(x) + +#else + +#define BX_INFO(x) (LOG_THIS info) x +#define BX_DEBUG(x) (LOG_THIS ldebug) x +#define BX_ERROR(x) (LOG_THIS error) x +#define BX_PANIC(x) (LOG_THIS panic) x +#define BX_PASS(x) (LOG_THIS pass) x + +#if BX_ASSERT_ENABLE + #define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%d\n", #x, __FILE__, __LINE__));} while (0) +#else + #define BX_ASSERT(x) +#endif + +#endif + +BOCHSAPI extern iofunc_t *io; +BOCHSAPI extern logfunc_t *genlog; + +#ifndef UNUSED +# define UNUSED(x) ((void)x) +#endif + +#if BX_SUPPORT_X86_64 +#define FMT_ADDRX FMT_ADDRX64 +#else +#define FMT_ADDRX FMT_ADDRX32 +#endif + +#if BX_PHY_ADDRESS_LONG + #define FMT_PHY_ADDRX FMT_ADDRX64 +#else + #define FMT_PHY_ADDRX FMT_ADDRX32 +#endif + +#define FMT_LIN_ADDRX FMT_ADDRX + +#if BX_GDBSTUB +// defines for GDB stub +void bx_gdbstub_init(void); +void bx_gdbstub_break(void); +int bx_gdbstub_check(unsigned int eip); +#define GDBSTUB_STOP_NO_REASON (0xac0) + +#if BX_SUPPORT_SMP +#error GDB stub was written for single processor support. If multiprocessor support is added, then we can remove this check. +// The big problem is knowing which CPU gdb is referring to. In other words, +// what should we put for "n" in BX_CPU(n)->dbg_xlate_linear2phy() and +// BX_CPU(n)->dword.eip, etc. +#endif +#endif + +typedef struct { + bx_bool interrupts; + bx_bool exceptions; + bx_bool debugger; + bx_bool print_timestamps; +#if BX_DEBUGGER + bx_bool magic_break_enabled; +#endif +#if BX_GDBSTUB + bx_bool gdbstub_enabled; +#endif +#if BX_SUPPORT_APIC + bx_bool apic; +#endif +#if BX_DEBUG_LINUX + bx_bool linux_syscall; +#endif + void* record_io; +} bx_debug_t; + +void CDECL bx_signal_handler(int signum); +int bx_atexit(void); +BOCHSAPI extern bx_debug_t bx_dbg; + +// determinted by XAPIC option +BOCHSAPI extern Bit32u apic_id_mask; + +// memory access type (read/write/execute/rw) +#define BX_READ 0 +#define BX_WRITE 1 +#define BX_EXECUTE 2 +#define BX_RW 3 + +// to be used in concatenation with BX_READ/BX_WRITE/BX_EXECUTE/BX_RW +#define BX_PDPTR0_ACCESS 0x010 +#define BX_PDPTR1_ACCESS 0x020 +#define BX_PDPTR2_ACCESS 0x030 +#define BX_PDPTR3_ACCESS 0x040 +#define BX_PTE_ACCESS 0x050 +#define BX_PDE_ACCESS 0x060 +#define BX_PDPTE_ACCESS 0x070 +#define BX_PML4E_ACCESS 0x080 +#define BX_EPT_PTE_ACCESS 0x090 +#define BX_EPT_PDE_ACCESS 0x0a0 +#define BX_EPT_PDPTE_ACCESS 0x0b0 +#define BX_EPT_PML4E_ACCESS 0x0c0 +#define BX_VMCS_ACCESS 0x0d0 +#define BX_VMX_MSR_BITMAP_ACCESS 0x0e0 +#define BX_VMX_IO_BITMAP_ACCESS 0x0f0 +#define BX_VMX_LOAD_MSR_ACCESS 0x100 +#define BX_VMX_STORE_MSR_ACCESS 0x110 +#define BX_VMX_VTPR_ACCESS 0x120 +#define BX_SMRAM_ACCESS 0x130 + +// types of reset +#define BX_RESET_SOFTWARE 10 +#define BX_RESET_HARDWARE 11 + +#include "memory/memory.h" +#include "pc_system.h" +#include "plugin.h" +#include "gui/gui.h" + +/* --- EXTERNS --- */ + +#if BX_GUI_SIGHANDLER +extern bx_bool bx_gui_sighandler; +#endif + +// This value controls how often each I/O device's periodic() method +// gets called. The timer is set up in iodev/devices.cc. +#define BX_IODEV_HANDLER_PERIOD 100 // microseconds +//#define BX_IODEV_HANDLER_PERIOD 10 // microseconds + +#define BX_PATHNAME_LEN 512 + +#define BX_KBD_XT_TYPE 0 +#define BX_KBD_AT_TYPE 1 +#define BX_KBD_MF_TYPE 2 + +#define BX_N_OPTROM_IMAGES 4 +#define BX_N_OPTRAM_IMAGES 4 +#define BX_N_SERIAL_PORTS 4 +#define BX_N_PARALLEL_PORTS 2 +#define BX_N_USB_UHCI_PORTS 2 +#define BX_N_USB_OHCI_PORTS 2 +#define BX_N_USB_HUB_PORTS 8 +#define BX_N_PCI_SLOTS 5 +#define BX_N_USER_PLUGINS 8 + +void bx_center_print(FILE *file, const char *line, unsigned maxwidth); + +#include "instrument.h" + +// These are some convenience macros which abstract out accesses between +// a variable in native byte ordering to/from guest (x86) memory, which is +// always in little endian format. You must deal with alignment (if your +// system cares) and endian rearranging. Don't assume anything. You could +// put some platform specific asm() statements here, to make use of native +// instructions to help perform these operations more efficiently than C++. + + +#ifdef BX_LITTLE_ENDIAN + +#define WriteHostWordToLittleEndian(hostPtr, nativeVar16) \ + *((Bit16u*)(hostPtr)) = (nativeVar16) +#define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) \ + *((Bit32u*)(hostPtr)) = (nativeVar32) +#define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) \ + *((Bit64u*)(hostPtr)) = (nativeVar64) + +#define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) \ + (nativeVar16) = *((Bit16u*)(hostPtr)) +#define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) \ + (nativeVar32) = *((Bit32u*)(hostPtr)) +#define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) \ + (nativeVar64) = *((Bit64u*)(hostPtr)) + +#define CopyHostWordLittleEndian(hostAddrDst, hostAddrSrc) \ + (* (Bit16u *)(hostAddrDst)) = (* (Bit16u *)(hostAddrSrc)); +#define CopyHostDWordLittleEndian(hostAddrDst, hostAddrSrc) \ + (* (Bit32u *)(hostAddrDst)) = (* (Bit32u *)(hostAddrSrc)); +#define CopyHostQWordLittleEndian(hostAddrDst, hostAddrSrc) \ + (* (Bit64u *)(hostAddrDst)) = (* (Bit64u *)(hostAddrSrc)); + +#else + +#define WriteHostWordToLittleEndian(hostPtr, nativeVar16) { \ + ((Bit8u *)(hostPtr))[0] = (Bit8u) (nativeVar16); \ + ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar16)>>8); \ +} +#define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) { \ + ((Bit8u *)(hostPtr))[0] = (Bit8u) (nativeVar32); \ + ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar32)>>8); \ + ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar32)>>16); \ + ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar32)>>24); \ +} +#define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) { \ + ((Bit8u *)(hostPtr))[0] = (Bit8u) (nativeVar64); \ + ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar64)>>8); \ + ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar64)>>16); \ + ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar64)>>24); \ + ((Bit8u *)(hostPtr))[4] = (Bit8u) ((nativeVar64)>>32); \ + ((Bit8u *)(hostPtr))[5] = (Bit8u) ((nativeVar64)>>40); \ + ((Bit8u *)(hostPtr))[6] = (Bit8u) ((nativeVar64)>>48); \ + ((Bit8u *)(hostPtr))[7] = (Bit8u) ((nativeVar64)>>56); \ +} + +#define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) { \ + (nativeVar16) = ((Bit16u) ((Bit8u *)(hostPtr))[0]) | \ + (((Bit16u) ((Bit8u *)(hostPtr))[1])<<8) ; \ +} +#define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) { \ + (nativeVar32) = ((Bit32u) ((Bit8u *)(hostPtr))[0]) | \ + (((Bit32u) ((Bit8u *)(hostPtr))[1])<<8) | \ + (((Bit32u) ((Bit8u *)(hostPtr))[2])<<16) | \ + (((Bit32u) ((Bit8u *)(hostPtr))[3])<<24); \ +} +#define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) { \ + (nativeVar64) = ((Bit64u) ((Bit8u *)(hostPtr))[0]) | \ + (((Bit64u) ((Bit8u *)(hostPtr))[1])<<8) | \ + (((Bit64u) ((Bit8u *)(hostPtr))[2])<<16) | \ + (((Bit64u) ((Bit8u *)(hostPtr))[3])<<24) | \ + (((Bit64u) ((Bit8u *)(hostPtr))[4])<<32) | \ + (((Bit64u) ((Bit8u *)(hostPtr))[5])<<40) | \ + (((Bit64u) ((Bit8u *)(hostPtr))[6])<<48) | \ + (((Bit64u) ((Bit8u *)(hostPtr))[7])<<56); \ +} + +#define CopyHostWordLittleEndian(hostAddrDst, hostAddrSrc) { \ + ((Bit8u *)(hostAddrDst))[0] = ((Bit8u *)(hostAddrSrc))[0]; \ + ((Bit8u *)(hostAddrDst))[1] = ((Bit8u *)(hostAddrSrc))[1]; \ +} +#define CopyHostDWordLittleEndian(hostAddrDst, hostAddrSrc) { \ + ((Bit8u *)(hostAddrDst))[0] = ((Bit8u *)(hostAddrSrc))[0]; \ + ((Bit8u *)(hostAddrDst))[1] = ((Bit8u *)(hostAddrSrc))[1]; \ + ((Bit8u *)(hostAddrDst))[2] = ((Bit8u *)(hostAddrSrc))[2]; \ + ((Bit8u *)(hostAddrDst))[3] = ((Bit8u *)(hostAddrSrc))[3]; \ +} +#define CopyHostQWordLittleEndian(hostAddrDst, hostAddrSrc) { \ + ((Bit8u *)(hostAddrDst))[0] = ((Bit8u *)(hostAddrSrc))[0]; \ + ((Bit8u *)(hostAddrDst))[1] = ((Bit8u *)(hostAddrSrc))[1]; \ + ((Bit8u *)(hostAddrDst))[2] = ((Bit8u *)(hostAddrSrc))[2]; \ + ((Bit8u *)(hostAddrDst))[3] = ((Bit8u *)(hostAddrSrc))[3]; \ + ((Bit8u *)(hostAddrDst))[4] = ((Bit8u *)(hostAddrSrc))[4]; \ + ((Bit8u *)(hostAddrDst))[5] = ((Bit8u *)(hostAddrSrc))[5]; \ + ((Bit8u *)(hostAddrDst))[6] = ((Bit8u *)(hostAddrSrc))[6]; \ + ((Bit8u *)(hostAddrDst))[7] = ((Bit8u *)(hostAddrSrc))[7]; \ +} + +#endif + +BX_CPP_INLINE Bit32u bx_bswap32(Bit32u val32) +{ + Bit32u b0 = val32 & 0xff; val32 >>= 8; + Bit32u b1 = val32 & 0xff; val32 >>= 8; + Bit32u b2 = val32 & 0xff; val32 >>= 8; + Bit32u b3 = val32; + return (b0<<24) | (b1<<16) | (b2<<8) | b3; +} + +BX_CPP_INLINE Bit64u bx_bswap64(Bit64u val64) +{ + Bit64u b0 = val64 & 0xff; val64 >>= 8; + Bit64u b1 = val64 & 0xff; val64 >>= 8; + Bit64u b2 = val64 & 0xff; val64 >>= 8; + Bit64u b3 = val64 & 0xff; val64 >>= 8; + Bit64u b4 = val64 & 0xff; val64 >>= 8; + Bit64u b5 = val64 & 0xff; val64 >>= 8; + Bit64u b6 = val64 & 0xff; val64 >>= 8; + Bit64u b7 = val64; + return (b0<<56) | (b1<<48) | (b2<<40) | (b3<<32) | (b4<<24) | (b5<<16) | (b6<<8) | b7; +} + +#endif /* BX_BOCHS_H */ diff --git a/bochs/bochsrc-multiple-ne2k b/bochs/bochsrc-multiple-ne2k new file mode 100644 index 00000000..a7526f05 --- /dev/null +++ b/bochs/bochsrc-multiple-ne2k @@ -0,0 +1,57 @@ +# configuration file generated by Bochs +plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, pci_ide=1, acpi=1, ioapic=1 +config_interface: textconfig +display_library: x +memory: host=32, guest=32 +romimage: file="/usr/share/bochs/BIOS-bochs-latest" +vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" +boot: cdrom +floppy_bootsig_check: disabled=0 +floppya: type=1_44, 1_44="a.img", status=inserted, write_protected=0 +# no floppyb +ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata2: enabled=0 +ata3: enabled=0 +ata0-slave: type=cdrom, path=fli4l.iso, status=inserted +parport1: enabled=1, file="" +parport2: enabled=0 +com1: enabled=1, mode=null, dev="" +com2: enabled=0 +com3: enabled=0 +com4: enabled=0 +usb_uhci: enabled=0 +usb_ohci: enabled=0 +i440fxsupport: enabled=1 +vga_update_interval: 50000 +vga: extension=vbe +cpu: count=1, ips=4000000, reset_on_triple_fault=1, ignore_bad_msrs=1 +cpuid: cpuid_limit_winnt=0, mmx=1, sse=sse2, xapic=1, sep=1, aes=0, xsave=0, movbe=0 +cpuid: stepping=3, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " +print_timestamps: enabled=0 +# no gdb stub +port_e9_hack: enabled=0 +text_snapshot_check: enabled=0 +private_colormap: enabled=0 +clock: sync=none, time0=local +# no cmosimage +ne2k: card=0, enabled=1, ioaddr=0x320, irq=10, mac=fe:fd:00:00:00:02, ethmod=tuntap, ethdev=/dev/net/tun:tap0, script=none +ne2k: card=1, enabled=0, ioaddr=0x320, irq=7, mac=fe:fd:00:00:00:01, ethmod=null, ethdev=xl0, script=none +ne2k: card=2, enabled=0 +ne2k: card=3, enabled=0 +pnic: enabled=0 +sb16: enabled=0 +# no loader +log: - +logprefix: %t%e%d +panic: action=ask +error: action=report +info: action=report +debug: action=ignore +pass: action=fatal +keyboard_type: mf +keyboard_serial_delay: 250 +keyboard_paste_delay: 100000 +keyboard_mapping: enabled=0, map= +user_shortcut: keys=none +mouse: enabled=0, type=ps2, toggle=ctrl+mbutton diff --git a/bochs/build/batch-build.perl b/bochs/build/batch-build.perl new file mode 100755 index 00000000..7d66e021 --- /dev/null +++ b/bochs/build/batch-build.perl @@ -0,0 +1,320 @@ +#!/usr/bin/perl +##################################################################### +# $Id$ +##################################################################### +# +# Batch build tool for multiple configurations +# +# switches: +# - show output vs. send it all to nohup. --nohup +# - serial or parallel. --parallel +# +# no args: serial, display output +# --nohup: serial, output to nohup.out. (Need summary.) +# --nohup --parallel: parallel, output to nohup.out +# --parallel: parallel, spawn xterm for each +# + +sub usage { + print <$name/build.sh"); + print BUILD <$name/xterm-init.sh"); + print XTI <, Mon, 17 Sep 2001 14:40:30 -0700 diff --git a/bochs/build/debian/changelog b/bochs/build/debian/changelog new file mode 100644 index 00000000..a7fadbf5 --- /dev/null +++ b/bochs/build/debian/changelog @@ -0,0 +1,65 @@ +bochs (1.3-1) unstable; urgency=low + + * Update for 1.3 + + -- Rob Lemley Mon, 10 Dec 2001 15:16:18 -0800 + +bochs (1.3pre1-1) unstable; urgency=low + + * Update for 1.3pre1 + + -- Rob Lemley Wed, 28 Nov 2001 16:47:25 -0800 + +bochs (1.2.1cvs20011128-1) unstable; urgency=low + + * Update from cvs + * Package now installs in /usr like a good package should + + -- Rob Lemley Wed, 28 Nov 2001 16:39:35 -0800 + +bochs (1.2.1cvs20010917-1) unstable; urgency=low + + * Added files to docs + * Run mkfontdir after installation to update the font + * Added some documentation RE common errors to the README.Debian file + + -- Rob Lemley Mon, 17 Sep 2001 16:09:50 -0700 + +bochs (1.2.1-2) unstable; urgency=low + + * Added bochs-dlx stuff. This may be separated out into its own + package at some point + + -- Rob Lemley Tue, 12 Jun 2001 19:47:05 -0700 + +bochs (1.2.1-1) unstable; urgency=low + + * New upstream release. + + -- Rob Lemley Tue, 12 Jun 2001 17:57:51 -0700 + +bochs (1.2-3) unstable; urgency=low + + * Moved debian dir to build dir + * Fixed rules file to work with potato + + -- Rob Lemley Mon, 11 Jun 2001 21:33:06 -0700 + +bochs (1.2-2) unstable; urgency=low + + * Backed out changes to Makefile.in to keep in sync with upstream + * Modified rules to install temp files in proper place for package build + * Added hack to rules file to put symlinks in right places + + -- Rob Lemley Mon, 11 Jun 2001 09:48:21 -0700 + +bochs (1.2-1) unstable; urgency=low + + * Initial Release. + * Adjusted Makefike.in to fix $DESTDIR problems + + -- Rob Lemley Tue, 5 Jun 2001 21:08:30 -0700 + +Local variables: +mode: debian-changelog +End: diff --git a/bochs/build/debian/conffiles.ex b/bochs/build/debian/conffiles.ex new file mode 100644 index 00000000..e423055b --- /dev/null +++ b/bochs/build/debian/conffiles.ex @@ -0,0 +1,7 @@ +# +# If you want to use this conffile, remove all comments and put files that +# you want dpkg to process here using their absolute pathnames. +# See section 9.1 of the packaging manual. +# +# for example: +# /etc/bochs/bochs.conf diff --git a/bochs/build/debian/control b/bochs/build/debian/control new file mode 100644 index 00000000..15188e19 --- /dev/null +++ b/bochs/build/debian/control @@ -0,0 +1,17 @@ +Source: bochs +Section: unknown +Priority: optional +Maintainer: Rob Lemley +Build-Depends: debhelper (>> 3.0.0) +Standards-Version: 3.5.2 + +Package: bochs +Architecture: any +Depends: ${shlibs:Depends} +Description: IA-32 Emulator Project + Bochs is a highly portable open source IA-32 (x86) PC emulator written in C++, + that runs on most popular platforms. It includes emulation of the Intel x86 + CPU, common I/O devices, and a custom BIOS. Currently, bochs can be compiled + to emulate a 386, 486 or Pentium CPU. Bochs is capable of running most + Operating Systems inside the emulation including Linux, Windows 95, DOS, + and recently Windows NT 4. diff --git a/bochs/build/debian/copyright b/bochs/build/debian/copyright new file mode 100644 index 00000000..b2eae880 --- /dev/null +++ b/bochs/build/debian/copyright @@ -0,0 +1,10 @@ +This package was debianized by Rob Lemley on +Tue, 5 Jun 2001 21:08:30 -0700. + +It was downloaded from http://bochs.sourceforge.net + +Upstream Author(s): + +Copyright: + + diff --git a/bochs/build/debian/cron.d.ex b/bochs/build/debian/cron.d.ex new file mode 100644 index 00000000..a2b15665 --- /dev/null +++ b/bochs/build/debian/cron.d.ex @@ -0,0 +1,4 @@ +# +# Regular cron jobs for the bochs package +# +0 4 * * * root bochs_maintenance diff --git a/bochs/build/debian/dirs b/bochs/build/debian/dirs new file mode 100644 index 00000000..e69de29b diff --git a/bochs/build/debian/docs b/bochs/build/debian/docs new file mode 100644 index 00000000..a3867b1b --- /dev/null +++ b/bochs/build/debian/docs @@ -0,0 +1,6 @@ +README +TESTFORM.txt +macintosh.txt +win32.txt +COPYING +CHANGES diff --git a/bochs/build/debian/emacsen-install.ex b/bochs/build/debian/emacsen-install.ex new file mode 100644 index 00000000..2f45077e --- /dev/null +++ b/bochs/build/debian/emacsen-install.ex @@ -0,0 +1,45 @@ +#! /bin/sh -e +# /usr/lib/emacsen-common/packages/install/bochs + +# Written by Jim Van Zandt , borrowing heavily +# from the install scripts for gettext by Santiago Vila +# and octave by Dirk Eddelbuettel . + +FLAVOR=$1 +PACKAGE=bochs + +if [ ${FLAVOR} = emacs ]; then exit 0; fi + +echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR} + +#FLAVORTEST=`echo $FLAVOR | cut -c-6` +#if [ ${FLAVORTEST} = xemacs ] ; then +# SITEFLAG="-no-site-file" +#else +# SITEFLAG="--no-site-file" +#fi +FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile" + +ELDIR=/usr/share/emacs/site-lisp/${PACKAGE} +ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE} + +# Install-info-altdir does not actually exist. +# Maybe somebody will write it. +if test -x /usr/sbin/install-info-altdir; then + echo install/${PACKAGE}: install Info links for ${FLAVOR} + install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/info/${PACKAGE}.info.gz +fi + +install -m 755 -d ${ELCDIR} +cd ${ELDIR} +FILES=`echo *.el` +cp ${FILES} ${ELCDIR} +cd ${ELCDIR} + +cat << EOF > path.el +(setq load-path (cons "." load-path) byte-compile-warnings nil) +EOF +${FLAVOR} ${FLAGS} ${FILES} +rm -f *.el path.el + +exit 0 diff --git a/bochs/build/debian/emacsen-remove.ex b/bochs/build/debian/emacsen-remove.ex new file mode 100644 index 00000000..c5adf3d2 --- /dev/null +++ b/bochs/build/debian/emacsen-remove.ex @@ -0,0 +1,15 @@ +#!/bin/sh -e +# /usr/lib/emacsen-common/packages/remove/bochs + +FLAVOR=$1 +PACKAGE=bochs + +if [ ${FLAVOR} != emacs ]; then + if test -x /usr/sbin/install-info-altdir; then + echo remove/${PACKAGE}: removing Info links for ${FLAVOR} + install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/info/bochs.info.gz + fi + + echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR} + rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE} +fi diff --git a/bochs/build/debian/emacsen-startup.ex b/bochs/build/debian/emacsen-startup.ex new file mode 100644 index 00000000..c4f40c8d --- /dev/null +++ b/bochs/build/debian/emacsen-startup.ex @@ -0,0 +1,18 @@ +;; -*-emacs-lisp-*- +;; +;; Emacs startup file for the Debian GNU/Linux bochs package +;; +;; Originally contributed by Nils Naumann +;; Modified by Dirk Eddelbuettel +;; Adapted for dh-make by Jim Van Zandt + +;; The bochs package follows the Debian/GNU Linux 'emacsen' policy and +;; byte-compiles its elisp files for each 'emacs flavor' (emacs19, +;; xemacs19, emacs20, xemacs20...). The compiled code is then +;; installed in a subdirectory of the respective site-lisp directory. +;; We have to add this to the load-path: +(setq load-path (cons (concat "/usr/share/" + (symbol-name flavor) + "/site-lisp/bochs") load-path)) + + diff --git a/bochs/build/debian/ex.doc-base.package b/bochs/build/debian/ex.doc-base.package new file mode 100644 index 00000000..57418f4c --- /dev/null +++ b/bochs/build/debian/ex.doc-base.package @@ -0,0 +1,22 @@ +Document: bochs +Title: Debian bochs Manual +Author: +Abstract: This manual describes what bochs is + and how it can be used to + manage online manuals on Debian systems. +Section: unknown + +Format: debiandoc-sgml +Files: /usr/share/doc/bochs/bochs.sgml.gz + +Format: postscript +Files: /usr/share/doc/bochs/bochs.ps.gz + +Format: text +Files: /usr/share/doc/bochs/bochs.text.gz + +Format: HTML +Index: /usr/share/doc/bochs/html/index.html +Files: /usr/share/doc/bochs/html/*.html + + diff --git a/bochs/build/debian/init.d.ex b/bochs/build/debian/init.d.ex new file mode 100644 index 00000000..c07ac82a --- /dev/null +++ b/bochs/build/debian/init.d.ex @@ -0,0 +1,70 @@ +#! /bin/sh +# +# skeleton example file to build /etc/init.d/ scripts. +# This file should be used to construct scripts for /etc/init.d. +# +# Written by Miquel van Smoorenburg . +# Modified for Debian GNU/Linux +# by Ian Murdock . +# +# Version: @(#)skeleton 1.8 03-Mar-1998 miquels@cistron.nl +# +# This file was automatically customized by dh-make on Tue, 5 Jun 2001 21:08:30 -0700 + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/bochs +NAME=bochs +DESC=bochs + +test -f $DAEMON || exit 0 + +set -e + +case "$1" in + start) + echo -n "Starting $DESC: " + start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ + --exec $DAEMON + echo "$NAME." + ;; + stop) + echo -n "Stopping $DESC: " + start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ + --exec $DAEMON + echo "$NAME." + ;; + #reload) + # + # If the daemon can reload its config files on the fly + # for example by sending it SIGHUP, do it here. + # + # If the daemon responds to changes in its config file + # directly anyway, make this a do-nothing entry. + # + # echo "Reloading $DESC configuration files." + # start-stop-daemon --stop --signal 1 --quiet --pidfile \ + # /var/run/$NAME.pid --exec $DAEMON + #;; + restart|force-reload) + # + # If the "reload" option is implemented, move the "force-reload" + # option to the "reload" entry above. If not, "force-reload" is + # just the same as "restart". + # + echo -n "Restarting $DESC: " + start-stop-daemon --stop --quiet --pidfile \ + /var/run/$NAME.pid --exec $DAEMON + sleep 1 + start-stop-daemon --start --quiet --pidfile \ + /var/run/$NAME.pid --exec $DAEMON + echo "$NAME." + ;; + *) + N=/etc/init.d/$NAME + # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $N {start|stop|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/bochs/build/debian/manpage.1.ex b/bochs/build/debian/manpage.1.ex new file mode 100644 index 00000000..9e58cafb --- /dev/null +++ b/bochs/build/debian/manpage.1.ex @@ -0,0 +1,60 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH BOCHS SECTION "June 5, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +bochs \- program to do something +.SH SYNOPSIS +.B bochs +.RI [ options ] " files" ... +.br +.B bar +.RI [ options ] " files" ... +.SH DESCRIPTION +This manual page documents briefly the +.B bochs +and +.B bar +commands. +This manual page was written for the Debian GNU/Linux distribution +because the original program does not have a manual page. +Instead, it has documentation in the GNU Info format; see below. +.PP +.\" TeX users may be more comfortable with the \fB\fP and +.\" \fI\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBbochs\fP is a program that... +.SH OPTIONS +These programs follow the usual GNU command line syntax, with long +options starting with two dashes (`-'). +A summary of options is included below. +For a complete description, see the Info files. +.TP +.B \-h, \-\-help +Show summary of options. +.TP +.B \-v, \-\-version +Show version of program. +.SH SEE ALSO +.BR bar (1), +.BR baz (1). +.br +The programs are documented fully by +.IR "The Rise and Fall of a Fooish Bar" , +available via the Info system. +.SH AUTHOR +This manual page was written by Rob Lemley , +for the Debian GNU/Linux system (but may be used by others). diff --git a/bochs/build/debian/manpage.sgml.ex b/bochs/build/debian/manpage.sgml.ex new file mode 100644 index 00000000..d22983ef --- /dev/null +++ b/bochs/build/debian/manpage.sgml.ex @@ -0,0 +1,143 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + --> + + + FIRSTNAME"> + SURNAME"> + + June 5, 2001"> + + SECTION"> + rjlemley@calypsoblue.org"> + + BOCHS"> + + + Debian GNU/Linux"> + GNU"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2001 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + &dhpackage; + + program to do something + + + + &dhpackage; + + + + + + + + DESCRIPTION + + This manual page documents briefly the + &dhpackage; and bar + commands. + + This manual page was written for the &debian; distribution + because the original program does not have a manual page. + Instead, it has documentation in the &gnu; + Info format; see below. + + &dhpackage; is a program that... + + + + OPTIONS + + These programs follow the usual GNU command line syntax, + with long options starting with two dashes (`-'). A summary of + options is included below. For a complete description, see the + Info files. + + + + + + + + Show summary of options. + + + + + + + + Show version of program. + + + + + + SEE ALSO + + bar (1), baz (1). + + The programs are documented fully by The Rise and + Fall of a Fooish Bar available via the + Info system. + + + AUTHOR + + This manual page was written by &dhusername; &dhemail; for + the &debian; system (but may be used by others). Permission is + granted to copy, distribute and/or modify this document under + the terms of the GNU Free Documentation + License, Version 1.1 or any later version published by the Free + Software Foundation; with no Invariant Sections, no Front-Cover + Texts and no Back-Cover Texts. + + +
+ + diff --git a/bochs/build/debian/menu.ex b/bochs/build/debian/menu.ex new file mode 100644 index 00000000..8a50db74 --- /dev/null +++ b/bochs/build/debian/menu.ex @@ -0,0 +1,2 @@ +?package(bochs):needs=X11|text|vc|wm section=Apps/see-menu-manual\ + title="bochs" command="/usr/bin/bochs" diff --git a/bochs/build/debian/postinst b/bochs/build/debian/postinst new file mode 100644 index 00000000..2f0c295c --- /dev/null +++ b/bochs/build/debian/postinst @@ -0,0 +1,48 @@ +#! /bin/sh +# postinst script for bochs +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + mkfontdir /usr/lib/X11/fonts/misc + + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/bochs/build/debian/postinst.ex b/bochs/build/debian/postinst.ex new file mode 100644 index 00000000..1d1134f9 --- /dev/null +++ b/bochs/build/debian/postinst.ex @@ -0,0 +1,47 @@ +#! /bin/sh +# postinst script for bochs +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/bochs/build/debian/postrm.ex b/bochs/build/debian/postrm.ex new file mode 100644 index 00000000..41c0aa61 --- /dev/null +++ b/bochs/build/debian/postrm.ex @@ -0,0 +1,36 @@ +#! /bin/sh +# postrm script for bochs +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `purge' +# * `upgrade' +# * `failed-upgrade' +# * `abort-install' +# * `abort-install' +# * `abort-upgrade' +# * `disappear' overwrit>r> +# for details, see /usr/share/doc/packaging-manual/ + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + + + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 0 + +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + + diff --git a/bochs/build/debian/preinst.ex b/bochs/build/debian/preinst.ex new file mode 100644 index 00000000..9b013229 --- /dev/null +++ b/bochs/build/debian/preinst.ex @@ -0,0 +1,42 @@ +#! /bin/sh +# preinst script for bochs +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' +# +# For details see /usr/share/doc/packaging-manual/ + +case "$1" in + install|upgrade) +# if [ "$1" = "upgrade" ] +# then +# start-stop-daemon --stop --quiet --oknodo \ +# --pidfile /var/run/bochs.pid \ +# --exec /usr/sbin/bochs 2>/dev/null || true +# fi + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/bochs/build/debian/prerm.ex b/bochs/build/debian/prerm.ex new file mode 100644 index 00000000..0b32b482 --- /dev/null +++ b/bochs/build/debian/prerm.ex @@ -0,0 +1,37 @@ +#! /bin/sh +# prerm script for bochs +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `upgrade' +# * `failed-upgrade' +# * `remove' `in-favour' +# * `deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ + +case "$1" in + remove|upgrade|deconfigure) +# install-info --quiet --remove /usr/info/bochs.info.gz + ;; + failed-upgrade) + ;; + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/bochs/build/debian/rules b/bochs/build/debian/rules new file mode 100755 index 00000000..41350732 --- /dev/null +++ b/bochs/build/debian/rules @@ -0,0 +1,90 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatability version to use. +export DH_COMPAT=2 + +configure: configure-stamp +configure-stamp: + ln -snf build/debian debian + dh_testdir + # Add here commands to configure the package. + pwd + export CONFIGURE_ARGS="--prefix=/usr"; ./.conf.linux + + touch configure-stamp + +build: configure-stamp build-stamp +build-stamp: + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #/usr/bin/docbook-to-man debian/bochs.sgml > bochs.1 + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) dist-clean + + dh_clean + + rm -f debian + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/bochs. + $(MAKE) unpack_dlx # with normal prefix so that dlxlinux + # bochsrc.txt file gets right pathnames + $(MAKE) install install_dlx prefix=$(CURDIR)/debian/bochs/usr + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit + dh_installcron + dh_installmanpages + dh_installinfo +# dh_undocumented + dh_installchangelogs CHANGES + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_makeshlibs + dh_installdeb +# dh_perl + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/bochs/build/debian/watch.ex b/bochs/build/debian/watch.ex new file mode 100644 index 00000000..b3e039f5 --- /dev/null +++ b/bochs/build/debian/watch.ex @@ -0,0 +1,5 @@ +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# Site Directory Pattern Version Script +sunsite.unc.edu /pub/Linux/Incoming bochs-(.*)\.tar\.gz debian uupdate diff --git a/bochs/build/linux/README.linux-binary b/bochs/build/linux/README.linux-binary new file mode 100644 index 00000000..e69de29b diff --git a/bochs/build/linux/bochs-dlx.in b/bochs/build/linux/bochs-dlx.in new file mode 100755 index 00000000..2f3a4dde --- /dev/null +++ b/bochs/build/linux/bochs-dlx.in @@ -0,0 +1,118 @@ +#!/bin/sh +BOCHS=@prefix@/bin/bochs +DLXINST=@prefix@/share/bochs/dlxlinux +GZIP=@GZIP@ +if [ ! -z $1 ]; then + DLXPATH=$1 +else + DLXPATH=$HOME/.bochsdlx +fi +CONFFILE=$HOME/.bochsdlx/bochsconf + +makedlxdir() { + echo + echo --------------------------------------------------------------- + echo To run the DLX Linux demo, I need to create a directory called + echo $DLXPATH, and copy some configuration files + echo and a 10 megabyte disk image into the directory. + echo --------------------------------------------------------------- + ok='unknown' + while test $ok = 'unknown'; do + echo Is that okay? [y/n] + read j + case $j in + y*) ok=1 ;; + n*) ok=0 ;; + esac + done + if test $ok != 1; then + echo Aborting + exit 1 + fi + #echo DEBUG: Creating $HOME/.bochsdlx/bochsrc + echo DLXPATH=$DLXPATH > $CONFFILE + . $CONFFILE + for file in bochsrc.txt readme.txt testform.txt; do + if [ ! -f $DLXPATH/$file ]; then + echo Copying $DLXINST/$file '->' $DLXPATH/. + cp $DLXINST/$file $DLXPATH/. + else + echo "ERROR: $file already exists in $DLXPATH. Remove it to replace." + fi; + done + if [ ! -f $DLXPATH/hd10meg.img ]; then + echo Uncompressing $DLXINST/hd10meg.img.gz '->' $DLXPATH/hd10meg.img + $GZIP -dc $DLXINST/hd10meg.img.gz > $DLXPATH/hd10meg.img + else + echo "ERROR: hd10meg.img already exists in $DLXPATH. Remove it to replace." + fi +} + +echo --------------------------------------------------------------- +echo " DLX Linux Demo, for Bochs x86 Emulator" +echo --------------------------------------------------------------- + +echo -n "Checking for bochs binary..." +if test ! -x $BOCHS; then + echo FAILED + echo ERROR: I could not find bochs in $BOCHS + exit 1 +fi +echo ok +echo -n "Checking for DLX linux directory..." +if test ! -d $DLXINST; then + echo FAILED + echo ERROR: I could not find the DLX linux directory. + exit 1 +fi +echo ok +echo -n "Checking for $GZIP..." +$GZIP < /dev/null > /dev/null +if test $? = 0; then + echo ok +else + echo not found + echo ERROR: without $GZIP in your PATH, I cannot continue. + exit 1 +fi +echo -n "Checking for $HOME/.bochsdlx directory..." +if test -d "$HOME/.bochsdlx"; then + echo "ok" + if test -f "$CONFFILE"; then + . $CONFFILE + else + makedlxdir + fi +else + #echo DEBUG: Creating $HOME/.bochsdlx + mkdir -p $HOME/.bochsdlx + mkdir -p $DLXPATH + makedlxdir +fi +echo Entering $DLXPATH +cd $DLXPATH + +# Now that we're in the DLXPATH, make sure that bochsrc.txt & hd10meg.img exist +if test ! -f bochsrc.txt; then + echo ERROR: bochsrc.txt not found + exit 1 +fi +if test ! -f hd10meg.img; then + echo ERROR: hd10meg.img not found + exit 1 +fi + +echo Running bochs + +# ok now try it +$BOCHS -q + +echo +echo --------------------------------------------------------------- +echo The DLX Linux demo is over. If you want to free up the disk +echo space in your account, remove the .bochsdlx directory from +echo your home directory. Example: +echo " rm -rf ~/.bochsdlx" +echo Please be careful with rm -rf because it can make a mess. +echo --------------------------------------------------------------- +exit 0 diff --git a/bochs/build/macos/CWPro3_project.sit b/bochs/build/macos/CWPro3_project.sit new file mode 100644 index 00000000..b10adc6f Binary files /dev/null and b/bochs/build/macos/CWPro3_project.sit differ diff --git a/bochs/build/macos/bochs.rsrc b/bochs/build/macos/bochs.rsrc new file mode 100644 index 00000000..5c0924fd --- /dev/null +++ b/bochs/build/macos/bochs.rsrc @@ -0,0 +1,300 @@ +(This file must be converted with BinHex 4.0) + +:#Q*[BfKc,R*cFQ-!FR0bBe*6483!!!!!!!!!!$GVKP!!!!!!!3!!!$ES!!!ek!! +!!)-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TLEf0SFbjbFh*M45j +SER4cUQ&dEh+UFAKcG#"&H'0P!J"bFh*M8P0&4!%!rrrrr`!!!!!!!!!!!!!!!!! +!!!!!!,3U'bJ!!!!!!!!kIJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!!!!!!!!!!!!!!!!!!!!!!%!!!$rrrrr3!!!!J!#!!%k6@&M6e-J8h9`F'pbG$T +0B@0)C@&NCA*c1J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!!!!!!!9!#!!%3%9!M%!!3%!!3!!!!!!!)!!!!!b2$)m!!!!!!#[!&S!%3,r$!$ +rrrrr!!!!!!!!!!!!@J!!!+m!!!!!!!!!(i!!J!#!!!!H!!%!#J!!!!!!V`"DJJ! +!!$&b!!!!!3!!!!!!!!!!!!!!!!!!!!%!!!!!!!!!!!!!!!!!!%!!!!!!!!!!!!! +!!!!!!!!!3!!!!!!!V`"D!!!$!!!!!!!!!!KHCfPQ)!!!!!!!!!!!!!!!!'&`F'` +!!!!!!!!%!!"D!+m!5!!!!%J!!!!!+-m!!30(58B!!!!!!!!!!!!!!!!!!!!!!!! +!!!!!!!!!!!!!!!J!!!!!!!#!!!$rJ!!#!J)#!J+!!!i1+bX#!S!!&"3m2!)#J!" +lHfPT"!5!!(4dCQB3%)!!YE@QTJd0J!#eY3`-#`Z!!1EQhYjfGS!!NT)0$3S+J!$ +Ki4iH$`q!!-6%V+`5%S!!JB%0$3S+J!"kHJm2$!b!!0IA(am4%B!!`F'TU4NCJ!$ +cml+bUUU!!1RTjZE8e)!!GA80$3S+J!$Gh6`m+bZ!!,Hh)5%A&i!!(Ki#!TUDJ!$ +0cE@e'aZ!!,DfQjX'"S!!H(KZELJSJ!$VkqMSfYU!!&YE$3d,#i!!6Nik1V+bJ!# +3!*!!2$`+#S!!6Nif0UDQJ!#KS5)L%4'!!0hGFR*YEB!!bXUbXLSUJ!$ZlYE@DQU +!!"iH'KS#!S!!mr2`m0VDJ!"fGQjZ1MU!!1(Kc-`P*B!!0MBH(U1MJ!!N*!B'!`1 +!!)U+HRSq2S!!4%3l1`3%J!#'KLFR(4f!!"NC&KB$!i!![lqNT!B'J!"$3c`m%K+ +!!1VUeYE@eS!!%K)5%JS+J!$LiXE'3N+!!2[lp[EDfS!!D'KGA4`FJ!"-6#!J#`Z +!!0rIdY*LBS!!(4dH(JB'J!#m[*LB4ND!!)k1I(`2$i!!LiYjH33%J!$)b+bX"JD +!!,qrTkFc-i!!JS+#JS'"J!$@eKSD$3f!!2Ihm[,@eS!!&48`-!B'J!$HhXV+EQk +!!!i1$Ji,#i!!PjH1MX2$J!$@eV1c$3f!!,@eEQjVDi!!q[Vkq[VkJ!$3d,5d"JD +!!0E@YlF5%S!!JS*eGEZlJ!$QjYVDEQk!!0VDfYVCfB!!Q*L%K!B'J!$kqZ$JhYk +!!+UUUDQTUB!!TUD9P438J!#2Mi'"+bZ!!"`F2cm%")!!2cmm2$FhJ!$5dVDf-M+ +!!'PT@eX'"S!!pI@q[VUkJ!$1cKJB$3f!!*qIRTkEQi!!&KB$!`)#J!#ZVQeYD@Q +!!12MK)4qIS!!Rjm4%3`-J!$QjVkq%K+!!'*L@eXX,)!!5dY&45NTJ!"483N*"3@ +!!#BQ)5%#!S!!-c-D'U+LJ!"mI#JS'KU!!(amE'bfYS!!eG@m[!X,J!#[Vkq[V+b +!!++LPTBq2S!!hpqhYl1cJ!$dp0rIfpZ!!!S+#JS)#)!!b-JB'!`-J!"fGQ*LAPk +!!0E@UUURTi!!eYDkZJB'J!!Z,LSU&"5!!0lHEQi+#S!!RTk)L!B'J!$Nj0rI[,b +!!-c-bXV-c)!!m[,@eYE@J!!R*cBf#JU!!0lHcXk#JS!!aF9qIRPjJ!$2ce"34dH +!!-R*a-5bXS!!EfpLBPjHJ!$fpXV+YVD!!&YE6Nj'4S!!XE'TUGcFJ!"ZEKmI'4Q +!!*UDLSSM)i!!-c-b-M!`J!$DfS+#%K+!!2[ljqIQjS!!`-#'KSD'J!#9PBQ*ZlZ +!!1,LfYU#JS!!HRTD@PTDJ!$kq[EfeYD!!%P*#3N'"S!!KiGlHlZlJ!"GA9PC06@ +!!0lH`m1r[i!!TUCQCQ*LJ!#1MSU+8P+!!1(KZVS0$B!!9&4*538&J!$LiY$3%K+ +!!&*58P*58S!!hYlHhYhGJ!"LBQ*LB'#!!,DfVUl'aS!!r[lqr[lqJ!"E@dG(VUk +!!1,L-M)Q*S!!`X+TUDQTJ!$YlH$JhYk!!0A9Q*L9PB!!cmr1cY$3J!$amI$`lqq +!!!B'"JB&"B!!lZl@eYE@J!"eGA4dFR+!!-$!&aF0$B!!Rjp99948J!$YlH[VeYD +!!-[,`-!0$B!!)L)J)!S+J!!U+LSU+5Q!!0E@eYE@eS!!4dG&484%J!$Nj1,LeYD +!!"B@-M)#!S!!iq1q[J`-J!$DfVkq"JD!!"XE'KSB')!!R*b)L"38J!!Q*Miq%K+ +!!+UU&"30$B!!P*58P*16J!$mr2EfhYk!!++LLSS'"S!!4NB[,kDQJ!#cXk+L$`q +!!,Li3%!k1S!!fGPIAeC@J!#`X"89$3f!!1$J,LiG(B!!cFfq[X("J!$0cCZEQCQ +!!$Xl"38&"B!!hYl-c"B@J!$PjGIAeG@!!#dY,Li#!S!!2Mib-M)bJ!"58NY,4dH +!!&PC6Ni9&B!!CQC58UkZJ!"A9eC@9PD!!+kZTkI'aS!!Sk13!*!!MSk!!2cmm2$ +Vki!!,LiZ,LdYJ!!Q*KB@!J+!!$Bf8P)U+S!!CQC99E5dJ!#YVCqIXE'!!%Y,5dY ++5S!!p26Sk1EQJ!$%a-6%b-L!!1cXMSk+LS!!jH916N0$J!"SD"SD%a1!!)+#%a- +0$B!!`F'q[Y$3J!!J)#!J(Kk!!-R*VUi0$B!!m[,DfYE@J!$Sk1MSjqH!!&pIAPj +FA)!!XV*58Nj1J!$)b#3N'KU!!$Xl,Li*#B!!q[VDfYE@J!#+LK-6$!b!!+UUQCN +R*i!!+#J5%JS+J!#DQMdp-M+!!)1$L)L!J)!!iZ,LiZ,LJ!#!J(amHRU!!#`X+bX +)#)!!DfX2$``-J!$HhYA9dp1!!*qI&aF0$B!!%K)5%K)5J!$TkFA&#JU!!"B@&KB +5%S!!B'"58J8&J!$fp[EfprH!!,'aPjF-$)!!Ji0bFK%4J!$bmZlZeYD!!0VDeYE +@eS!![,blZlbmJ!"UDQTUD@Q!!,Li&KB1$S!!p[ECfGE@J!#bXTD@"JD!!*16&"3 +-$)!!`F'fYU5NJ!$ZlYVDeYD!!)k1MSk0MB!!1$Ji1$FhJ!#5NSU+!J+!!1RTRCf +@PS!!+bXK)4SDJ!$TkGMB%K+!!*kH,bmK)B!!JS*QCQCQJ!#RTif0#`Z!!0VD-M) +Q*S!!,5dR*`)#4dP'1$PK@J#[!1F!!!)#!JiV!K3m!RYT"(4Q%,@Q$E8-#qEHGT) +0#Z%H$m5X%S%0#RS2$0FI%F'T'I1bUZRQe(80#Ydm+lFK&ai#QXfe'lDE"RKZ+1[ +SfPX0#dikXT!!2!T10UDK)K(GFQh+XLVZeQSH'J,cm0TfEMVKc#8f(U-N"J1+HMj +%1`5'*adC&J1rT!C$2",UeYB5%JVLaN,lpYTSA4a-)![IdQ)G(JDmQ%D1I!q,H36 +)V!DrTc1#JS(@'JhhmYB9-!EHbQi1$JZAMX2@X`feEQ[kq[V3Y!E@Ya+#GE[QfQl +DfYQBK!Eki0kUUDQQP452J5XF2`3r2$I5YM*T@`Ee[VV1'!fIRTX@!`+ZE@RMK(k +I%3cQ[K*L@ba,45P4#38Q)3)c'U*m+"TmE,E9[!Z[VkbLPMlIYl2dhpX+#JM)'!a +fBPl@UUI@ZJBZ+K6HEJUHL!ENhlc-bXcbeYBR0JVHcS,&IRR28%I*a,*[BPlfbVC +E6NDaUGaZ(aQDLL-c-M$DJK,ljqE!KSD9LE[LfS*k@PVkpYC*#3D(HlYG@6AH`lq +QCQ+1LP,KZJe853ALd"*58P,HhYeLBQ#fVXEqr[jE4klL-LE#UDRYi0l9Q*A2cY$ +am1m'"JAZeYCeG(,!&`fI996YkpE,`!dL)!SU+LR@eYC(486NiYB@-J,M[JcD[JB +E'KLFL"3Q2K+U&!f8P*2mpYkLLJC',kDcSJqi3$VCAeD`&3hJ,Kh0[X(0QjNl"3A +Hc"EPep8Y,J)q-M*55dGC6K9Q8UjA9PDZTmDMN!#1r2$V,LiY*KB#0P)UCP@dVCq +a5dY+p1MQa-6)l)k+j8j$D"S6JK-0`El3)#!HbDi0mYV@k1MRAejFXP*1b#3D1bi +*qYV@LK--UTNR+")+QMdbJiL!iZ,LJ(ak,#X)D`m-hYA6RaF0%K)5kF8+&KB5B&) +&p[EhXCF-Jh)4mZl@fYE@[,ZmDQTTZ"B1pYR@XTB'Na3-`EDNlYV@MSk01$JhNSS +#kCf@+b%DkGJ5RLmKJQCQTid,fM)Q,5F#,!!!!!"D!+m!3!Mq!#-*(%L`S-'$#"- +UA-L3!1'`KT%`14*&%BR&LaBGBGaSND,(Mb"$L[4i594*NU)FB8)BkL($)48GbG5 +)4'6(N5G,RM4CNq+PQMp0#[8CG1G1EbaG-U3i8k-SLp-`SCZ+EXL3!%KA%rBXk@J +)9A45V4B8KJf10%dYdZCLpr(5Y+3%!3aF!XfE0fKL0ShbpJD9-TP)N!$9kiQNhLK +4!+L*SXE('bUN[qSY3G@Z(DV"@)FX!4$C'lC$!#JG'[BY'+m@QNB&UdGC&"pUPeJ +0QrBi8Q5",38#f-hlPm!KBP$a4X9+)P"4ShMc(S9%*99-5&C'FV668F(0[1#8a9C +@'ZT$GS,qD8VQ*eNC12$5`p0H*MdF1#fUZ0aGF*Sh4mL8!cKFX*(qhD,i4`8QhA! +fa#8!AM)-!+J-B`i!M84#"@H4f!2!-!X#8%mNQ`"JcbDD-EJ&JdKYjKY"Z3f%L6G +2hIG44c9&*a!51Y&S(3`i`S#"4GjJ-J3%+&%N`L#$f$F0"26NJKjhCF&4L8qjN!$ +&R4)XIS513D&NiJd'kr$!JbH9d%4B48raj#@14+E*3jTU%VRQ)'[bd*-M4'+5c** +-DXHGGZqYpek6D@QA(RIZ`@&#&fYk!PLCBilN%6R$f"2+$h9GSX`cbPcLSd#BC!, +!$d0-`p-d@GQQhc"HjY*#,QLK"NHVrQN0#NpCkQN#4a@CB25L4cf"9")58b%c5LL +SN!$cJaQmCC)*0)p`kLNjBN@53!)ll,"+"!XJ8-@fZcecL5hLS+HR"qr-JJ8$$2b +j(UhBT'F#!$@a`dk[[*DC%dAHM2*%+1D3!!2!PGiJ`iHPj,bK6#JkX2,I0Cm3!%! +'G'#&K$Z(*%$,P394L`!$UlaM`#VR-S!)V@LTDUX*QB688c[$)-XE1BqX8)3KZi5 +JJMNZZ1#T+iSS8Xl23!1G44C4r'#)2R2-XX1dddjK`"3lR'&!"!Bd$I88UcJ6MM0 +#,)RHH[3NQ@3PPG#$Ud9Lm+(I$qV!SXBT(m3`E$l'rZ##h5kiR-RqAe'KX`k0Pea +5$akm2*%*-4PNXmS8Cqb3!1dCN!#Id3!RjElc$LH3!&rp$J,CB,%i*eAXPSNCHSa +M$6-Qr3$!*BjimLB2pEL`QcQM32-$16LEdqrG,N$M-J"[6&-93N0iNb%jhV46ccI +8&+2+0GLq-d8#$8bq#J)4B*[ppPc)X!XLqi`McbTRd()(R&jf%B)RkhJ#`85"Xr) +l!1B38)%D#Ub`!Jj%R2+f'J!NJMT8aaXcf1-5"f#%2KE)3(e8J!RT5-FplT'%IU" +!1@E3`[e1i6m!rSm!RYT0YZMJ*5$j"!#)mK)2eX&#&VTM0fEB3a"`B)&ie0!#k4K +!#%))J%aF``,qr8Y(&,V!3aGd3ADmqF%23QJ'2#MJE4dF!4*rd!88T+*fd)"'i(B +L#RDiJ45HB"m,Na'#&,V*6D436KXkk$m1HY#0DP"%%HCBK#!8)BjZG1-DGN11*lC +4MN')"Ji%L3-l!K#1S0M0$m3KaKCf5BASid%A%1@Q1-(TM&p5"MAm*ETr$#!D(-a +M'dICaM$d`e1C)!!849N%#bb#KhaSacVBG%Ed4I+5Ah)$4AEcNhXKJ452E"-N[65 +N5#*K#BrJBE*S%),rp1B0N!#N*5eI0iMfkG)S60P8*&*8%,"iJeifF4d(+(",&FE +*R)-B%LPm3K&*8)#BFCTPqhV&49'3!!*M#rlK*N3)!TCT81!9(QN("54aLB(U""! +8!))M"NT28I`c+1jmKNq3!1"1CHb6*D'iU%BhbY'0kP-K&@P18`#6NHC`"*aP%NQ +0KK)5R3bPRR"jb90%kT5RG18jB+&+Y!UbPC4NCLT5S3T#[(%[S331+3IjD%*LFT1 +CHS0895Q93QMN%@pi4DJ%'3+6X1%GY@K#("-9#P+aT*4)b%8J5cM4,eMKL%IXjK% +JH8CbpY-1Q3!J2hc)&'Xmj)dP)+-NJV%1@Ld%!$5N*aM#XF1VNV-,e34M&+UUaB, +-83Gal(8BYFK&,Z5M'mlmJV"['-*Z50S4i9(&2rTKK6ImXk(0f!-k#4VqE54-0&X +)+3%E`9L2fS,K"rmX)4,H!!!dd1%(5J"J&m)iKR"ria86P*8JGU%*Vf)d%&&J!K0 +#3B*!6!+6S@#&+$84`CT%8"*2&*-8iQJ"2B3aN!"T)1'TM[!$NkiLN@Ni`US&#FA +U6()5GNKhTLQeL&[!BK*([+j,-1""MJD4B$Cj*)bZ)e)b@U!R26'T81YaMc6#C"( +T#)5iYc8"+0+%!@q3!-)Lm`S`QAlLKNIq)"4mX)Fpq-!($)8L&2Q!"LTd4iiH+p% +-CP#Q-hI$(8hBkX,[XG@Xm[5UY+4&%e8!a3V[dbK`p[3M,ai'0#!e%DY+05+H#S8 +M-M8m2b6J$2,3([j[KL%198QM$0)i#b+baBeDU#9XU+'(HR14T,24kmrJ2)R`a,# +[PS4L&1j`Kii"`)GR@130MqJ8!-K"%&P-kaeBQ-!F$S%%GRLJ!6YJaM,Q))YCD)d +,h,$'&*aQ!!C%S"0EABq63aG5AmAS1+*3aL0q)#NPiZdE3q!N+N"J#P0FS!NqZ!& +[@2!*GhcM#r*B@J0QX3X!#'&D(3+!1`BLM'RY3"l1B%!+UT''flBV6dmf9+j%X3N +9+#F6+'K#'2))`#D-)J3jbpQaP"-&RbNL#%()3Y$+)A"3-'%4ah9!')V!M@`XS'1 +Vb-BihJ&UDf&"(J`)4`4Z`D"Z(#)AKdL$,IiXBBXd())Y*J'!P$e"#TV-4!c8q-% +6KS'+BZ&-"ITZd)0i+4@&k(Fh*L$%1+l9J3l-BJ*,SaE6V%@eMh(#!*EE3DXMm#j +bZ!-*IZ#'2$M"$$Ke!3!88CYb@"#0YkR$"6A(QGh`"SfGm`BD9%K*Mi!+J3ALiK2 +kq-30&Z%%!3LJ&$d)3!"k%!FC4#!$A6!($3LiQa#S)`b("'!4&R%02N,!R*)-J5- +GbB00S!)DS9"(2hS"L[QKJ!NEI1-T`J"j043K&IB3XMh1iAEHG+%*'b5PreD!F0i +JJa3*IX!NaN'(L8cA$5iBF649q-*2T@,H(36J$'XBMhLN)aj*L-)L"[l3MqTlhiD +$r-GZ90#2&AcI"ZIS`V&8F)d"H0m#+iJ'%3Ml!aD6!J+EEq%+*6RL5pU5"rP43#c +3"[fMHSF85U-%4DX%3(XdDAk%J!VB3853!!kp`%1K3!@2K(RPC%jIK`3YjL@iC%P +[iRpHFJQE`(LlJ3Tl3!3,q%D'`"Xhi%Bii$!&Y!QB)%eXmMVRY%)3F"a&N3NCK3l +fp9)XP4)3-#3m8%b4"),$*),Sj!P8j4&(1%h5e$ipH#mRS4)ap4,V8#86G3P!3!& +'B",+3!'qm$F8S!&HJP$(-!ML8!*H!!3N%BB8F!`mi5&%8d!k@-SC2i3PIeK" ++e9&CK3lIe"Eq,"8i4$%8lq9KK*K8'I@)NML*([9FP(L*Q*KIPRJ33c!4'$&5)N9 +6STJ4BX)4!2CR43%82YK,21&65E@*"h&VJ&'+!1BS,S@)4%J54F91['K8V,1&#Y& +GS[J4Q@%9Al&6"3%r&9%39S'-"8&849K9`*J3-"'+d[9832898q'-!f&mA)%91,@ +0J6J%PD"CZ(J*Bk@*%"%6*08LaaL)XAJ89l@0"S&NUh+2ZF"1*C'1+&*@Cc9E*l* +G2h%4pq80bS!+hp!Fhi!+-C)5MNJ3p0)9AS%+[c80G4&VVk)UU+%*Z8J4`2L2D58 +3[q"AMm!+*LP40E%*F#88e,!*#1)4'Q,q$dX`NfrJ9a5"$0dJ@-U`)3,a$EaJ'YT +K'Sq9&MpT'#8"GK44$e3JNdY!"Fp`&B0B%#Y#@M5P%5IaAZk&P+eSA3-4N3Ha9B6 +5C+JaPNEQC%p@PQDj@I-"NK55(`PT%Bp`'IF9&CL3!"pX44MHd!f03"FHSJaU!`f +X!&LMB"e[F"ZEJ3IF)3LmB3HDX*!!(P)29Z&jM"B-l8)*MA!-`S%%b3!2R'9@rpK +HDV-%(E%*I!#CTH*E[q%4U,NCMB!1#!*fVfNGY%9Ee@B(P*!!(-F3#DYT@qe#(l3 +e%%1`$E!S%94@Lalj'e%"&'ma"$8"%kjT%YpP9,dS#ZcM*L@K#8U3!"@KrM+%hQ" +Zf!#2rAJ3pZ886986AE&G)+&GN8!4%Y'+NI#F3b%#5NKP)V!1kQ8VF&!'3i"GTH@ +G`Z#*%q%)q)3ES5#%3q&IZN)QM1)MJ$-RYR4,DU+-&"&'mZN*da!VjdBSA#80,$) +0hZN(SZ)6$iN9fl"I[c)6RFBS,8@GF3)$P94,1*JQ[H)*J`!@CA"Nfj'MHr)HAl- +ZVr)R66)Sf(!SVq-*90C8Zd)4T!##lU"%j2"jS*G&0BF+0h-h5k3X@0T$@DSI93! +)KG)Z2*TN6bB05aD@6()SF0+&dS9bMN)4AV31jK!T0,G%30CMmc0NH-SES@"ZVk* +NB,NR6NB2K1)HrL+f*Y0`BQeU,leS$U%J+DM`#jIL,BiJ2#VL+BpK+CNLS&La$"1 +!"9bJTqT&TR&@-TSP$AZL(Ri#$r5J#DYD"@DJ%68e%[4b&1L3!!N0-JVfJ+XheRD +08DN-)LU#j@fVX!!4J!Aki@4+BKE5F!8HJ`A1d!Q`SQITGM+jFK'b@QXe!KD2B!m +k0Jam!!fld3Lr!+lK#QD64K",GchCJJ!)3+cX5U`,%!l0S!G5!!ri%$@cX$%-3!C +Jk4j3PM)TT6)*kK(SJ!5-35bSm"04)5UMB!i%-5$2`Nq6m'fd`&i#S35d3![Bm"Z +BF+mEJ`@@-`A[-+`-X!#RUJQXmKkK8jkik2k$2-%+YG-[2IB@b2!,$'*@BV!Ehk! +`Ze%!Ra!$,+!054!1fB!2da!+6d!0c*!!!(IJ$T[`9`2KEHJbYHK5$Arb(V%#$e# +QPEAQ+rA`FiV%V5T!$[S'!+cJ$YF3")T35)SJF%"c$J!!#cjE!q13!(40B`!'m(6 +9X!f#F!Gh)!@6`$46i!c1N!!#,E"NJi)HUeSbmD'90&)2XDFI8H!f(%3%-I!%qH! +#1(FhZp%2E3Y`!aFdLX!%FI!*Bj!!!hhJE9M!#3RJ0!M!#8[c$Z2!!-i!XZ'@2FF +J,[#K@CU&"00J*%J!)0R''pUJ"T!!4frqS`@6BU9VTabK)"RYm!Bqm!)c9%JirS! +$+k!#NkX,94!1A0!-qc!"(5!2i4!1$#"aib!qf4"ZYmX&fm)!l$S,eM#r%e#rG0! +#J3-J!+C*qJ'%MUSlqBBhHE-E5p!McIJE!m'c!,!05Y1kll!!dFBd%X`dCj!!03r +h$N[$#3M`"C@R(hKJG*1`*NF8JT@d$Ym!$8q`C3*X0bi$$6`N#U5L%1fJ(293$cT +3$jH!#%3l$V#EG0@#"3X`"3K30Gjf"YMcDPFK$(mJ2Pb(2Pp(%FU!$%K83#PFFf3 +E`$RcH6bd"+6`Zk9b94*""Hlf+8l3Gi)RH$e3#M,`F*b!"4(3$&[`$I93EEDR$NP +!!-d%!#D3!!,i-%Y,f!Aq+Y"bE-%+,U`F,Y!2DT!!"$['1rVf!bZJ"MP!@-Va#kb +$#G0`!!f8b303aJ)3H)*A#J&J$Vq6#5kJ!+dAH3"N!mRL$ZB%*!#JHCXR!K2K$ZD +!JMd8Ea9!ErrM389`F2p"!!d8"Yjh!PX`aQr("!F)4`"%!'1maa0J$Cdk"r@%)&h +!3Rl32Zf6$1[J9TR3"8R`IIe`$FT%$L0`J'rd2d63")NdC$p3[20QcQkd!ZZX5+L +3!!rXS#Mma5YZi!KZ)%BK)'9,Z%,E$%1TJ-id4(diP!6&l%aQ!!lFphhLP`RrB!2 +B&`AJS$-T5%5li3,YehdfY!9"pJ1mZ-m3d%L1"!ST42j0F-*$6!"(#3K)f2YphfF +"1("((Y5!,J!,Te"(qL26haGrLK"+6k")e*Pr,)4jr+I5AT*'[*%%NDI-,Jf"SK5 +"$8J1$U"l#4KpTd!%ED!,bN%0R)I8Ip`&*#L#Jh!*he"l2l!)b-a'8Th9F!3,""3 ++#S#!@Dd'&R""cc5#CEf"+J3"Q4!#,fT*Z14rJm!1-+Y-S+!1r32A(64[Hi"+MaG ++DM#"jr!l,X!+ILa01KM3kl$222'DfH8'4mL%KVf$NE319*!!)FT"$Vd`"JG)"1! +!3leJ!bLJ6+1`T$(D*[mh6kc)+e%a+I"cLlr5cq+eJ@U#6Qk#"0r!"jcd(jQ!$+, +q54'AapFiH%kHi!CFG*8BJ)cFj"8V%SA6L346L$jJ3!&)i0Flb)4!SSLL8!Kl5-* +[`N)3S%[k@"'!k(1`#*a'LK-Q-9#!i!YJJ!6Qp!aJi!Z!!)*%XJj!)!N16K%$03M +eJ1!Xj!PLi1"'J%fN-+,k[9&#f#[ZP"-KlJ9Hi)%3i%qq-!KH8!)pq"(ZC"&Z%)C +!J!6Yi!9LU+3$UP&4Z8rHN!#'`!!)ib5(Pf!%!`8%Vj!!8#8"$"33K`d1"%UqNTG +!iQ!SKX"3!K6`&SrB%KLbj9cHj9jZBcGQD--3jQ'H4E8XC2pK"ZB!$@0qBfhqjA! +HjffZjA*HjhCqjhLHjhFHLIkCf1GpML&q(ZLB11ElC)JSPDL)RZL+AK'8LK#%hK! +KHP)PC9+5,ZNVkP++Q1Qh'#3QJH8'mHJ-%5-S1P+M6ZQ9IQX+bL[Be*&2FC@+k1K +m(ScX#+ZQ1&eYZZPF*0km@%qiH*bI(ZXJCBhrPDJeXZVL6GbYRZb*1*fZq1[V')V +@qL,h9C!!aFP19(AXiMf`bMkG1I',"`(U#c&6T&84aTK6laL,eJkFAY'-i1Q&ZmL +2!`(Z)#AZd[9Hf@MZ3B83e1%4eM'2fTMM!Q&mc!l[!L([5dA[YfCDjRiPi$NM3h& +6rhl!`%N@IDS*E(%[""m*"Sm3iUiVphAZSIi49RA[ApEq#VH&(UfLNEdS@-lH%#& +9RNL`lJe[%$d&mF2666ZDmQJ"9Vr0mJ9"k$Blb5&CA5T+N!"[%)$)S!c0iF8*iBd +T!Gj,B#(3m&Z4J'5`BQ4JeBZA!1Ya-4Fb4L'Ai&EQS&Vhi3MIm!KL-JS*#3"Za3I +DaCHE-&XeYKp2Ea8!S*1HJ9J!B!I5m&LUSKVe`!IQm!JX`b$Y-&[J'[F&(q[r+!B +RXTI)B!r)J!aMIa'M-"JH83r)J"K8CEE3m!ZI0C+(J4cei21ce5'8B"VFm9K$f3) +rf3fMMj3P34HJE`mR!ZiJqIK8m!hfS!bk*P%8m3cQX!N8X3RQS!b)m3f,-3ScE&' +5rZ&A*A(jkKPF'e)*['!(8K!DC,!,TB%+Y9!,jP!2`B!-Uc)-LP%2`c$$aj!!#cZ +E#j8!HLpK(iH)kQhKZlplpemBmed*AJBa"'AD,J!"$`iF6CTDj$T)lf#,&Z*DD#+ +)N!"KVPa93N@+Y%5MaMFB-8jcY)4929'1[%hcKZ55U#AeA)kXYd58+#51N!#S&18 +4TkK,5$aLK!#-%MDL4!Fb,%K3fN##5CP#T'H`iX9)!!"Sl!B03,e)MUa5BrA)UKK +(2@dL!d$0CEeZ5aaK3KFh,LDINC!!c14Ceq-5!,b+BK2i80SS!-(L$SQVT)a!10L +82#B+6jT&M&BpeJ2`UbS!QcG[L[lbKQl)k&m!h&'K-P,CY%B!S#eT$8#($J#SH&V +eb9FchdEB[[80CJi!T@qS!0MMfVV4-H2"i2%phQLd%K08V9j(Y535*UZG26Y#2(T +)kde,8(Gl*UUdGYe$N!"BRBNlBqEj[p!GXQ2FDV!KkqFh3NF*E+`D3J`!'[N*R@f +X!q#R50$aKTADC)+1UjrmLf5)DAJUM3T(*2aP#&'X@XNUC5,CK$iUk,-+MKCfZ5U +5dX5S$)"$I+020`IcSDS4"$dD`L5EPRKNP&&NZL6"EdC""TP'IQRbNRT'@@f*8HT +"4a3MmGTNP%HH'@868ZCT4)G,RU''Pfm1q@@6VYaTK"9dK+(q"!eHkTN')f8DXG# +M8+Kb-"*[[((%1laQmXJE6$"aC+DkH(*[3d64@FR45`BC4)4+24%"dd&QJN-*MaK +G&)PTLK)')h43`L63B3$pDBK"EF,V,NFp%Q8D5A[#D#CdbTSTb5&@X[85%6SGa*1 +52&PR(BS3+Q1)l@KbK*eTr#JUVN)a!DR9Rei0p0H82M[88@pj`SYA%5qCTPLIGXA +V@%aj3)*34a##!al'bX$Nd&1,fR#PPEb4pPZU9V@e8(*YY662VLbGD3JH-)@KiSS +p*HA3P85Bq#4-+XPPUEq8)+L5ZkB4N!!S*C*"pa*(!SdNP"mBaN[KFXZp"#j[dN@ +#"ajJr["jBTrRpE4B6cJpPZ1Si2QV+-Cbm8-*TZ&4BZH"#rBS3"-!Z,NN3fYPZ&j +-,JjDQ+!(%ATLY09@9K42"d(RBhUB0UTTICR#'ak$@T!!KM%PX#9UkjNFQDCC3Mf +MkHC+13jkk+'*4[YYYKheCT!!)6!TBk#k0fHXXEq1JXKcE2)0(*5dHE#h8CVZqQ` +R4hlQB4fe@r%%Jf551AYYb*1GUA)Bd%Q'RXC%&hed[*QDU2LQ63"PE4iJ)-AQa-' +qC+9+JJk&4clXXBH2lBF"rdraSB('((0F-#166+jMRre3M0IFU)NB)MfbcJGL2ZK +TSZmXFA)eCJF%H0!+FS5#Hkq#"LVqb''1(ra!IHf$B!6Cpi1LK+jiG-ZA3+3b%'N +XT3TGQ0Jk["'pcl#$(@#MLF!U*3Tb$--HS5"(*NE4L%Hi`afr'!AhZRFGlM%TKcU +d"cRD&`SH##0i#XQAjc4B%,i"aRljqL$D-%!+*,#$GDZV9E#db"0c'"#'9(V'-j6 +a$(D0DRhQS)XbaTJcMj6'I4"J#$hN1"'*N!"1Ai!C(N%8`Mbd3H"V+,696J6@3Mk +8$aPUc"8k()51p8%$#BMd&MiQm3i%4#!#9E$+--4"MdU8SB04q8-R1L%1K$J&$Kd +X#"1VS!))M*!!C[qMQFCbp32bN3-D2@K%0eK"KACi5e@0G-3Ek[ibK%RXi"d,L!! +#YQB9FdJ%)4f8KLcH-BYX-#!0$%R)Xjj&MbUB3@%R,"FXY9LTZ+#L%FL`ac!55)i +&aK!DhQ)N!-LK)@P*)3%*f!%@NVQ+pQN#AdR8e`6HB3!%-)!E5q'J31iQ$40N`S3 +R2+%i(A8c6!aK5D%`KaPLZ$jbE#m8d-M%LH**MTrF%jpB3+BP-a!"3Yb##bm04c1 +q8"4m'"-,P9b!%jd''(Jdp&"KZf,A5K)hC(b8'Sd3MPA)BBBIm-%P6e"'2(p3dRZ +H!3(bQ-8ik"!,!`b8%fIJ""DF%9-`B%-@8jM#1eEKM!JmB+F$-3JQ*bV1QK3VABY +baa-qL[k+4kL`(G"i`XZfd`fTrZ3"*hf(,%5cUQ8N3!+A1)NST#Q2"@#"%fMPa#` +@`)!&+"%1%QN"*Q2CZYA4LLH9`J3`H$%-9)"8N6q4%#D@G!P@)'&p2jK'UfB3L6X +dB"Aiq)N(%[!!"rNK!Cc)"J)'qSjhB)%"$)K&C&cd%(d*EU,AGG3V9`)-C2""J6m +`Jb+lJ4PS9+8G+G,"LUbLJ"X!J!#I`!8!j%&FNBbL'JR!aa"5Jl9l6Q%"#d!!&UV +jAd[`G'm(dB4FKGS6BXAb%ShJ!cPqi!)AQ1-CN8JI!-b"$J$m"J$GF-Ik!&!!4Rc +L#EhB`#Si-B%rJ*FAY%K!-13*$Ij[H-5Ncm@a-kT4[m"!C(30EGh#jRSA-@a#L'C +i!LSD51%IN!$M$IU*JL)88BiJP-2+","+-@#KM4`ii`chE%!$*V!0@54J%Y3!`!p +1&!PKA1'H1h"'R0-`0IXaCRj9b)6r`LQ+0fa#+pI*a$#fX!Y8R'r#CJ$!!)+3!!9 +&-$S,9SDdP9h`!fh8S4Ucf)&*m@N!!qc!d`-p`cXimHB%M#21h"J)h4M$40$+pBT +hBB9q!,d*)UK"$A[B3LK8S13*Vfm&@3M#P#-GD8@S!392B-3mZ$'&rVjM"ja'3#@ +aB&*Q*q!-cRLZ(LL433h5Jb+f@a4Fe)HAGSa#a0Fj4kh9F!TErX1#&fXS0*0GB*9 +rp+-F`!lfX+fX#&1JJ!PGH%)1JX!'@R"#ZCTqacLbm3jVF%+Yf&j!"[)"LBJF*"I +IdG9YZ+D-F`0J#d`S3KMB[@k5Af!BjTXdK4(0[K$Ni!@-aX'8(feP0B5!#IGST#Z +qd)%*C#-FiC!!4`0fd)!TF')9@$!e!b+`J'9@33El'%I81c#,$X5#$*8#3*lEdA% +!'+)#)fIh+G+KK5G-HX)6R[4eH'(&rBRM$@m3KabJ%'`,J%)&LdK"CI2jhfa-S!2 +MN!!(YTmE$JBi)a[M-)!qR5'$E"cqXLZH3!SQ-!&VH#!qA%YKV0YRKM8BiJN[6'! +$PmaNUlMq)j'ML83V4)!"4iJ$'Mq`LJVdJ1Q`VQ)"q-bdTKX!jKe-i3c-hX%CN!! +HL`fXr$TiQ$SG4#'#,S4!GBGLa6#Z%iTGK+,3+L#(#N32MAaN'!#V%3h-(L4%UmK +M&9DYj'8pM8p0plk5#$J$3CdpK8VHBS*iX-)ihL%"Y)'L#j&6QmG4KP"iJRaJS*4 +$1`S$UHYJ&p36[bGSRaM3KJe!"-26[fScU4h!+I9E[fHcT'C`Kb4""dX`[`CBKSN +"K8a`"0QCPiRaK0,)Ke&!"3ScK`8k(d6,K!8NNGc#QN#C"[DK!T%BL8Z`JRfD!Nr +E[Gj,*J2`2GmcJ*4L!(%B!MLS"X$MrS3'Z!1e!38!8!QA8BC(N!#eV,-(!k3`XbY +$@i+pXG#9eiU99I''8,!+D&#'ELL'!,$$!)L$If!!HAJ(SU-kCrL#I8J",UL#+VL +&3K5a+XJ!&GX"CS#(aaQ%,C`*0lU1(eL%G###Mc+(3T1`-R5""')I9(J'8q("aCU +')rJ%"8L#HlJ"F!J!!4#!(VM$!#L&(JL(E"LVI`!&'RJ#mV1+De#!8f!h($L(V!1 +!*jJ(5)c%2"-&+NJUUmL%IcL(D&#$'fJR&b!(*J1[FcJ"imZNGM!9Z-#%!f!%I6" +(IF!&A'#%!R!#@#b&1bb&Ij!!!4UJJAN$Y"KB0f%-1hDc!4(l!3MqN!#F6!L"Sk' +Ldl)(pXQ%,DJe*JJ"-mL`,X!"NE-eEIL(pN%&XcL#FMc(Ff3%@,L(GT6&(NL&44J +L)K!jNG0(NUY)UkJ#1r!8(QL85`#!%'L@QLa)83Lap[Q(%b!jNY[(-&#$-)#&Jfb +I40M)Fr`%#iL(TBb(!HL#pZ'&&E#eUG6(8eJ"AEL1$$!r,+J'6e!GV#1'QK6,GF! +!Gb!I9&J$&HJiFaJ")YM(I!3l0B#&81Li+)#&6h#!H(!&!S"$K!`"!UJ!@aXj`95 +$0X$+6*U(+j!!!0mDKc[S`PS"J,!FbfEa"(Ii!A2J!aZ)"`Y)JNAB3N$6!QT-5EL +8b&0SJM#%S2jSY)'hl%PE8iIf-BHH@3G23)*+N!#&UjX*+h)%8S!!&3!KRaR,bP5 +U*&L"cGa-TAa+pM%(EDJeB34+08J(&2"'#FS("f"0GLZ!&'5I")+'8"!&FC!!TCT +`"!LB6@B*JIpc(Z!86J!`Je4J0b*B!D9F5J[SKh2SJR0c!A"!!A[-ZQZ)JMD)Ke4 +)6Q+iJ3'i"KA!$J*BJ3T)KF2-K#jB"(ASKhlB!QKJTa9D(9)J"@C*KTS8JI1-R"C +%'hH`L[BmK@+cY5,!!3Z3!-qP[)&&X-G-!)8)C8UQY)#+I0!NB%SE1)GVi%qV))C +&d-cja!(#5,-'fmh*V%NHm$qed4fI-G*-B2i#X!Xl05J#&Bh2'Zf('Th2&5##)P# +$0E#+(l#!)-K5TP5(+$J(!R!&TP`"('K1#%`c8H"0CQ'@b43Drh[*Y&N(pQN$`Da +5Z,65))J'(&L"q$a8(!"6`Jc6-CA+NBZ'q&4+q6c8)1M*8pL#%K@&XHc3f'NF6!' +&jRR5LB%!2mh(5a9'3,8e&)h,5a96HF)"4P8$&,e53"djBK3a9##&XI68!2382A8 +FY5R9kqL#'fK1@eA9UEa84K@j`h3""@K0`5bfYm5"'d$3%[d&0`$1aR&5*ie%ddN +Eb&Q#0-`k-d!"#cM9G+9+4Ke-B9a*&eL"`@4A@b1#'`L"kb#(6A!%S2i*eYha9Kj +3!G24(3#-R(9SKfriXc%pKhL9ef9Yc9-)JhjBZ9j39PNP!KZi9[CN"8rJeR!083# +-RB`"J1Cj(+&"Qdia@3J3!h1Va#jBf(Pp@*(EJj@,!ANGaL4)6UYSK*lT@)rYeYM +abQ"*-diK'T-Pf0bj")4Y(e")"EH8eDTm6DYSJX%NJL6ic%bUJr6NeS%03"l`K)* +NX"(K'L4`!fC"fD*eRSr&P$F`8[E*"h@!9VJm"5*J!@JF!#+i@(,9-#V3fSlP@Tr +a"$G!Ph3"$H%)fjNS@aiifl2TeVFC"!KJKEj%5"8)K4K3J(6Jc`N,aBeY`ClY9q# +%!)K"PlG3*2kkh)QI+P['-GU29FC"@)G,-%X*fMal%!-khG1J8GeJ"GUl%*KDbDe +[HDH8N!#Pl1,0GAM*cRAFaPd(CG!"2[$'8+!#`JA)YH%BP-hGhGfL&%+#LR)9UKJ +#6`!*a6Q8$89Hb6RHmhe*fL`AJ&6F6-%8i`A1f46F&GU*DHK""`'A0JcDF@UCC9% +EAk!!52cAj"d%$'#B5j!!"!SJi*-0h0-Lh*,`*I',K2b&QF[*Q2kYRX&e"!V`KFC +&Ak)4SF'p"!U3!!6dABI3a4PcZ9m*TQ!*hJj*'5H9@!)+S)"A5'![3!*-13B+m!) +!jS#e33)[U'&*N!#%5jKKAr!#$K$LGR#$'IECJJ5@K-&9&"H'Q4DQiJG4ha35"51 +J!#!)PJ4'!M#JJ(E!&"(Ji%%3BbVJhCRJiN)iQMUJ!'-3"@2SBJf1i#Xf'$`1&-4 +)#35QJ-&pK6mQBEa3"K*H"`i'PJa1i"3#JLjHLAB)C%R`K"A@Bib`iNS'%Jl1'$m +'"P&i"5r!#bm!C8mHia8Di5KHL88@"5!JR$bJJ$c!j#U'P9M'#&HQi4,`K@F3AP% +!!b&q"8")&b!)C"*Z"f#3!)416Z9#8"3Ji!!++!&BTQAmRH9S&Mr%!)Rr'GbZ%4Y ++TQEm$3J!1`!!"`#Z!(i!"`!"!!%!!`!$!!3!!!!0!!`!%!"D!&S!b`$,!#J!8J! +!(P&eD@0V9'PYCDSJCA3JG@iJC)jMEfe`FQ9cFf9eFJ!!+!"A!!8I4dP')(0[ER3 +JFQ9aG@Pc)("[GA)JGQPcG@&XDA0PFJ!S!&`!(!aMCA4dC5"TE@&RC5i!!!!!r`! +!!&[8T5562q8b-!!%!!!!!!!!!!#k*S3PZLD%*3!!!!!!!!!!!!!!!!!!!!!)Bf* +[G'KKEAN!!!!+BQpMD(-ZFR0bB`!!!!!8,5"cCA3JGQ9bFfP[EL"dEb!b,M!!!!! +$,!!,!!!!!!$0!FB!i3)!"!*25`!!!!!!'3!'!%X"fBL"9'KTFb"cEfCdGf&bC5" +TFb"bC@aPBA0PC#"eEQ4PFL"dD'8J4dj9)%a(8%`Z$8C[FL"YEh*P)'PZCQpbE@& +dD@pZ,#"bC@&N)(4SC5"QD@aP)#G$6e"C58j(*b"TEQ0XG@4PC#"TEL"dD'8JBQp +MD(-JC'PcG(*TBR9dD@pZ,L!J!!!!!!!!V3!'!0%"ZSK@6@&M6e-JF'pbG#"LH5" +%BACTC#"#BA4dCA*SB@dX)&4TE5"6C@jPBf&X,#"$D(*TFh4[F'KP)%*[G'KKEAN +JB@jN)%4KEQPPE#"(D@e`C@aPGQPMD#i!!!!!!0)!"J$e!EL)E94SC5"#Ef0SFb" +dC@&Y)'Pc)'a[EfYTEQFJCQpb)'%JE@&TER4KD@jPFL"QEh)J3QpMD(-JEfiJ6@& +M6e-Z)!e*CL"jEh8JG'KTEQXJH@pe)'0KEL"SC@a`,#"`E'9KFf8JBfpZG'&MG#" +eFbi!!!!!!!!&!!B!&J(1L"G#Ef0SFb!b,M%Z-5!JCQpb)%eKBdp6$3!!!!!!!%m +!"J#$!Fq)XP0[GA*MC5"MEf4P)'C[FL"#Ef0SFb"TFb"KGQ&TE'&LE'8JCR*[E5" +dD'8J3QpMD(-JD'pYC5"`B@GP)'&d)!eSG(4`1Lm[BQpMD(-ZFfpeFQ0PCQpbCf8 +ZEQ9d,L"8D'8JC'pMG@ePER4KG'P[EL"TFb"[EQaTEQ8JBA3JD(4dF$S[,f*[BfK +c,R0[GA*MC@C[FQGP,QjPG#pNEf-[C'pMBQp[DbpTEQ4PH#jSG'eX)#i!!!!!!)B +!"J#R!Fb)C8PQ)(P[G5"hEh9XC#"XD@YP)'0[ER4bD@*eG'8JG'mJG'KP)%*[BfK +c)("bEfTPBh3X)("XC@&cC5"UEfPZ)'PZ)#"dD'8JBQpMD(-YC'9fC@a[F'9bFb" +YB@PXD@jR)'aTFh3Z!!!!!!!!%!'j!,m#%d!#!)!!!!!!!"!"Z3#r!K0!!J#!!!! +!!!!3!EN![`)63!)!J!!!!!!!%!'j!,m#%d!#!)!!!!!!!"!"Z3#r!K0!!J#!!!! +"!!!!0ZJ!!$AS!!!!Je028P3(fJ#!!"`!EJ!$4%P86!!!!#*%6%p(!!!!,P"*3e3 +!!!!kBfYTC!!!!%B!J2rr!!!bZ!3[T"3!J!!!!!!!!!3[SH3!J2rr!!!!'33[Sp` +!J!!'!!!b@33[T%J&3@*[GA318(*[DQ9MG'pb)%4KG'%aNJ: diff --git a/bochs/build/macos/bochsico.bmp b/bochs/build/macos/bochsico.bmp new file mode 100644 index 00000000..08e4c38f Binary files /dev/null and b/bochs/build/macos/bochsico.bmp differ diff --git a/bochs/build/macos/macos_defines.h b/bochs/build/macos/macos_defines.h new file mode 100644 index 00000000..aac525d3 --- /dev/null +++ b/bochs/build/macos/macos_defines.h @@ -0,0 +1,12 @@ +#define NO_ASSEMBLER +#define USE_WITH_CPU_SIM +#define PARANOID + +#define fileno(A) 0 +#ifdef __cplusplus +#include +inline long read(int fd, void *buf, std::size_t nbytes); +long read(int fd, void *buf, std::size_t nbytes) {return read(fd, (char*)buf, nbytes);} +inline long write(int fd, const void *buf, std::size_t nbytes); +long write(int fd, const void *buf, std::size_t nbytes) {return write(fd, (const char*)buf, nbytes);} +#endif diff --git a/bochs/build/macosx/Info.plist.in b/bochs/build/macosx/Info.plist.in new file mode 100644 index 00000000..e61b78b9 --- /dev/null +++ b/bochs/build/macosx/Info.plist.in @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + bochs + CFBundleGetInfoString + @VERSION@ Carbon + CFBundleIconFile + bochs-icn + CFBundleIdentifier + net.sourceforge.bochs.bochs + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Bochs Carbon @VERSION@ + CFBundlePackageType + APPL + CFBundleShortVersionString + Bochs Carbon (@VERSION@) + CFBundleSignature + BOCHS + CFBundleVersion + @VERSION@ + CSResourcesFileMapped + + + diff --git a/bochs/build/macosx/README.macosx-binary b/bochs/build/macosx/README.macosx-binary new file mode 100644 index 00000000..e69de29b diff --git a/bochs/build/macosx/bochs-icn.icns b/bochs/build/macosx/bochs-icn.icns new file mode 100644 index 00000000..bc976959 Binary files /dev/null and b/bochs/build/macosx/bochs-icn.icns differ diff --git a/bochs/build/macosx/bochs.applescript b/bochs/build/macosx/bochs.applescript new file mode 100644 index 00000000..de469fcd --- /dev/null +++ b/bochs/build/macosx/bochs.applescript @@ -0,0 +1,70 @@ +property bochs_path : "Contents/MacOS/bochs" +property bochs_app : "" + +on run + tell application "Finder" to get container of (path to me) as string + set script_path to POSIX path of result + + -- Locate bochs + set bochs_alias to findBochs() + + -- Tell Terminal to run bochs from the command line + --Use the script's directory as the current directory + tell application "Terminal" + activate + do script "cd '" & script_path & "';exec '" & (POSIX path of bochs_app) & bochs_path&"'" + -- Wait for Terminal to change the name first, then change it to ours + delay 1 + set AppleScript's text item delimiters to "/" + set the text_item_list to every text item of the script_path + set AppleScript's text item delimiters to "" + + + set next_to_last to ((count of text_item_list) - 1) + set the folder_name to item next_to_last of text_item_list + set name of front window to "Running bochs in ../" & folder_name & "/" + end tell +end run + +-- Taken from examples at http://www.applescriptsourcebook.com/tips/findlibrary.html +to Hunt for itemName at folderList + --Returns path to itemName as string, or empty string if not found + repeat with aFolder in folderList + try + if class of aFolder is constant then + return alias ((path to aFolder as string) & itemName) as string + else if folder of (info for alias aFolder) then + return alias (aFolder & itemName) as string + end if + on error number -43 --item not there, go to next folder + end try + end repeat + return "" --return empty string if item not found +end Hunt + +on findBochs() + try + if bochs_app is "" then error number -43 + return alias bochs_app + on error number -43 + -- bochs_app no good, go hunting + try + tell application "Finder" to get container of (path to me) as string + set this_dir_alias to alias result + tell application "Finder" to get container of (this_dir_alias) as string + set one_up_dir_alias to alias result + set TheUsualPlaces to {this_dir_alias as string, one_up_dir_alias as string} + Hunt for "bochs.app" at TheUsualPlaces + set result_alias to result + if result_alias is "" then error number -43 + set bochs_app to result_alias as string + return result_alias + on error number -43 + --Give up seeking, Ask the user + choose application with prompt "Please locate Bochs:" as alias + set result_alias to result + set bochs_app to result_alias as string + return result_alias + end try + end try +end findBochs \ No newline at end of file diff --git a/bochs/build/macosx/bochs.r b/bochs/build/macosx/bochs.r new file mode 100755 index 00000000..9072489b --- /dev/null +++ b/bochs/build/macosx/bochs.r @@ -0,0 +1,1365 @@ +data 'BNDL' (128) { + $"426F 6368 0000 0001 4652 4546 0000 0000" /* Boch....FREF.... */ + $"0080 4943 4E23 0000 0000 0080" /* .ICN#..... */ +}; + +data 'Boch' (0, "Owner resource") { + $"00" /* . */ +}; + +data 'FREF' (128) { + $"4150 504C 0000 00" /* APPL... */ +}; + +data 'icl4' (128) { + $"0000 0000 0000 000F F000 00FF FF00 0000" /* ............. */ + $"0000 0000 0000 00FC CF0F FFFC CF00 0000" /* ........... */ + $"0000 0000 0000 0FCC BBFC DF1F 3F00 0000" /* .......̻.?... */ + $"0000 0000 0000 FCCB BFCD F1DF FF00 0000" /* ......˿... */ + $"0000 0000 000F CCCF FCDF 1DFF DDF0 0000" /* ......... */ + $"0000 0000 00FC CFFF CDF1 DFFD DDCF 0000" /* ....... */ + $"0000 0000 0FCC FFFC DF1D FFFD DCCC F000" /* ....... */ + $"0000 0000 FCCF FFFD F1DF FFFD CCCC CFFF" /* .... */ + $"0000 000F CCFF FFFF 1FFF FFCC CCCC DFFF" /* ..... */ + $"0000 00FC CFFF FFF1 FCCC CCCC CCCC DFFF" /* ... */ + $"0000 0FCC FFFC CFFD FFFD DDDC CCCC DFFF" /* ... */ + $"0000 FCCF FFCC CFFF FFFF FFDD DDCC DFFF" /* .. */ + $"000F CCFF FCFF FFCC FFF9 99FF FFDD DFFF" /* .. */ + $"00FC CFFF CCFF FFCC FFF0 0000 FFFF FFFF" /* ... */ + $"0FCC CFFC FFCF FFCF FFF0 0000 0F99 FFFF" /* .... */ + $"FCCC FFCC FFFC FCFF FFFF FFF0 0FFF FBBF" /* . */ + $"FCCC FFCC FFFF CFFF F00F FFF0 0FFF BBBF" /* .. */ + $"0FCC CFFF FFFC FFFF F00F FFF0 0FFB BBF0" /* ... */ + $"00FC CFFF CCCF F000 FFF0 0FF0 0FFB BF00" /* ..... */ + $"000F CCFF CCFF 0000 FFF0 0FFF FFBB F000" /* ...... */ + $"0000 FCCF FFF0 0FFF FFFF FFFF FBBF 0000" /* ..... */ + $"0000 0FCC FFF0 0FFF F00F FFFF BBFD DDDD" /* ..... */ + $"0000 00FC CFF0 0FFF F00F FFFB BFEE EEED" /* ..... */ + $"0000 000F CCFF 00FF F00F FFBB FEEE EEE0" /* ...... */ + $"0000 0000 FCCF F000 00FF FBBF AAEE EE00" /* ....... */ + $"0000 0000 0FCC FF00 0FFF BBFA AEEE E000" /* ........ */ + $"0000 0000 00FC CFFF FFF8 8FAA EEE0 0000" /* ....... */ + $"0000 0000 000F CCCF FB88 FAEE E000 0000" /* ......... */ + $"0000 0000 0000 FCCB B88F EEE0 0000 0000" /* ......˸.... */ + $"0000 0000 0000 0FCC BBFE EE00 0000 0000" /* .......̻..... */ + $"0000 0000 0000 00FC CFEE 0000 0000 0000" /* ............. */ + $"0000 0000 0000 000F FE00 0000 0000 0000" /* ............... */ +}; + +data 'icl8' (128) { + $"0000 0000 0000 0000 0000 0000 0000 00FF" /* ............... */ + $"FF00 0000 0000 FFFF FFFF 0000 0000 0000" /* ........... */ + $"0000 0000 0000 0000 0000 0000 0000 FF2C" /* .............., */ + $"2CFF 00FF FFFF FF13 13FF 0000 0000 0000" /* ,......... */ + $"0000 0000 0000 0000 0000 0000 00FF 2C2C" /* .............,, */ + $"3434 FF08 33FF 05FF D8FF 0000 0000 0000" /* 44.3....... */ + $"0000 0000 0000 0000 0000 0000 FF2C 2C34" /* ............,,4 */ + $"34FF 0833 FF05 33FF FFFF 0000 0000 0000" /* 4.3.3...... */ + $"0000 0000 0000 0000 0000 00FF 2C2C 2CFF" /* ...........,,, */ + $"FF08 33FF 0533 FFFF 3333 FF00 0000 0000" /* .3.333..... */ + $"0000 0000 0000 0000 0000 FF2C 2CFF FFFF" /* ..........,, */ + $"0833 FF05 33FF FF33 3333 08FF 0000 0000" /* .3.3333..... */ + $"0000 0000 0000 0000 00FF 2C2C FFFF FF08" /* .........,,. */ + $"33FF 0533 FFFF FF33 3308 0808 FF00 0000" /* 3.333...... */ + $"0000 0000 0000 0000 FF2C 2CFF FFFF FF33" /* ........,,3 */ + $"FF05 33FF FFFF FF33 0808 0808 08FF FFFF" /* .33..... */ + $"0000 0000 0000 00FF 2C2C FFFF FFFF FFFF" /* .......,, */ + $"05FF FFFF FFFF 0808 0808 0808 33FF FFFF" /* .......3 */ + $"0000 0000 0000 FF2C 2CFF FFFF FFFF FF05" /* ......,,. */ + $"FF08 0808 0808 0808 0808 0808 33FF FFFF" /* ...........3 */ + $"0000 0000 00FF 2C2C FFFF FF2A 2AFF FF33" /* .....,,**3 */ + $"FFFF FF33 3333 3308 0808 0808 33FF FFFF" /* 3333.....3 */ + $"0000 0000 FF2C 2CFF FFFF 2A2A 2AFF FFFF" /* ....,,*** */ + $"FFFF FFFF FFFF 3333 3333 0808 33FF FFFF" /* 3333..3 */ + $"0000 00FF 2C2C FFFF FF2A FFFF FFFF 2A2A" /* ...,,*** */ + $"FFFF FFE8 E8E8 FFFF FFFF 3333 33FF FFFF" /* 333 */ + $"0000 FF2C 2CFF FFFF 2A2A FFFF FFFF 2A2A" /* ..,,**** */ + $"FFFF FF00 0000 0000 FFFF FFFF FFFF FFFF" /* ..... */ + $"00FF 2C2C 2CFF FF2A FFFF 2AFF FFFF 2AFF" /* .,,,*** */ + $"FFFF FF00 0000 0000 00FF E8E8 FFFF FFFF" /* ...... */ + $"FF2C 2C2C FFFF 2A2A FFFF FF2A FF2A FFFF" /* ,,,**** */ + $"FFFF FFFF FFFF FF00 00FF FFFF FF34 34FF" /* ..44 */ + $"FF2C 2C2C FFFF 2A2A FFFF FFFF 2AFF FFFF" /* ,,,*** */ + $"FF00 00FF FFFF FF00 00FF FFFF 3434 34FF" /* ....444 */ + $"00FF 2C2C 2CFF FFFF FFFF FF2A FFFF FFFF" /* .,,,* */ + $"FF00 00FF FFFF FF00 00FF FF34 3434 FF00" /* ....444. */ + $"0000 FF2C 2CFF FFFF 2A2A 2AFF FF00 0000" /* ..,,***... */ + $"FFFF FF00 00FF FF00 00FF FF34 34FF 0000" /* ....44.. */ + $"0000 00FF 2C2C FFFF 2A2A FFFF 0000 0000" /* ...,,**.... */ + $"FFFF FF00 00FF FFFF FFFF 3434 FF00 0000" /* ..44... */ + $"0000 0000 FF2C 2CFF FFFF FF00 00FF FFFF" /* ....,,.. */ + $"FFFF FFFF FFFF FFFF FF34 34FF 0000 0000" /* 44.... */ + $"0000 0000 00FF 2C2C FFFF FF00 00FF FFFF" /* .....,,.. */ + $"FF00 00FF FFFF FFFF 3434 FFFA FAFA FAFA" /* ..44 */ + $"0000 0000 0000 FF2C 2CFF FF00 00FF FFFF" /* ......,,.. */ + $"FF00 00FF FFFF FF34 34FF FBFB FBFB FBFA" /* ..44 */ + $"0000 0000 0000 00FF 2C2C FFFF 0000 FFFF" /* .......,,.. */ + $"FF00 00FF FFFF 3434 FFFB FBFB FBFB FB00" /* ..44. */ + $"0000 0000 0000 0000 FF2C 2CFF FF00 0000" /* ........,,... */ + $"0000 FFFF FF34 34FF FDFD FCFC FCFB 0000" /* ..44.. */ + $"0000 0000 0000 0000 00FF 2C2C FFFF 0000" /* .........,,.. */ + $"00FF FFFF 3434 FFFD FDFC FCFB FB00 0000" /* .44... */ + $"0000 0000 0000 0000 0000 FF2C 2CFF FFFF" /* ..........,, */ + $"FFFF FFE1 E1FF FDFD FCFB FB00 0000 0000" /* ..... */ + $"0000 0000 0000 0000 0000 00FF 2C2C 2CFF" /* ...........,,, */ + $"FF34 E1E1 FFFD FCFB FB00 0000 0000 0000" /* 4....... */ + $"0000 0000 0000 0000 0000 0000 FF2C 2C34" /* ............,,4 */ + $"34E1 E1FF FCFB FB00 0000 0000 0000 0000" /* 4......... */ + $"0000 0000 0000 0000 0000 0000 00FF 2C2C" /* .............,, */ + $"3434 FFFB FBFB 0000 0000 0000 0000 0000" /* 44.......... */ + $"0000 0000 0000 0000 0000 0000 0000 FF2C" /* .............., */ + $"2CFF FBFB 0000 0000 0000 0000 0000 0000" /* ,............ */ + $"0000 0000 0000 0000 0000 0000 0000 00FF" /* ............... */ + $"FFFB 0000 0000 0000 0000 0000 0000 0000" /* .............. */ +}; + +data 'icl8' (129) { + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FF00 0000 0000 0000 0000 0000 0000 0000" /* ............... */ + $"0000 0000 0000 0000 0000 0000 0000 00FF" /* ............... */ + $"FF00 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B" /* .++++++++++++++ */ + $"2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B F9FF" /* ++++++++++++++ */ + $"FF00 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B" /* .++++++++++++++ */ + $"2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2BF9 F9FF" /* +++++++++++++ */ + $"FF00 2B2B 2B00 0000 0000 0000 0000 0000" /* .+++........... */ + $"0000 0000 0000 0000 0000 0000 F9F9 F9FF" /* ............ */ + $"FF00 2B2B 00FF FFFF FFFF FFFF 2A2A FFFF" /* .++.** */ + $"FFFF FFFF FFFF FFFF FFFF FFFF 00F9 F9FF" /* . */ + $"FF00 2B2B 00FF FFFF FFFF FF2A 2A2A FFFF" /* .++.*** */ + $"FFFF FFFF FFFF FFFF FFFF FFFF 00F9 F9FF" /* . */ + $"FF00 2B2B 00FF FFFF FFFF 2AFF FFFF FF2A" /* .++.** */ + $"2AFF FFFF FFFF FFFF FFFF FFFF 00F9 F9FF" /* *. */ + $"FF00 2B2B 00FF FFFF FF2A 2AFF FFFF FF2A" /* .++.*** */ + $"2AFF FFFF 0000 0000 00FF FFFF 00F9 F9FF" /* *...... */ + $"FF00 2B2B 00FF FFFF 2AFF FF2A FFFF FF2A" /* .++.*** */ + $"FFFF FFFF 0000 0000 0000 FFFF 00F9 F9FF" /* ....... */ + $"FF00 2B2B 00FF FF2A 2AFF FFFF 2AFF 2AFF" /* .++.**** */ + $"FFFF FFFF FFFF FFFF 0000 FFFF 00F9 F9FF" /* ... */ + $"FF00 2B2B 00FF FF2A 2AFF FFFF FF2A FFFF" /* .++.*** */ + $"FFFF 0000 FFFF FFFF 0000 FFFF 00F9 F9FF" /* ..... */ + $"FF00 2B2B 00FF FFFF FFFF FFFF 2AFF FFFF" /* .++.* */ + $"FFFF 0000 FFFF FFFF 0000 FFFF 00F9 F9FF" /* ..... */ + $"FF00 2B2B 00FF FFFF FF2A 2A2A FFFF 0000" /* .++.***.. */ + $"00FF FFFF 0000 FFFF 0000 FFFF 00F9 F9FF" /* ...... */ + $"FF00 2B2B 00FF FFFF FF2A 2AFF FF00 0000" /* .++.**... */ + $"00FF FFFF 0000 FFFF FFFF FFFF 00F9 F9FF" /* .... */ + $"FF00 2B2B 00FF FFFF FFFF FFFF 0000 FFFF" /* .++... */ + $"FFFF FFFF FFFF FFFF FFFF FFFF 00F9 F9FF" /* . */ + $"FF00 2B2B 00FF FFFF FFFF FFFF 0000 FFFF" /* .++... */ + $"FFFF 0000 FFFF FFFF FFFF FFFF 00F9 F9FF" /* ... */ + $"FF00 2B2B 00FF FFFF FFFF FFFF 0000 FFFF" /* .++... */ + $"FFFF 0000 FFFF FFFF FFFF FFFF 00F9 F9FF" /* ... */ + $"FF00 2B2B 00FF FFFF FFFF FFFF FF00 00FF" /* .++... */ + $"FFFF 0000 FFFF FFFF FFFF FFFF 00F9 F9FF" /* ... */ + $"FF00 2B2B 00FF FFFF FFFF FFFF FFFF 0000" /* .++... */ + $"0000 00FF FFFF FFFF FFFF FFFF 00F9 F9FF" /* .... */ + $"FF00 2B2B 00FF FFFF FFFF FFFF FFFF FF00" /* .++.. */ + $"0000 FFFF FFFF FFFF FFFF FFFF 00F9 F9FF" /* ... */ + $"FF00 2B2B F900 0000 0000 0000 0000 0000" /* .++........... */ + $"0000 0000 0000 0000 0000 0000 00F9 F9FF" /* ............. */ + $"FF00 F9F9 F9E3 E3E3 E3E3 E3F9 F9F9 F9F9" /* . */ + $"F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 F9FF" /* */ + $"FFF9 F9F9 F9E3 E3E3 E3E3 E3F9 F9F9 F9F9" /* */ + $"F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 F9FF" /* */ + $"FF00 0000 0000 0000 0000 0000 0000 0000" /* ............... */ + $"0000 0000 0000 0000 0000 0000 0000 00FF" /* ............... */ + $"FF00 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 0000" /* .++++++++++++.. */ + $"00FF 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2BFF" /* .+++++++++++++ */ + $"FF00 2BFC F9F9 F9F9 F9F9 F9F9 F9F9 002B" /* .+.+ */ + $"2BFF FFF9 F9F9 F9F9 F9F9 F9F9 2B2B 2BFF" /* ++++ */ + $"FF00 2BFC 2B2B 2B2B 2B2B 2B2B 2B2B 002B" /* .+++++++++++.+ */ + $"2BFF F92B 2B2B 2B2B 2B2B 2B2B 002B 2BFF" /* ++++++++++.++ */ + $"FF00 2B2B 0000 0000 0000 0000 0000 002B" /* .++...........+ */ + $"2BFF 2B00 0000 0000 0000 0000 2B2B 2BFF" /* ++.........+++ */ + $"FF00 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B FFFF" /* .++++++++++++ */ + $"FFFF 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2BFF" /* +++++++++++++ */ + $"FF00 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B" /* .++++++++++++++ */ + $"2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2B2B 2BFF" /* +++++++++++++++ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ +}; + +data 'ICN#' (128) { + $"0001 83C0 0002 5E40 0004 25C0 0008 49C0" /* ....^@..%..I */ + $"0011 9320 0027 2610 004E 4E08 009E 9E07" /* .. .'&..NN... */ + $"013F 7C07 027E 8007 04E6 E007 09C7 FC07" /* .?|..~.... */ + $"13BC FFC7 273C E0FF 46DD E07F 8CEB FE79" /* .'֣֣ */ + $"003F A3D6 A3D6 A3D6 0040 0000 0000 0000" /* .?֣֣.@...... */ + $"0041 0000 0000 0000 0042 0000 0000 0000" /* .A.......B...... */ + $"0043 0000 0000 0000 0044 0000 0000 0000" /* .C.......D...... */ + $"0045 0000 0000 0000 0046 0000 0000 0000" /* .E.......F...... */ + $"0047 0000 0000 0000 0048 0000 0000 0000" /* .G.......H...... */ + $"0049 0000 0000 0000 004A 0000 0000 0000" /* .I.......J...... */ + $"004B 0000 0000 0000 004C 0000 0000 0000" /* .K.......L...... */ + $"004D 0000 0000 0000 004E 0000 0000 0000" /* .M.......N...... */ + $"004F 0000 0000 0000 0050 0000 0000 0000" /* .O.......P...... */ + $"0051 0000 0000 0000 0052 0000 0000 0000" /* .Q.......R...... */ + $"0053 0000 0000 0000 0054 0000 0000 0000" /* .S.......T...... */ + $"0055 0000 0000 0000 0056 0000 0000 0000" /* .U.......V...... */ + $"0057 0000 0000 0000 0058 0000 0000 0000" /* .W.......X...... */ + $"0059 0000 0000 0000 005A 0000 0000 0000" /* .Y.......Z...... */ + $"005B 0000 0000 0000 005C 0000 0000 0000" /* .[.......\...... */ + $"005D 0000 0000 0000 005E 0000 0000 0000" /* .].......^...... */ + $"005F 0000 0000 0000 0060 0000 0000 0000" /* ._.......`...... */ + $"0061 0000 0000 0000 0062 0000 0000 0000" /* .a.......b...... */ + $"0063 0000 0000 0000 0064 0000 0000 0000" /* .c.......d...... */ + $"0065 0000 0000 0000 0066 0000 0000 0000" /* .e.......f...... */ + $"0067 0000 0000 0000 0068 0000 0000 0000" /* .g.......h...... */ + $"0069 0000 0000 0000 006A 0000 0000 0000" /* .i.......j...... */ + $"006B 0000 0000 0000 006C 0000 0000 0000" /* .k.......l...... */ + $"006D 0000 0000 0000 006E 0000 0000 0000" /* .m.......n...... */ + $"006F 0000 0000 0000 0070 0000 0000 0000" /* .o.......p...... */ + $"0071 0000 0000 0000 0072 0000 0000 0000" /* .q.......r...... */ + $"0073 0000 0000 0000 0074 0000 0000 0000" /* .s.......t...... */ + $"0075 0000 0000 0000 0076 0000 0000 0000" /* .u.......v...... */ + $"0077 0000 0000 0000 0078 0000 0000 0000" /* .w.......x...... */ + $"0079 0000 0000 0000 007A 0000 0000 0000" /* .y.......z...... */ + $"007B 0000 0000 0000 007C 0000 0000 0000" /* .{.......|...... */ + $"007D 0000 0000 0000 007E 0000 0000 0000" /* .}.......~...... */ + $"007F 0000 0000 0000 0080 0000 0000 0000" /* ............... */ + $"0081 0000 0000 0000 0082 0000 0000 0000" /* .............. */ + $"0083 0000 0000 0000 0084 0000 0000 0000" /* .............. */ + $"0085 0000 0000 0000 0086 0000 0000 0000" /* .............. */ + $"0087 0000 0000 0000 0088 0000 0000 0000" /* .............. */ + $"0089 0000 0000 0000 008A 0000 0000 0000" /* .............. */ + $"008B 0000 0000 0000 008C 0000 0000 0000" /* .............. */ + $"008D 0000 0000 0000 008E 0000 0000 0000" /* .............. */ + $"008F 0000 0000 0000 0090 0000 0000 0000" /* .............. */ + $"0091 0000 0000 0000 0092 0000 0000 0000" /* .............. */ + $"0093 0000 0000 0000 0094 0000 0000 0000" /* .............. */ + $"0095 0000 0000 0000 0096 0000 0000 0000" /* .............. */ + $"0097 0000 0000 0000 0098 0000 0000 0000" /* .............. */ + $"0099 0000 0000 0000 009A 0000 0000 0000" /* .............. */ + $"009B 0000 0000 0000 009C 0000 0000 0000" /* .............. */ + $"009D 0000 0000 0000 009E 0000 0000 0000" /* .............. */ + $"009F 0000 0000 0000 00A0 0000 0000 0000" /* .............. */ + $"00A1 0000 0000 0000 00A2 0000 0000 0000" /* .............. */ + $"00A3 0000 0000 0000 00A4 0000 0000 0000" /* .............. */ + $"00A5 0000 0000 0000 00A6 0000 0000 0000" /* .............. */ + $"00A7 0000 0000 0000 00A8 0000 0000 0000" /* .............. */ + $"00A9 0000 0000 0000 00AA 0000 0000 0000" /* .............. */ + $"00AB 0000 0000 0000 00AC 0000 0000 0000" /* .............. */ + $"00AD 0000 0000 0000 00AE 0000 0000 0000" /* .............. */ + $"00AF 0000 0000 0000 00B0 0000 0000 0000" /* .............. */ + $"00B1 0000 0000 0000 00B2 0000 0000 0000" /* .............. */ + $"00B3 0000 0000 0000 00B4 0000 0000 0000" /* .............. */ + $"00B5 0000 0000 0000 00B6 0000 0000 0000" /* .............. */ + $"00B7 0000 0000 0000 00B8 0000 0000 0000" /* .............. */ + $"00B9 0000 0000 0000 00BA 0000 0000 0000" /* .............. */ + $"00BB 0000 0000 0000 00BC 0000 0000 0000" /* .............. */ + $"00BD 0000 0000 0000 00BE 0000 0000 0000" /* .............. */ + $"00BF 0000 0000 0000 00C0 0000 0000 0000" /* .............. */ + $"00C1 0000 0000 0000 00C2 0000 0000 0000" /* .............. */ + $"00C3 0000 0000 0000 00C4 0000 0000 0000" /* .............. */ + $"00C5 0000 0000 0000 00C6 0000 0000 0000" /* .............. */ + $"00C7 0000 0000 0000 00C8 0000 0000 0000" /* .............. */ + $"00C9 0000 0000 0000 00CA 0000 0000 0000" /* .............. */ + $"00CB 0000 0000 0000 00CC 0000 0000 0000" /* .............. */ + $"00CD 0000 0000 0000 00CE 0000 0000 0000" /* .............. */ + $"00CF 0000 0000 0000 00D0 0000 0000 0000" /* .............. */ + $"00D1 0000 0000 0000 00D2 0000 0000 0000" /* .............. */ + $"00D3 0000 0000 0000 00D4 0000 0000 0000" /* .............. */ + $"00D5 0000 0000 0000 00D6 0000 0000 0000" /* .............. */ + $"00D7 0000 0000 0000 00D8 0000 0000 0000" /* .............. */ + $"00D9 0000 0000 0000 00DA 0000 0000 0000" /* .............. */ + $"00DB 0000 0000 0000 00DC 0000 0000 0000" /* .............. */ + $"00DD 0000 0000 0000 00DE 0000 0000 0000" /* .............. */ + $"00DF 0000 0000 0000 00E0 0000 0000 0000" /* .............. */ + $"00E1 0000 0000 0000 00E2 0000 0000 0000" /* .............. */ + $"00E3 0000 0000 0000 00E4 0000 0000 0000" /* .............. */ + $"00E5 0000 0000 0000 00E6 0000 0000 0000" /* .............. */ + $"00E7 0000 0000 0000 00E8 0000 0000 0000" /* .............. */ + $"00E9 0000 0000 0000 00EA 0000 0000 0000" /* .............. */ + $"00EB 0000 0000 0000 00EC 0000 0000 0000" /* .............. */ + $"00ED 0000 0000 0000 00EE 0000 0000 0000" /* .............. */ + $"00EF 0000 0000 0000 00F0 0000 0000 0000" /* .............. */ + $"00F1 0000 0000 0000 00F2 0000 0000 0000" /* .............. */ + $"00F3 0000 0000 0000 00F4 0000 0000 0000" /* .............. */ + $"00F5 0000 0000 0000 00F6 0000 0000 0000" /* .............. */ + $"00F7 0000 0000 0000 00F8 0000 0000 0000" /* .............. */ + $"00F9 0000 0000 0000 00FA 0000 0000 0000" /* .............. */ + $"00FB 0000 0000 0000 00FC 0000 0000 0000" /* .............. */ + $"00FD 0000 0000 0000 00FE 0000 0000 0000" /* .............. */ + $"00FF 0000 0000 0000" /* ....... */ +}; + +data 'DLOG' (128, "About") { + $"0028 0028 0154 0209 0001 0100 0100 0000" /* .(.(.T......... */ + $"0000 0080 00" /* .... */ +}; + +data 'DITL' (128) { + $"0003 0000 0000 010B 0199 011F 01D3 0402" /* .............. */ + $"4F4B 0000 0000 0003 000C 0064 01D2 88DC" /* OK.........d.҈ */ + $"424F 4348 5320 6973 2043 6F70 7972 6967" /* BOCHS is Copyrig */ + $"6874 2031 3939 342D 3139 3939 2062 7920" /* ht 1994-1999 by */ + $"4B65 7669 6E20 502E 204C 6177 746F 6E2E" /* Kevin P. Lawton. */ + $"0D0D 424F 4348 5320 6973 2063 6F6D 6D65" /* ..BOCHS is comme */ + $"7263 6961 6C20 736F 6674 7761 7265 2E0D" /* rcial software.. */ + $"0D46 6F72 206D 6F72 6520 696E 666F 726D" /* .For more inform */ + $"6174 696F 6E2C 2072 6561 6420 7468 6520" /* ation, read the */ + $"6669 6C65 2027 4C49 4345 4E53 4527 2069" /* file 'LICENSE' i */ + $"6E63 6C75 6465 6420 696E 2074 6865 2062" /* ncluded in the b */ + $"6F63 6873 2064 6973 7472 6962 7574 696F" /* ochs distributio */ + $"6E2E 2020 4966 2079 6F75 2064 6F6E 2774" /* n. If you don't */ + $"2068 6176 6520 6163 6365 7373 2074 6F20" /* have access to */ + $"7468 6973 2066 696C 652C 206F 7220 6861" /* this file, or ha */ + $"7665 2071 7565 7374 696F 6E73 0000 0000" /* ve questions.... */ + $"0062 000C 00DA 01D3 88B9 7265 6761 7264" /* .b....ӈregard */ + $"696E 6720 7468 6520 6C69 6365 6E73 696E" /* ing the licensin */ + $"6720 706F 6C69 6379 2C20 7468 6520 6175" /* g policy, the au */ + $"7468 6F72 206D 6179 2062 6520 636F 6E74" /* thor may be cont */ + $"6163 7465 6420 7669 613A 0D0D 5553 204D" /* acted via:..US M */ + $"6169 6C3A 2020 4B65 7669 6E20 4C61 7774" /* ail: Kevin Lawt */ + $"6F6E 0D20 2020 2020 2020 2020 2020 2020" /* on. */ + $"2020 3532 3820 4C65 7869 6E67 746F 6E20" /* 528 Lexington */ + $"5374 2E0D 2020 2020 2020 2020 2020 2020" /* St.. */ + $"2020 2057 616C 7468 616D 2C20 4D41 2030" /* Waltham, MA 0 */ + $"3231 3534 0D0D 454D 6169 6C3A 2020 2020" /* 2154..EMail: */ + $"626F 6368 7340 776F 726C 642E 7374 642E" /* bochs@world.std. */ + $"636F 6D61 0000 0000 00DB 000C 0102 01D5" /* coma.......... */ + $"8863 4D61 6342 6F63 6873 2070 6F72 7420" /* cMacBochs port */ + $"6279 2044 6176 6964 2042 6174 7465 7268" /* by David Batterh */ + $"616D 203C 6472 6261 7474 6572 4070 726F" /* am */ + $"200D 7769 7468 2063 6F6E 7472 6962 7574" /* .with contribut */ + $"696F 6E73 2066 726F 6D20 5469 6D20 5365" /* ions from Tim Se */ + $"6E65 6361 6C00" /* necal. */ +}; + +data 'DITL' (200) { + $"0001 0000 0000 006B 0129 007F 0163 0404" /* .......k.)...c.. */ + $"5175 6974 0000 0000 000C 0053 0060 0163" /* Quit.......S.`.c */ + $"8892 5468 6520 426F 6368 7320 5043 2065" /* The Bochs PC e */ + $"6D75 6C61 746F 7220 6861 7320 6861 6C74" /* mulator has halt */ + $"6564 2E0D 0D49 6620 796F 7520 6469 646E" /* ed...If you didn */ + $"2774 2065 7870 6563 7420 7468 6973 2074" /* 't expect this t */ + $"6F20 6861 7070 656E 2C20 636F 6E73 756C" /* o happen, consul */ + $"7420 796F 7572 206C 6F67 2066 696C 6520" /* t your log file */ + $"2874 7970 6963 616C 6C79 2022 626F 6368" /* (typically "boch */ + $"732E 6F75 7422 2920 746F 2066 696E 6420" /* s.out") to find */ + $"6F75 7420 7768 6174 2077 656E 7420 7772" /* out what went wr */ + $"6F6E 672E" /* ong. */ +}; + +data 'cicn' (128) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 3DFF FFF8 7FFF FFFC 7FFF" /* ......=.. */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 3FFF" /* ...? */ + $"FFFC 0000 0000 3DFF FFF8 4220 0104 4220" /* ....=B ..B */ + $"0106 4220 F106 4A20 F15E 4E20 F176 4A20" /* ..B .J ^N vJ */ + $"F15E 4A20 F106 4220 F106 4220 0106 4220" /* ^J .B .B ..B */ + $"0106 421F FF06 4000 0006 4000 0006 41FF" /* ..B..@...@...A */ + $"FFC6 4200 0006 4200 0006 4200 0006 4200" /* B...B...B...B. */ + $"8006 4200 8006 4201 4006 4201 4006 4202" /* .B..B.@.B.@.B. */ + $"2006 4202 2006 4207 F006 4204 1006 5A04" /* .B. .B..B...Z. */ + $"101E 5A00 001E 4200 0006 7FFF FFDE 3FFF" /* ..Z...B....? */ + $"FFFC 0000 0000 0000 0005 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 CCCC CCCC FFFF 0002 6666 6666" /* ....ffff */ + $"CCCC 0003 BBBB BBBB BBBB 0004 5555 5555" /* ....UUUU */ + $"5555 000F 0000 0000 0000 0000 0000 0000" /* UU.............. */ + $"0000 0000 0000 0000 0000 00FF FF0F FFFF" /* ............ */ + $"FFFF FFFF FFFF FFFF F000 0F00 0041 11F0" /* ....A. */ + $"0000 0000 001F 0000 1F00 0F01 1143 3320" /* .............C3 */ + $"1010 1111 1114 0113 32F0 0F01 1143 3320" /* ........2...C3 */ + $"0100 4444 0114 0133 32F0 0F01 2143 3320" /* ..DD...32..!C3 */ + $"1010 4222 0114 0F1F F4F0 0F03 2243 3320" /* ..B"......"C3 */ + $"0110 4222 0114 0FFF 1FF0 0F01 2343 3320" /* ..B"......#C3 */ + $"1110 4222 0114 0F1F F2F0 0F01 2343 3320" /* ..B"......#C3 */ + $"1110 4222 0114 0333 32F0 0F01 3343 3320" /* ..B"...32..3C3 */ + $"1110 4222 0114 0333 32F0 0F01 3343 3320" /* ..B"...32..3C3 */ + $"1110 0000 0114 0333 32F0 0F01 3343 3320" /* .......32..3C3 */ + $"1111 1111 1114 0333 32F0 0F01 3343 3334" /* .......32..3C34 */ + $"4444 4444 4444 0333 32F0 0F01 3330 0000" /* DDDDDD.32..30.. */ + $"0000 0000 0000 0333 32F0 0F01 3333 3333" /* .......32..3333 */ + $"3333 3333 3333 3333 32F0 0F01 3334 4444" /* 333333332..34DD */ + $"4444 4444 4444 4433 32F0 0F01 3343 3333" /* DDDDDDD32..3C33 */ + $"3333 3333 3333 3303 32F0 0F01 3343 3333" /* 3333333.2..3C33 */ + $"3333 3333 3333 3303 32F0 0F01 3343 3333" /* 3333333.2..3C33 */ + $"3333 3333 3333 3303 32F0 0F01 3343 3333" /* 3333333.2..3C33 */ + $"3333 F333 3333 3303 32F0 0F01 3343 3333" /* 333333.2..3C33 */ + $"3333 F333 3333 3303 32F0 0F01 3343 3333" /* 333333.2..3C33 */ + $"333F 3F33 3333 3303 32F0 0F01 3343 3333" /* 3??3333.2..3C33 */ + $"333F 3F33 3333 3303 32F0 0F01 3343 3333" /* 3??3333.2..3C33 */ + $"33F3 33F3 3333 3303 32F0 0F01 3343 3333" /* 33333.2..3C33 */ + $"33F3 33F3 3333 3303 32F0 0F01 3343 3333" /* 33333.2..3C33 */ + $"3FFF FFFF 3333 3303 32F0 0F01 3343 3333" /* ?333.2..3C33 */ + $"3F33 333F 3333 3303 32F0 0F02 2343 3333" /* ?33?333.2..#C33 */ + $"3F33 333F 3333 3302 22F0 0F0F F043 3333" /* ?33?333."..C33 */ + $"3333 3333 3333 330F F2F0 0F00 0043 3333" /* 3333333....C33 */ + $"3333 3333 3333 3303 32F0 0F22 2242 2222" /* 3333333.2.""B"" */ + $"2222 2222 2222 2212 22F0 00FF FFFF FFFF" /* """"""".". */ + $"FFFF FFFF FFFF FFFF FF00" /* . */ +}; + +data 'cicn' (129) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 3DFF FFF8 7FFF FFFC 7FFF" /* ......=.. */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE FFFF FFFF FFFF FFFF FFFF" /* . */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 3FFF" /* ...? */ + $"FFFC 0000 0000 3DFF FFF8 427F FF04 43FF" /* ....=B..C */ + $"FF86 43F0 FFC6 4FE0 F3FE 4F20 F1F6 5E20" /* COO ^ */ + $"F3FE 7E20 F7BE 7A20 FF1E 7A20 1F1E 7220" /* ~ z .z ..r */ + $"3D0E 721F FF0E E000 F007 E001 E007 E1FF" /* =.r...... */ + $"FFC7 E207 8007 E20F 0007 E21E 0007 E23C" /* ........< */ + $"8007 7278 800E 72F1 400E 7BE1 401E 7BC2" /* .rx.r@.{@.{ */ + $"201E 7F82 203E 5F07 F07E 4F04 10F6 5FC4" /* .. >_.~O.._ */ + $"13FE 5BF0 0FDE 43FF FF86 7FFF FFDE 3FFF" /* .[.C.? */ + $"FFFC 0000 0000 0000 0006 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 CCCC CCCC FFFF 0002 6666 6666" /* ....ffff */ + $"CCCC 0003 BBBB BBBB BBBB 0004 5555 5555" /* ....UUUU */ + $"5555 0005 DDDD 0000 0000 000F 0000 0000" /* UU............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 00FF FF0F FFFF 5555 5555 FFFF FFFF" /* ....UUUU */ + $"F000 0F00 0041 1555 5555 5555 555F 0000" /* ....A.UUUUUU_.. */ + $"1F00 0F01 1145 5555 5555 5555 5555 5113" /* .....EUUUUUUUUQ. */ + $"32F0 0F01 1155 5555 0100 4444 5555 5533" /* 2...UUU..DDUUU3 */ + $"32F0 0F01 2555 5520 1010 4222 0155 555F" /* 2..%UU ..B".UU_ */ + $"F4F0 0F03 5555 3320 0110 4222 0115 5555" /* ..UU3 ..B"..UU */ + $"1FF0 0F05 5553 3320 1110 4222 0155 5555" /* ...US3 ..B".UUU */ + $"52F0 0F55 5543 3320 1110 4222 0555 5355" /* R.UUC3 ..B".USU */ + $"55F0 0F55 5343 3320 1110 4222 5555 0335" /* U.USC3 ..B"UU.5 */ + $"55F0 0555 5343 3320 1110 0005 5554 0335" /* U.USC3 ....UT.5 */ + $"5550 0555 3343 3320 1111 1155 5514 0333" /* UP.U3C3 ...UU..3 */ + $"5550 0555 3343 3334 4444 4555 5444 0333" /* UP.U3C34DDEUTD.3 */ + $"5550 5551 3330 0000 0000 5555 0000 0333" /* UPUQ30....UU...3 */ + $"3555 5551 3333 3333 3335 5553 3333 3333" /* 5UUQ333335US3333 */ + $"3555 5551 3334 4444 4455 5544 4444 4433" /* 5UUQ34DDDUUDDDD3 */ + $"3555 5551 3343 3333 3555 5333 3333 3303" /* 5UUQ3C335US3333. */ + $"3555 5551 3343 3333 5555 3333 3333 3303" /* 5UUQ3C33UU33333. */ + $"3555 5551 3343 3335 5553 3333 3333 3303" /* 5UUQ3C35US33333. */ + $"3555 5551 3343 3355 5533 F333 3333 3303" /* 5UUQ3C3UU33333. */ + $"3555 0555 3343 3555 5333 F333 3333 3303" /* 5U.U3C5US33333. */ + $"5550 0555 3343 5555 333F 3F33 3333 3303" /* UP.U3CUU3??3333. */ + $"5550 0555 5345 5553 333F 3F33 3333 3305" /* UP.USEUS3??3333. */ + $"5550 0F55 5355 5533 33F3 33F3 3333 3305" /* UP.USUU333333. */ + $"55F0 0F55 5555 5333 33F3 33F3 3333 3355" /* U.UUUS333333U */ + $"55F0 0F05 5555 3333 3FFF FFFF 3333 3555" /* U..UU33?335U */ + $"52F0 0F01 5555 3333 3F33 333F 3333 5555" /* R..UU33?33?33UU */ + $"32F0 0F02 2555 5533 3F33 333F 3355 5552" /* 2..%UU3?33?3UUR */ + $"22F0 0F0F F055 5555 3333 3333 5555 550F" /* "..UUU3333UUU. */ + $"F2F0 0F00 0045 5555 5555 5555 5555 5303" /* ...EUUUUUUUUS. */ + $"32F0 0F22 2242 2555 5555 5555 5552 2212" /* 2.""B%UUUUUUR". */ + $"22F0 00FF FFFF FFFF 5555 5555 FFFF FFFF" /* ".UUUU */ + $"FF00" /* . */ +}; + +data 'cicn' (131) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 3DFF FFF8 7FFF FFFC 7FFF" /* ......=.. */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE FFFF FFFF FFFF FFFF FFFF" /* . */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 3FFF" /* ...? */ + $"FFFC 0000 0000 3DFF FFF8 427F FF04 43FF" /* ....=B..C */ + $"FF86 43F0 FFC6 4FE0 F3FE 4F20 F1F6 5E20" /* COO ^ */ + $"F3FE 7E20 F7BE 7A20 FF1E 7A20 1F1E 7220" /* ~ z .z ..r */ + $"3D0E 721F FF0E E000 F007 E001 E007 E1FF" /* =.r...... */ + $"FFC7 E207 8007 E20F 0007 E21E 0007 E23F" /* ........? */ + $"E007 727C 100E 72F4 100E 7BE7 E01E 7BC4" /* .r|..r..{.{ */ + $"101E 7F84 103E 5F04 107E 4F04 10F6 5FC7" /* ....>_..~O.._ */ + $"E3FE 5BF0 0FDE 43FF FF86 7FFF FFDE 3FFF" /* [.C.? */ + $"FFFC 0000 0000 0000 0006 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 CCCC CCCC FFFF 0002 6666 6666" /* ....ffff */ + $"CCCC 0003 BBBB BBBB BBBB 0004 5555 5555" /* ....UUUU */ + $"5555 0005 DDDD 0000 0000 000F 0000 0000" /* UU............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 00FF FF0F FFFF 5555 5555 FFFF FFFF" /* ....UUUU */ + $"F000 0F00 0041 1555 5555 5555 555F 0000" /* ....A.UUUUUU_.. */ + $"1F00 0F01 1145 5555 5555 5555 5555 5113" /* .....EUUUUUUUUQ. */ + $"32F0 0F01 1155 5555 0100 4444 5555 5533" /* 2...UUU..DDUUU3 */ + $"32F0 0F01 2555 5520 1010 4222 0155 555F" /* 2..%UU ..B".UU_ */ + $"F4F0 0F03 5555 3320 0110 4222 0115 5555" /* ..UU3 ..B"..UU */ + $"1FF0 0F05 5553 3320 1110 4222 0155 5555" /* ...US3 ..B".UUU */ + $"52F0 0F55 5543 3320 1110 4222 0555 5355" /* R.UUC3 ..B".USU */ + $"55F0 0F55 5343 3320 1110 4222 5555 0335" /* U.USC3 ..B"UU.5 */ + $"55F0 0555 5343 3320 1110 0005 5554 0335" /* U.USC3 ....UT.5 */ + $"5550 0555 3343 3320 1111 1155 5514 0333" /* UP.U3C3 ...UU..3 */ + $"5550 0555 3343 3334 4444 4555 5444 0333" /* UP.U3C34DDEUTD.3 */ + $"5550 5551 3330 0000 0000 5555 0000 0333" /* UPUQ30....UU...3 */ + $"3555 5551 3333 3333 3335 5553 3333 3333" /* 5UUQ333335US3333 */ + $"3555 5551 3334 4444 4455 5544 4444 4433" /* 5UUQ34DDDUUDDDD3 */ + $"3555 5551 3343 3333 3555 5333 3333 3303" /* 5UUQ3C335US3333. */ + $"3555 5551 3343 3333 5555 3333 3333 3303" /* 5UUQ3C33UU33333. */ + $"3555 5551 3343 3335 5553 3333 3333 3303" /* 5UUQ3C35US33333. */ + $"3555 5551 3343 3355 55FF FFF3 3333 3303" /* 5UUQ3C3UU333. */ + $"3555 0555 3343 3555 5F33 333F 3333 3303" /* 5U.U3C5U_33?333. */ + $"5550 0555 3343 5555 3F33 333F 3333 3303" /* UP.U3CUU?33?333. */ + $"5550 0555 5345 5553 3FFF FFF3 3333 3305" /* UP.USEUS?333. */ + $"5550 0F55 5355 5533 3F33 333F 3333 3305" /* UP.USUU3?33?333. */ + $"55F0 0F55 5555 5333 3F33 333F 3333 3355" /* U.UUUS3?33?333U */ + $"55F0 0F05 5555 3333 3F33 333F 3333 3555" /* U..UU33?33?335U */ + $"52F0 0F01 5555 3333 3F33 333F 3333 5555" /* R..UU33?33?33UU */ + $"32F0 0F02 2555 5533 3FFF FFF3 3355 5552" /* 2..%UU3?3UUR */ + $"22F0 0F0F F055 5555 3333 3333 5555 550F" /* "..UUU3333UUU. */ + $"F2F0 0F00 0045 5555 5555 5555 5555 5303" /* ...EUUUUUUUUS. */ + $"32F0 0F22 2242 2555 5555 5555 5552 2212" /* 2.""B%UUUUUUR". */ + $"22F0 00FF FFFF FFFF 5555 5555 FFFF FFFF" /* ".UUUU */ + $"FF00" /* . */ +}; + +data 'cicn' (130) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 3DFF FFF8 7FFF FFFC 7FFF" /* ......=.. */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF" /* .... */ + $"FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE 3FFF" /* ...? */ + $"FFFC 0000 0000 3DFF FFF8 4220 0104 4220" /* ....=B ..B */ + $"0106 4220 F106 4A20 F15E 4E20 F176 4A20" /* ..B .J ^N vJ */ + $"F15E 4A20 F106 4220 F106 4220 0106 4220" /* ^J .B .B ..B */ + $"0106 421F FF06 4000 0006 4000 0006 41FF" /* ..B..@...@...A */ + $"FFC6 4200 0006 4200 0006 4200 0006 4207" /* B...B...B...B. */ + $"E006 4204 1006 4204 1006 4207 E006 4204" /* .B...B...B..B. */ + $"1006 4204 1006 4204 1006 4204 1006 5A07" /* ..B...B...B...Z. */ + $"E01E 5A00 001E 4200 0006 7FFF FFDE 3FFF" /* .Z...B....? */ + $"FFFC 0000 0000 0000 0005 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 CCCC CCCC FFFF 0002 6666 6666" /* ....ffff */ + $"CCCC 0003 BBBB BBBB BBBB 0004 5555 5555" /* ....UUUU */ + $"5555 000F 0000 0000 0000 0000 0000 0000" /* UU.............. */ + $"0000 0000 0000 0000 0000 00FF FF0F FFFF" /* ............ */ + $"FFFF FFFF FFFF FFFF F000 0F00 0041 11F0" /* ....A. */ + $"0000 0000 001F 0000 1F00 0F01 1143 3320" /* .............C3 */ + $"1010 1111 1114 0113 32F0 0F01 1143 3320" /* ........2...C3 */ + $"0100 4444 0114 0133 32F0 0F01 2143 3320" /* ..DD...32..!C3 */ + $"1010 4222 0114 0F1F F4F0 0F03 2243 3320" /* ..B"......"C3 */ + $"0110 4222 0114 0FFF 1FF0 0F01 2343 3320" /* ..B"......#C3 */ + $"1110 4222 0114 0F1F F2F0 0F01 2343 3320" /* ..B"......#C3 */ + $"1110 4222 0114 0333 32F0 0F01 3343 3320" /* ..B"...32..3C3 */ + $"1110 4222 0114 0333 32F0 0F01 3343 3320" /* ..B"...32..3C3 */ + $"1110 0000 0114 0333 32F0 0F01 3343 3320" /* .......32..3C3 */ + $"1111 1111 1114 0333 32F0 0F01 3343 3334" /* .......32..3C34 */ + $"4444 4444 4444 0333 32F0 0F01 3330 0000" /* DDDDDD.32..30.. */ + $"0000 0000 0000 0333 32F0 0F01 3333 3333" /* .......32..3333 */ + $"3333 3333 3333 3333 32F0 0F01 3334 4444" /* 333333332..34DD */ + $"4444 4444 4444 4433 32F0 0F01 3343 3333" /* DDDDDDD32..3C33 */ + $"3333 3333 3333 3303 32F0 0F01 3343 3333" /* 3333333.2..3C33 */ + $"3333 3333 3333 3303 32F0 0F01 3343 3333" /* 3333333.2..3C33 */ + $"3333 3333 3333 3303 32F0 0F01 3343 3333" /* 3333333.2..3C33 */ + $"3FFF FFF3 3333 3303 32F0 0F01 3343 3333" /* ?333.2..3C33 */ + $"3F33 333F 3333 3303 32F0 0F01 3343 3333" /* ?33?333.2..3C33 */ + $"3F33 333F 3333 3303 32F0 0F01 3343 3333" /* ?33?333.2..3C33 */ + $"3FFF FFF3 3333 3303 32F0 0F01 3343 3333" /* ?333.2..3C33 */ + $"3F33 333F 3333 3303 32F0 0F01 3343 3333" /* ?33?333.2..3C33 */ + $"3F33 333F 3333 3303 32F0 0F01 3343 3333" /* ?33?333.2..3C33 */ + $"3F33 333F 3333 3303 32F0 0F01 3343 3333" /* ?33?333.2..3C33 */ + $"3F33 333F 3333 3303 32F0 0F02 2343 3333" /* ?33?333.2..#C33 */ + $"3FFF FFF3 3333 3302 22F0 0F0F F043 3333" /* ?333."..C33 */ + $"3333 3333 3333 330F F2F0 0F00 0043 3333" /* 3333333....C33 */ + $"3333 3333 3333 3303 32F0 0F22 2242 2222" /* 3333333.2.""B"" */ + $"2222 2222 2222 2212 22F0 00FF FFFF FFFF" /* """"""".". */ + $"FFFF FFFF FFFF FFFF FF00" /* . */ +}; + +data 'cicn' (134) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 0000 7C00 0003 FF00 0007" /* ........|...... */ + $"8380 0006 01C0 000F 00E0 007F E070 00FF" /* ........p. */ + $"F030 00FF F030 00FF F018 01FF F818 01FF" /* 0.0..... */ + $"F818 01FF F80C 03FF FC0C 03FF FC0C 03FF" /* ........ */ + $"FC04 03FF FC04 07FF FE00 07FF FE00 07FF" /* ........ */ + $"FE00 07FF FE00 07FF FE00 07FF FE00 07FF" /* ........ */ + $"FE00 07FF FE00 07FF FE00 03FF FE00 03FF" /* ........ */ + $"FC00 01FF FC00 01FF F800 00FF F000 003F" /* ........? */ + $"C000 0000 0000 0000 7C00 0003 FF00 0007" /* .......|...... */ + $"8380 0006 01C0 000F 00E0 007F E070 0080" /* ........p. */ + $"1030 0080 1030 0080 1018 0100 0818 0100" /* .0..0......... */ + $"0818 0100 080C 0200 040C 03FF FC0C 0200" /* .............. */ + $"0404 0200 0404 0400 0200 0500 0200 0500" /* ................ */ + $"0200 0500 0200 0500 0200 0500 0200 0500" /* ................ */ + $"0200 0500 0200 0480 0200 0280 0200 0242" /* .............B */ + $"0400 0146 0400 0106 0800 00C0 3000 003F" /* ...F.......0..? */ + $"C000 0000 0000 0000 0005 0000 FFFF FFFF" /* ........... */ + $"FFFF 0001 BBBB BBBB BBBB 0002 8888 8888" /* .... */ + $"8888 0003 DDDD DDDD DDDD 0004 EEEE EEEE" /* .... */ + $"EEEE 000F 0000 0000 0000 0000 0000 0000" /* .............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0222 2200 0000 0000 0000 0000 0000" /* ...""........... */ + $"0022 2222 2222 0000 0000 0000 0000 0000" /* .""""".......... */ + $"0222 2000 0022 2000 0000 0000 0000 0000" /* ." .." ......... */ + $"0220 0000 0002 2200 0000 0000 0000 0000" /* . ...."......... */ + $"2222 0000 0000 2220 0000 0000 0000 0FFF" /* ""...." ....... */ + $"FFFF FFF0 0000 0222 0000 0000 0000 F211" /* ..."....... */ + $"1111 110F 0000 0022 0000 0000 0000 F211" /* ......."....... */ + $"1111 110F 0000 0022 0000 0000 0000 F211" /* ......."....... */ + $"4111 110F 0000 0002 2000 0000 000F 2314" /* A....... .....#. */ + $"4111 1110 F000 0002 2000 0000 000F 2314" /* A...... .....#. */ + $"1111 1110 F000 0002 2000 0000 000F 2344" /* ....... .....#D */ + $"1111 1110 F000 0000 2200 0000 00F2 1311" /* ......."...... */ + $"1111 1111 0F00 0000 2200 0000 00F2 2222" /* ........"...."" */ + $"2222 2222 2F00 0000 2200 0000 00F2 1311" /* """"/..."...... */ + $"1111 1111 0F00 0000 0200 0000 00F2 1311" /* ............... */ + $"1111 1111 0F00 0000 0200 0000 0F21 1311" /* .............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1311" /* ............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1311" /* ............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1311" /* ............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1311" /* ............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1311" /* ............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1311" /* ............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1311" /* ............!.. */ + $"1111 1111 10F0 0000 0000 0000 0F21 1131" /* ............!.1 */ + $"1111 1111 10F0 0000 0000 0000 00F1 1133" /* .............3 */ + $"1121 1111 10F0 0000 0000 0000 00F2 1113" /* .!............ */ + $"3221 1111 0F00 0000 0000 0000 000F 2111" /* 2!............!. */ + $"1221 1111 0F00 0000 0000 0000 000F 2211" /* .!............". */ + $"1111 1100 F000 0000 0000 0000 0000 FF22" /* ............." */ + $"2110 00FF 0000 0000 0000 0000 0000 00FF" /* !............. */ + $"FFFF FF00 0000 0000 0000" /* ....... */ +}; + +data 'cicn' (135) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 000F FC00 007F FF00 01FF" /* ............. */ + $"FF80 03F6 0FC0 07CF 03E0 0F7F E1F0 1EFF" /* ....... */ + $"F3F8 3CFF F7BC 38FF FF1C 79FF FE1E 71FF" /* <8.y.q */ + $"FC1E 71FF F80E E3FF FC0F E3FF FC0F E3FF" /* .q... */ + $"FC07 E3FF FC07 E7FF FE07 E7FF FE07 E7FF" /* .... */ + $"FE07 77FF FE0E 77FF FE0E 7FFF FE1E 3FFF" /* .w.w...? */ + $"FE1C 3FFF FE3C 1FFF FE78 0FFF FEF0 07FF" /* .?<.x.. */ + $"FFE0 03FF FFC0 01FF FF80 00FF FE00 003F" /* .....? */ + $"F000 0000 0000 000F FC00 007F FF00 01FF" /* ............ */ + $"FF80 03F6 0FC0 07CF 03E0 0F7F E1F0 1E80" /* ....... */ + $"13F8 3C80 17BC 3880 1F1C 7900 1E1E 7100" /* .<.8..y...q. */ + $"3C1E 7100 780E E200 F40F E3FF FC0F E203" /* <.q.x..... */ + $"C407 E207 8407 E40F 0207 E51E 0207 E53C" /* .........< */ + $"0207 7578 020E 75F0 020E 7DE0 021E 3FC0" /* ..ux..u..}..? */ + $"021C 3F80 023C 1F80 0278 0F80 02F0 07C2" /* ..?.<..x... */ + $"07E0 03F6 0FC0 01FF FF80 00FF FE00 003F" /* .......? */ + $"F000 0000 0000 0000 0006 0000 FFFF FFFF" /* ........... */ + $"FFFF 0001 BBBB BBBB BBBB 0002 8888 8888" /* .... */ + $"8888 0003 DDDD DDDD DDDD 0004 EEEE EEEE" /* .... */ + $"EEEE 0005 DDDD 0000 0000 000F 0000 0000" /* ............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 5555 5555 2200 0000" /* ........UUUU"... */ + $"0000 0000 0000 0555 5555 5555 5552 0000" /* .......UUUUUUR.. */ + $"0000 0000 0005 5555 5555 5555 5555 5000" /* ......UUUUUUUUP. */ + $"0000 0000 0055 5555 0220 0000 5555 5500" /* .....UUU. ..UUU. */ + $"0000 0000 0555 5500 2222 0000 0055 5550" /* .....UU.""...UUP */ + $"0000 0000 5555 0FFF FFFF FFF0 0005 5555" /* ....UU...UU */ + $"0000 0005 5550 F211 1111 110F 0055 5555" /* ....UP......UUU */ + $"5000 0055 5500 F211 1111 110F 0555 5055" /* P..UU.......UPU */ + $"5500 0055 5000 F211 4111 110F 5555 0005" /* U..UP..A...UU.. */ + $"5500 0555 500F 2314 4111 1115 5550 0005" /* U..UP.#.A...UP.. */ + $"5550 0555 000F 2314 1111 1155 5500 0002" /* UP.U..#....UU... */ + $"5550 0555 000F 2344 1111 1555 5000 0000" /* UP.U..#D...UP... */ + $"5550 5550 00F2 1311 1111 5555 0F00 0000" /* UPUP.....UU.... */ + $"2555 5550 00F2 2222 2225 5552 2F00 0000" /* %UUP."""%UR/... */ + $"2555 5550 00F2 1311 1155 5511 0F00 0000" /* %UUP....UU..... */ + $"0555 5550 00F2 1311 1555 5111 0F00 0000" /* .UUP....UQ..... */ + $"0555 5550 0F21 1311 5555 1111 10F0 0000" /* .UUP.!..UU..... */ + $"0555 5550 0F21 1315 5551 1111 10F0 0000" /* .UUP.!..UQ..... */ + $"0555 5550 0F21 1355 5511 1111 10F0 0000" /* .UUP.!.UU...... */ + $"0555 0555 0F21 1555 5111 1111 10F0 0000" /* .U.U.!.UQ...... */ + $"5550 0555 0F21 5555 1111 1111 10F0 0000" /* UP.U.!UU....... */ + $"5550 0555 5F25 5551 1111 1111 10F0 0005" /* UP.U_%UQ....... */ + $"5550 0055 5F55 5511 1111 1111 10F0 0005" /* UP.U_UU........ */ + $"5500 0055 5555 5311 1111 1111 10F0 0055" /* U..UUUS.......U */ + $"5500 0005 5555 1131 1111 1111 10F0 0555" /* U...UU.1......U */ + $"5000 0000 5555 1133 1121 1111 10F0 5555" /* P...UU.3.!...UU */ + $"0000 0000 0555 5513 3221 1111 0F55 5550" /* .....UU.2!...UUP */ + $"0000 0000 0055 5555 1221 1111 5555 5500" /* .....UUU.!..UUU. */ + $"0000 0000 0005 5555 5555 5555 5555 5000" /* ......UUUUUUUUP. */ + $"0000 0000 0000 F555 5555 5555 5550 0000" /* ......UUUUUUP.. */ + $"0000 0000 0000 00FF 5555 5555 0000 0000" /* .......UUUU.... */ + $"0000" /* .. */ +}; + +data 'cicn' (138) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 000F F000 001F F800 3EFF F800 7FFF" /* ........>.. */ + $"FFF4 7FFF FFFE FFFF FFFF FFFF FFFF FFFF" /* . */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF 7FFF FFFE 00FF" /* .. */ + $"FF00 00FF FF00 007F FE00 003F FC00 001F" /* .......?... */ + $"F800 0007 E000 0000 0000 0000 0000 0000" /* .............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 000F F000 0010 0800 3EF0 0800 5FE0" /* .........>.._ */ + $"07F4 42E0 050A C5C0 0307 FF77 EEFD 809F" /* .B...w */ + $"F901 80B8 1D01 FFA7 E5FF FF58 1AFF FFA0" /* ...X. */ + $"05FF FFA0 05FF FF40 02FF FF40 02FF FF40" /* ..@.@.@ */ + $"02FF FF40 02FF FF40 02FF 7F40 02FE 00A0" /* .@.@..@.. */ + $"0500 00A0 0500 0058 1A00 0027 E400 0018" /* ......X...'... */ + $"1800 0007 E000 0000 0000 0000 0000 0000" /* ............... */ + $"0000 0000 0000 0000 0004 0000 FFFF FFFF" /* ............ */ + $"FFFF 0001 8888 8888 8888 0002 EEEE EEEE" /* .... */ + $"EEEE 0003 CCCC CCCC CCCC 000F 0000 0000" /* ........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 FFFF FFFF 0000 0000" /* ............ */ + $"0000 0000 0000 000F 0000 0000 F000 0000" /* ............... */ + $"0000 00FF FFF0 FFFF 3300 0000 F000 0000" /* ...3...... */ + $"0000 0F0F FFFF FFF3 3333 3330 0FFF FFFF" /* ....3330. */ + $"0F00 0F00 00F2 FFF3 3333 3333 0F2F 0000" /* .....3333./.. */ + $"F0F0 FF00 0F2F FF33 3333 3333 00FF 0000" /* ../33333... */ + $"2FFF FFFF FFFF 2FFF 3FFF FFF2 FFF0 FFFF" /* //? */ + $"FF3F F333 3333 F00F FFFF FFFF F00F 3333" /* ?333..33 */ + $"333F F333 3333 F2FF F000 002F FF0F 3333" /* 3?333../.33 */ + $"333F FFFF FFFF F0F0 0FFF FFF0 0F0F FFFF" /* 3?... */ + $"FFFF FFFF FFFF 2F0F F000 000F F0F2 FFFF" /* /.... */ + $"FFFF FFFF FFFF F0F0 0000 0000 0F0F FFFF" /* ...... */ + $"FFFF FFFF FFFF F0F0 0033 3000 0F0F FFFF" /* .30... */ + $"FFFF FFFF FFFF 0F10 0333 3330 00F0 FFFF" /* ...330. */ + $"FFFF FFFF FFFF 0F13 3333 3333 00F0 FFFF" /* ..3333. */ + $"FFFF FFFF FFFF 0F13 3333 3333 00F0 FFFF" /* ..3333. */ + $"FFFF FFFF FFFF 0F11 3333 3333 00F0 FFFF" /* ..3333. */ + $"FFFF FFFF FFFF 0F11 3333 3333 30F0 FFFF" /* ..33330 */ + $"FFFF 0FFF FFFF 0F11 1333 3333 31F0 FFFF" /* ....3331 */ + $"FFF0 0000 0000 F0F1 1133 3333 1F0F 0000" /* .....333.... */ + $"0000 0000 0000 F0F1 1111 3311 1F0F 0000" /* ........3..... */ + $"0000 0000 0000 0F0F F111 111F F0F0 0000" /* ............. */ + $"0000 0000 0000 00F0 0FFF FFF0 0F00 0000" /* ............ */ + $"0000 0000 0000 000F F000 000F F000 0000" /* .............. */ + $"0000 0000 0000 0000 0FFF FFF0 0000 0000" /* ............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000" /* .. */ +}; + +data 'cicn' (137) { + $"0000 0000 8008 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0002 0001 0002 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 0000 0000 000F F000 003F" /* ..............? */ + $"FC00 00FF FF00 01FF FF80 03FF FFC0 07FF" /* ...... */ + $"FFE0 0FFF FFF0 0FFF FFF0 1FFF FFF8 1FFF" /* .... */ + $"FFF8 3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF" /* ???? */ + $"FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF" /* ???? */ + $"FFFC 1FFF FFF8 1FFF FFF8 0FFF FFF0 0FFF" /* .... */ + $"FFF0 07FF FFE0 03FF FFC0 01FF FF80 00FF" /* .... */ + $"FF00 003F FC00 000F F000 0000 0000 0000" /* ..?.......... */ + $"0000 0000 0000 0000 0000 000F F000 003F" /* ..............? */ + $"FC00 00F8 1F00 01C0 0380 0380 01C0 0700" /* .......... */ + $"70E0 0E00 F070 0C01 F030 1803 F018 1807" /* p..p..0..... */ + $"7018 380E 701C 301C 700C 3038 700C 3070" /* p.8.p.0.p.08p.0p */ + $"700C 3070 700C 3038 700C 301C 700C 380E" /* p.0pp.08p.0.p.8. */ + $"701C 1807 7018 1803 F018 0C01 F030 0E00" /* p...p......0.. */ + $"F070 0700 70E0 0380 01C0 01C0 0380 00F8" /* p..p..... */ + $"1F00 003F FC00 000F F000 0000 0000 0000" /* ...?.......... */ + $"0000 0000 0000 0000 0002 0000 FFFF FFFF" /* ............ */ + $"FFFF 0001 5555 5555 5555 0002 CCCC CCCC" /* ..UUUUUU.. */ + $"CCCC 0000 0000 0000 0000 0000 0000 0000" /* .............. */ + $"0000 0000 0055 5500 0000 0000 0555 5550" /* .....UU......UUP */ + $"0000 0000 556A A955 0000 0001 5AAA AAA5" /* ....UjU....Z */ + $"4000 0005 6AAA AAA9 5000 0015 AAAA AAAA" /* @...jP... */ + $"5400 0056 AAAA 55AA 9500 005A AAA9 552A" /* T..VU..ZU* */ + $"A500 016A AAA5 552A A940 016A AA95 952A" /* ..jU*@.j* */ + $"A940 056A AA56 952A A950 05AA A95A 952A" /* @.jV*P.Z* */ + $"AA50 05AA A56A 952A AA50 05AA 952A 952A" /* P.j*P.** */ + $"AA50 05AA 952A 952A AA50 05AA A54A 952A" /* P.**P.J* */ + $"AA50 05AA A952 952A AA50 056A AA54 952A" /* P.R*P.jT* */ + $"A950 016A AA95 152A A940 016A AAA5 552A" /* P.j.*@.jU* */ + $"A940 005A AAA9 552A A500 0056 AAAA 552A" /* @.ZU*..VU* */ + $"9500 0015 AAAA 802A 5400 0005 6AAA AAA9" /* ...*T...j */ + $"5000 0001 5AAA AAA5 4000 0000 556A A955" /* P...Z@...UjU */ + $"0000 0000 0555 5550 0000 0000 0055 5500" /* .....UUP.....UU. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000" /* .. */ +}; + +data 'cicn' (136) { + $"0000 0000 8008 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0002 0001 0002 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 0000 0000 000F F000 003F" /* ..............? */ + $"FC00 00FF FF00 01FF FF80 03FF FFC0 07FF" /* ...... */ + $"FFE0 0FFF FFF0 0FFF FFF0 1FFF FFF8 1FFF" /* .... */ + $"FFF8 3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF" /* ???? */ + $"FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF" /* ???? */ + $"FFFC 1FFF FFF8 1FFF FFF8 0FFF FFF0 0FFF" /* .... */ + $"FFF0 07FF FFE0 03FF FFC0 01FF FF80 00FF" /* .... */ + $"FF00 003F FC00 000F F000 0000 0000 0000" /* ..?.......... */ + $"0000 0000 0000 0000 0000 000F F000 003F" /* ..............? */ + $"FC00 00F8 1F00 01C0 0380 0380 01C0 0700" /* .......... */ + $"00E0 0E03 C070 0C03 C030 1803 C018 1803" /* ...p..0..... */ + $"C018 3803 C01C 3003 C00C 3003 C00C 3003" /* .8..0..0..0. */ + $"C00C 3003 C00C 3003 C00C 3003 C00C 3803" /* .0..0..0..8. */ + $"C01C 1803 C018 1803 C018 0C03 C030 0E03" /* .........0.. */ + $"C070 0700 00E0 0380 01C0 01C0 0380 00F8" /* p........ */ + $"1F00 003F FC00 000F F000 0000 0000 0000" /* ...?.......... */ + $"0000 0000 0000 0000 0002 0000 FFFF FFFF" /* ............ */ + $"FFFF 0001 5555 5555 5555 0002 CCCC CCCC" /* ..UUUUUU.. */ + $"CCCC 0000 0000 0000 0000 0000 0000 0000" /* .............. */ + $"0000 0000 0055 5500 0000 0000 0555 5550" /* .....UU......UUP */ + $"0000 0000 556A A955 0000 0001 5AAA AAA5" /* ....UjU....Z */ + $"4000 0005 6AAA AAA9 5000 0015 AAAA AAAA" /* @...jP... */ + $"5400 0056 AAA5 5AAA 9500 005A AAA5 52AA" /* T..VZ..ZR */ + $"A500 016A AAA5 52AA A940 016A AAA5 52AA" /* ..jR@.jR */ + $"A940 056A AAA5 52AA A950 05AA AAA5 52AA" /* @.jRP.R */ + $"AA50 05AA AAA5 52AA AA50 05AA AAA5 52AA" /* P.RP.R */ + $"AA50 05AA AAA5 52AA AA50 05AA AAA5 52AA" /* P.RP.R */ + $"AA50 05AA AAA5 52AA AA50 056A AAA5 52AA" /* P.RP.jR */ + $"A950 016A AAA5 52AA A940 016A AAA5 52AA" /* P.jR@.jR */ + $"A940 005A AAA5 52AA A500 0056 AAA5 52AA" /* @.ZR..VR */ + $"9500 0015 AAA8 02AA 5400 0005 6AAA AAA9" /* ....T...j */ + $"5000 0001 5AAA AAA5 4000 0000 556A A955" /* P...Z@...UjU */ + $"0000 0000 0555 5550 0000 0000 0055 5500" /* .....UUP.....UU. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000" /* .. */ +}; + +data 'cicn' (139) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 FFF0 0000 FFF8 0000 FFF8 0000 FFF8" /* ........ */ + $"0000 FFF8 0000 FFF8 0000 FFF8 0000 FFF8" /* ........ */ + $"0000 FFF8 0000 FFF8 0000 FFF8 0000 FFF8" /* ........ */ + $"0000 FFF8 0000 FFF8 0000 FFF8 0000 FFF8" /* ........ */ + $"0000 0000 01F0 0000 01F0 0000 1FFF 0600" /* ............. */ + $"1FFF 0600 1FFF 0600 1FFF 0604 1FFF 0706" /* ............ */ + $"1FFF 03FF 1FFF 01FF 1FFF 0006 1FFF 0004" /* .......... */ + $"1FFF 0000 1FFF 0000 1FFF 0000 1FFF 0000" /* ............ */ + $"1FFF FFF0 0000 8078 0000 8058 0000 8078" /* ...x..X..x */ + $"0000 8008 0000 8008 0000 8008 0000 8008" /* ............ */ + $"0000 8008 0000 8008 0000 8008 0000 8008" /* ............ */ + $"0000 8008 0000 8008 0000 8008 0000 FFF8" /* ........... */ + $"0000 0000 01F0 0000 0150 0000 1E0F 0600" /* ........P...... */ + $"13FD 0600 1099 0600 110D 0604 1207 0706" /* .............. */ + $"140D 03FF 1219 01FF 1131 0006 10E1 0004" /* .......1..... */ + $"1041 0000 1001 0000 1001 0000 1001 0000" /* .A.............. */ + $"1FFF 0000 0000 0000 0004 0000 FFFF FFFF" /* ........... */ + $"FFFF 0001 5555 5555 5555 0002 CCCC CCCC" /* ..UUUUUU.. */ + $"CCCC 0003 DDDD 0000 0000 000F 0000 0000" /* ............ */ + $"0000 FFFF FFFF FFF1 0000 0000 0000 0000" /* .......... */ + $"0000 F000 0000 0FFF 1000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0F2F F000 0000 0000 0000" /* ....../....... */ + $"0000 F000 0000 0FFF F000 0000 0000 0000" /* ............. */ + $"0000 F000 0000 0022 F000 0000 0000 0000" /* ......"....... */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 F000 0000 0002 F000 0000 0000 0000" /* .............. */ + $"0000 FFFF FFFF FFFF F000 0000 0000 0000" /* ......... */ + $"0000 0000 0000 0000 0000 0000 000F 111F" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0001 0F21" /* ...............! */ + $"0000 0000 0000 0000 0000 000F 1112 0002" /* ................ */ + $"F11F 0000 0330 0000 0000 0001 00FF FFFF" /* ....0....... */ + $"F10F 0000 0330 0000 0000 0001 0222 100F" /* ....0.......".. */ + $"122F 0000 0330 0000 0000 0001 0221 0002" /* ./...0.......!.. */ + $"F12F 0000 0330 0000 0300 0001 0210 0000" /* /...0.......... */ + $"2F1F 0000 0333 0000 0330 0001 0100 0002" /* /....3...0...... */ + $"F12F 0000 0033 3333 3333 0001 0210 002F" /* /...33333...../ */ + $"122F 0000 0003 3333 3333 0001 0221 02F1" /* ./....3333...!. */ + $"222F 0000 0000 0000 0330 0001 0222 1F12" /* "/.......0...".. */ + $"222F 0000 0000 0000 0300 0001 0222 2122" /* "/..........."!" */ + $"222F 0000 0000 0000 0000 0001 0222 2222" /* "/...........""" */ + $"222F 0000 0000 0000 0000 0001 0222 2222" /* "/...........""" */ + $"222F 0000 0000 0000 0000 0001 0222 2222" /* "/...........""" */ + $"222F 0000 0000 0000 0000 000F FFFF FFFF" /* "/.......... */ + $"FFFF" /* */ +}; + +data 'cicn' (140) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0007 C000 0007 C000 0007 C000 001F" /* ............. */ + $"F000 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* ..... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 0007 C000 0004 4000 0005 4000 0018" /* .....@...@... */ + $"3000 1FE0 0FF0 1040 0C10 107F FE30 103C" /* 0....@....0.< */ + $"1E30 1008 0C30 1010 0630 1020 0330 1040" /* .0...0...0. .0.@ */ + $"01B0 1080 00F0 1100 01B0 1200 0330 1100" /* .........0.. */ + $"0630 1080 0C30 1040 1830 1020 3030 1010" /* .0..0.@.0. 00.. */ + $"6030 1008 C030 1005 8030 1003 0030 1000" /* `0..0..0...0.. */ + $"0030 1000 0030 1000 0030 1000 0030 1000" /* .0...0...0...0.. */ + $"0030 1000 0030 1000 0030 17FF FFF0 1FFF" /* .0...0...0.. */ + $"FFF0 0000 0000 0000 0004 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 5555 5555 5555 0002 CCCC CCCC" /* ..UUUUUU.. */ + $"CCCC 0003 1111 1111 1111 000F 0000 0000" /* .............. */ + $"0000 0000 0000 0000 0311 1300 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0102 0100 0000 0000" /* ................ */ + $"0000 0000 0000 0000 010F 2100 0000 0000" /* ..........!..... */ + $"0000 0000 0000 0001 1222 2211 0000 0000" /* .........""..... */ + $"0000 0003 1111 1110 0000 0002 3111 1113" /* ............1... */ + $"0000 0001 0000 0122 2222 2222 1322 0023" /* .......""""".".# */ + $"0000 0001 0222 2133 3333 3333 3312 2213" /* ....."!333333.". */ + $"0000 0001 0222 2211 1100 0003 1112 2213" /* ....."".......". */ + $"0000 0001 0222 2222 1000 0002 3122 2213" /* ....."""....1"". */ + $"0000 0001 0222 2221 0000 0000 2312 2213" /* .....""!....#.". */ + $"0000 0001 0222 2210 0000 0000 0231 2213" /* .....""......1". */ + $"0000 0001 0222 2100 0000 0000 0023 1213" /* ....."!......#.. */ + $"0000 0001 0222 1000 0000 0000 0002 3113" /* ....."........1. */ + $"0000 0001 0221 0000 0000 0000 0023 1213" /* .....!.......#.. */ + $"0000 0001 0210 0000 0000 0000 0231 2213" /* .............1". */ + $"0000 0001 0221 0000 0000 0000 2312 2213" /* .....!......#.". */ + $"0000 0001 0222 1000 0000 0002 3122 2213" /* ....."......1"". */ + $"0000 0001 0222 2100 0000 0023 1222 2213" /* ....."!....#."". */ + $"0000 0001 0222 2210 0000 0231 2222 2213" /* .....""....1""". */ + $"0000 0001 0222 2221 0000 2312 2222 2213" /* .....""!..#.""". */ + $"0000 0001 0222 2222 1002 3122 2222 2213" /* ....."""..1"""". */ + $"0000 0001 0222 2222 2123 1222 2222 2213" /* ....."""!#."""". */ + $"0000 0001 0222 2222 2231 2222 2222 2213" /* .....""""1""""". */ + $"0000 0001 0222 2222 2222 2222 2222 2213" /* ....."""""""""". */ + $"0000 0001 0222 2222 2222 2222 2222 2213" /* ....."""""""""". */ + $"0000 0001 0222 2222 2222 2222 2222 2213" /* ....."""""""""". */ + $"0000 0001 0222 2222 2222 2222 2222 2213" /* ....."""""""""". */ + $"0000 0001 0222 2222 2222 2222 2222 2213" /* ....."""""""""". */ + $"0000 0001 0222 2222 2222 2222 2222 2213" /* ....."""""""""". */ + $"0000 0001 0222 2222 2222 2222 2222 2213" /* ....."""""""""". */ + $"0000 0001 2111 1111 1111 1111 1111 1113" /* ....!........... */ + $"0000 0003 3333 3333 3333 3333 3333 3333" /* ....333333333333 */ + $"0000" /* .. */ +}; + +data 'cicn' (141) { + $"0000 0000 8008 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0002 0001 0002 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 1FFF FE00 1FFF FF00 1FFF FF80 1FFF" /* ........ */ + $"FFC0 1FFF FFE0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF" /* .... */ + $"FFF0 1FFF FE00 1000 0700 1000 0580 1000" /* ........... */ + $"04C0 1000 0460 1000 0430 1000 07F0 1000" /* ....`...0..... */ + $"03F0 1000 0010 1000 0010 10C0 0010 11E0" /* ............. */ + $"0010 13D0 0010 13D7 6E10 1120 0010 10C0" /* ......n.. ... */ + $"0010 1000 0010 1000 0010 10C0 0010 1120" /* .............. */ + $"0010 1210 0010 1217 6E10 1120 0010 10C0" /* ........n.. ... */ + $"0010 1000 0010 1000 0010 1000 0010 1000" /* ................ */ + $"0010 1000 0010 1000 0010 1000 0010 1FFF" /* ............... */ + $"FFF0 0000 0000 0000 0003 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 5555 5555 5555 0002 CCCC CCCC" /* ..UUUUUU.. */ + $"CCCC 0003 0000 0000 0000 03FF FFFF FFF4" /* ......... */ + $"0000 0300 0000 003D 0000 0300 0000 003B" /* .......=.......; */ + $"4000 0300 0000 0032 D000 0300 0000 0030" /* @......2......0 */ + $"B400 0300 0000 0032 AD00 0300 0000 003F" /* ......2......? */ + $"FF00 0300 0000 0005 5700 0300 0000 000A" /* .......W...... */ + $"AB00 0300 0000 0000 0B00 0302 F800 0000" /* .............. */ + $"0B00 030B 5E00 0000 0B00 030D F900 0000" /* ....^.......... */ + $"0B00 0305 F93F 3C7C 0B00 030B AE0A 8A2A" /* ....?<|....Š* */ + $"0B00 0302 5800 0000 0B00 0300 0000 0000" /* ....X........... */ + $"0B00 0300 0000 0000 0B00 0302 5800 0000" /* ............X... */ + $"0B00 0309 0600 0000 0B00 0304 2900 0000" /* ...........)... */ + $"0B00 0304 A93F 3CFC 0B00 0309 A60A 8A2A" /* ....?<...ƦŠ* */ + $"0B00 0302 7800 0000 0B00 0300 0000 0000" /* ....x........... */ + $"0B00 0300 0000 0000 0B00 0300 0000 0000" /* ................ */ + $"0B00 0300 0000 0000 0B00 0300 0000 0000" /* ................ */ + $"0B00 0300 0000 0000 0B00 032A AAAA AAAA" /* ...........* */ + $"AB00 03FF FFFF FFFF FF00" /* ... */ +}; + +data 'cicn' (132) { + $"0000 0000 8020 0000 0000 0020 0020 0000" /* .... ..... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0008 0001 0008 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 007F FC00 01FF FF00 03FF" /* ............ */ + $"FF80 07FF FFC0 0FFF FFE0 1FFF FFF0 3FFF" /* ...? */ + $"FFF8 7FFF FFFC 7FFF FFFC 7FFF FFFC FFFF" /* ... */ + $"FFFE FFFF FFFE FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFE 7FFF FFFE FFFF FFFF FFFF FFFF" /* . */ + $"FFFF FFFF FFFF FFFF FFFE 7FFF FFFE 7FFF" /* .. */ + $"FFFC 7FFF FFFC 3FFF FFF8 1FFF FFF0 0FFF" /* .?.. */ + $"FFE0 07FF FFC0 03FF FF80 01FF FF00 007F" /* ...... */ + $"FC00 0000 0000 007F FC00 01F0 3F00 03C0" /* .........?.. */ + $"0780 0740 03C0 0E00 0560 1C20 0230 3A00" /* ..@....`. .0:. */ + $"0458 7510 08BC 6A80 111C 7548 227C E08F" /* .Xu..j..uH"| */ + $"C4FE F55F FBEE FFFC 57FF DDFB BF7F FFD7" /* _W. */ + $"DBFF EFF6 5FEF FFB6 D7FF FDFB BF77 FFD4" /* _w */ + $"7FFF EFBF F55F FE47 E2AE 7C8A 055E 7110" /* ._G|.^q. */ + $"42AC 7A24 015C 3440 20B8 1888 0078 0D40" /* Bz$.\4@ ..x.@ */ + $"10F0 0790 01FC 03C0 07FE 01F8 1FFF 007F" /* ......... */ + $"FFFF 0000 0000 0000 0012 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 CCCC CCCC CCCC 0002 FFFF FFFF" /* .... */ + $"CCCC 0003 FFFF CCCC FFFF 0004 CCCC FFFF" /* .... */ + $"FFFF 0005 CCCC CCCC FFFF 0006 9999 FFFF" /* .... */ + $"FFFF 0007 9999 9999 CCCC 0008 6666 6666" /* ....ffff */ + $"9999 0009 EEEE EEEE EEEE 000A DDDD DDDD" /* .. */ + $"DDDD 000B BBBB BBBB BBBB 000C AAAA AAAA" /* .... */ + $"AAAA 000D 8888 8888 8888 000E 5555 5555" /* ....UUUU */ + $"5555 000F 4444 4444 4444 0010 2222 2222" /* UU..DDDDDD.."""" */ + $"2222 0011 1111 1111 1111 00FF 0000 0000" /* ""............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0010 1010 100F" /* ................ */ + $"0F0F 0F0F 1010 1010 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0010 100F 0F0D 0C0B" /* ................ */ + $"0101 010B 0C0D 1110 1010 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 100F 0F0C 010A 090A" /* ............. */ + $"0A0A 0A0A 0A01 0B0B 1110 1000 0000 0000" /* ........... */ + $"0000 0000 0000 0010 0F0D 0B09 0000 090A" /* ............. */ + $"0A0A 0A0A 010A 0A0A 010C 1110 0000 0000" /* ......... */ + $"0000 0000 0000 100F 0B02 0A00 0000 0009" /* .............. */ + $"0A0A 0A01 0A0A 0A0A 090A 0B11 1000 0000" /* ....... */ + $"0000 0000 0010 0F0A 0209 0200 0000 0009" /* ............. */ + $"0A0A 0A0A 010A 0A09 0A00 0A0B 1110 0000" /* ....... */ + $"0000 0000 100F 0B02 0A02 0902 0000 0000" /* .............. */ + $"090A 0A01 0A0A 090A 000A 000A 0B11 1000" /* ....... */ + $"0000 0010 0F0D 040A 020A 0209 0200 0000" /* ............. */ + $"090A 0A0A 010A 0A09 0A00 0A00 0A0C 1110" /* ...... */ + $"0000 0010 0F0B 0604 0A02 0A02 0902 0000" /* ............. */ + $"090A 0A01 0A0A 090A 000A 000A 0901 1110" /* ...... */ + $"0000 000F 0D0A 0406 0406 020A 0209 0200" /* ............. */ + $"000A 010A 0A09 0A00 0A09 0A09 0A0A 0C11" /* ..... */ + $"0000 100F 0C04 0A04 0604 0602 0902 010D" /* .............. */ + $"0D0D 0D0C 090A 000A 090A 090A 0A05 0B11" /* ........ */ + $"1000 100F 0B05 040A 0406 0406 0201 0B0B" /* ............... */ + $"0B0B 0B0B 0B01 0A09 0A0A 050A 0505 0111" /* ........... */ + $"1000 0F0D 0505 0505 0A0A 0A06 010B 0B0B" /* ............. */ + $"0B0B 0B0A 000B 090A 0A05 0A05 0305 030D" /* ........... */ + $"1110 0F07 0505 0505 0505 0A0A 0C0B 0B0B" /* .............. */ + $"0E0E 0E00 0A0B 0C0A 0503 0503 0503 0507" /* .............. */ + $"1110 0F07 0505 0505 0505 0505 0D0B 0B0E" /* ................ */ + $"0F0F 0F0D 0B0B 0D05 0305 0305 0305 0507" /* ................ */ + $"1110 0F07 0505 0505 0503 0503 0D0B 0B0E" /* ................ */ + $"0F00 000D 0B0B 0D03 0503 0505 0505 0507" /* ................ */ + $"1110 0F07 0305 0305 0305 0305 0D0B 010E" /* ................ */ + $"0F00 0F0D 0B0B 0D05 0505 0505 0505 0507" /* ................ */ + $"1110 0F07 0503 0503 0505 050A 0C0B 0A00" /* .............. */ + $"0D0D 0D0B 0B0B 0C0A 0A05 0505 0505 050D" /* .............. */ + $"1110 0F0D 0505 0505 0A05 0A0A 090A 000A" /* .......... */ + $"0B0B 0B0B 0B0B 0106 040A 0A0A 0505 0508" /* ............. */ + $"1110 100F 0B05 0A0A 050A 0A09 0A01 0B0B" /* .......... */ + $"0B0B 0B0B 0B01 0A02 0604 0604 0A04 0B11" /* .............. */ + $"1010 100F 0C0A 050A 090A 090A 000A 0C0D" /* ......... */ + $"0D0D 0D0C 0909 020A 020A 0406 040A 0C11" /* ........... */ + $"1000 000F 0D0A 0A09 0A09 0A00 0A09 0A01" /* ....... */ + $"0B01 0A09 0002 0902 0A02 0A04 0604 0D11" /* ........... */ + $"1000 0010 0F01 090A 000A 000A 090A 0A01" /* ......... */ + $"010B 0A09 0000 0009 020A 040A 040A 1110" /* .......... */ + $"0000 0010 0F0B 0A00 0A00 0A09 0A0A 0101" /* .......... */ + $"0B01 0A09 0000 0002 0902 0A04 0A0D 1110" /* ........... */ + $"0000 0000 100F 0B0A 000A 000A 090A 0101" /* ........... */ + $"010B 0A0A 0900 0000 0209 020A 0D11 1000" /* ........... */ + $"0000 0000 0010 0F0B 0A00 0A09 0A01 0101" /* ............ */ + $"0B01 0A0A 0900 0000 0002 0A0D 1110 1000" /* ............ */ + $"0000 0000 0000 100F 0B0A 090A 0A01 0101" /* ............ */ + $"010B 010A 0900 0000 000A 0D11 1010 0000" /* ............. */ + $"0000 0000 0000 0010 0F0B 010A 0101 0101" /* ............... */ + $"0B01 010A 0900 0000 0A0D 1110 1010 1010" /* ............. */ + $"0000 0000 0000 0000 100F 0F0D 0B01 0101" /* ................ */ + $"010B 010A 0909 0C0D 11FF 1010 1010 1010" /* ............ */ + $"1000 0000 0000 0000 0010 100F 0F0D 0C0B" /* ................ */ + $"0101 0B0C 0D10 FF11 1010 1010 1010 1010" /* ............... */ + $"1010 0000 0000 0000 0000 0010 1010 1010" /* ................ */ + $"1010 FFFF FF10 1010 1010 1010 1010 1010" /* ............. */ + $"1010" /* .. */ +}; + +data 'cicn' (133) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 007F FC00 01FF FF00 03FF" /* ............ */ + $"FF80 07FF FFC0 0FFF FFE0 1FFF FFF0 3FFF" /* ...? */ + $"FFF8 7FFF FFFC 7FFF FFFC 7FFF FFFC FFFF" /* ... */ + $"FFFE FFFF FFFE FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFE 7FFF FFFE FFFF FFFF FFFF FFFF" /* . */ + $"FFFF FFFF FFFF FFFF FFFE 7FFF FFFE 7FFF" /* .. */ + $"FFFC 7FFF FFFC 3FFF FFF8 1FFF FFF0 0FFF" /* .?.. */ + $"FFE0 07FF FFC0 03FF FF80 01FF FF00 007F" /* ...... */ + $"FC00 0000 0000 007F FC00 01FF FF00 03FF" /* ........... */ + $"FF80 07F0 0FC0 0F80 03E0 1E20 03F0 3E00" /* ..... .>. */ + $"07F8 7D10 0FBC 7A80 1F1C 7548 3E7C E08F" /* .}..z..uH>| */ + $"FCFE F55F FBEE FFFC F7FF FDFB FF7F FFD7" /* _. */ + $"DBFF EFF7 DFEF FFBF D7FF FDFF BF77 FFFC" /* w */ + $"7FFF EFFF F55F FEF7 E2AE 7DEA 055E 73D0" /* ._}.^s */ + $"42BC 7FA4 017C 3F40 20F8 1E88 00F8 0FC0" /* B..|?@ ... */ + $"13F0 07F0 1FFC 03FF FFFE 01FF FFFF 007F" /* ....... */ + $"FFFF 0000 0000 0000 000F 0000 FFFF FFFF" /* .......... */ + $"FFFF 0001 CCCC CCCC CCCC 0002 FFFF FFFF" /* .... */ + $"CCCC 0003 FFFF CCCC FFFF 0004 CCCC FFFF" /* .... */ + $"FFFF 0005 CCCC CCCC FFFF 0006 9999 FFFF" /* .... */ + $"FFFF 0007 EEEE EEEE EEEE 0008 DDDD DDDD" /* .... */ + $"DDDD 0009 BBBB BBBB BBBB 000A AAAA AAAA" /* .ƻ.ª */ + $"AAAA 000B 8888 8888 8888 000C 5555 5555" /* ....UUUU */ + $"5555 000D 4444 4444 4444 000E 2222 2222" /* UU..DDDDDD.."""" */ + $"2222 000F DDDD 0000 0000 0000 0000 0000" /* ""............ */ + $"0000 0000 0000 0000 0000 0000 0000 0EEE" /* ............... */ + $"FFFF FFFF EE00 0000 0000 0000 000E EFFF" /* ......... */ + $"FFFF FFFF FFFE 0000 0000 0000 00EF FFFF" /* ....... */ + $"FFFF FFFF FFFF F000 0000 0000 0EFF FFFF" /* ...... */ + $"7888 8818 FFFF FF00 0000 0000 EFFF FF00" /* x....... */ + $"0788 8188 88FF FFF0 0000 000E FFFF 2000" /* ..... . */ + $"0788 8818 878F FFFF 0000 00EF FFF2 7200" /* .....r. */ + $"0078 8188 78FF FFFF F000 0EFF FF28 2720" /* .xx..(' */ + $"0078 8818 8FFF F0FF FF00 0EFF F482 8272" /* .x...r */ + $"0078 8188 FFFF 087F FF00 0FFF F646 2827" /* .x....F(' */ + $"2008 188F FFF7 878F FFF0 EFFF 8464 6272" /* ..dbr */ + $"1BBB BAFF FF78 7885 FFF0 EFFF 4846 4621" /* .xxHFF! */ + $"9999 9FFF F788 5855 FFF0 FFF5 5588 8619" /* XUU. */ + $"9999 FFFF 7885 8535 3FFF FFF5 5555 88A9" /* x5?UU */ + $"99CF FFF9 A853 5353 5FFF FFF5 5555 55B9" /* SSS_UUU */ + $"9CFF FF99 B535 3535 5FFF FFF5 5553 53B9" /* 555_USS */ + $"9FFF FB99 B353 5555 5FFF FFF5 3535 35B9" /* SUU_555 */ + $"FFFF DB99 B555 5555 5FFF FFF3 5355 58AF" /* ۙUUU_SUX */ + $"FFFB B999 A885 5555 5FFF FFF5 5585 88FF" /* UU_U */ + $"FF99 9999 1648 8855 5FFF EFFF 8858 8FFF" /* .HU_X */ + $"F999 9991 8264 6484 FFFE EFFF 5878 FFFF" /* ddXx */ + $"ABBB BA77 2828 4648 FFF0 0FFF F78F FFF7" /* w((FH. */ + $"8191 8702 7282 846F FFF0 0EFF F8FF FF78" /* .ro.x */ + $"8119 8700 0728 484F FF00 0EFF FFFF F788" /* ...(HO.. */ + $"1191 8700 0272 84FF FF00 00EF FFFF 0878" /* ...r...x */ + $"1119 8870 0027 2FFF F000 000E FFFF 8781" /* ..p.'/... */ + $"1191 8870 0002 FFFF E000 0000 EFFF FF81" /* .p..... */ + $"1119 1870 00FF FFFE 0000 0000 0EFF FFFF" /* ...p...... */ + $"1191 1870 FFFF FFEE EE00 0000 00EF FFFF" /* ..p.... */ + $"FFFF FFFF FFFF FEEE EEE0 0000 000E EFFF" /* .... */ + $"FFFF FFFF FFFE EEEE EEEE 0000 0000 0EEE" /* ..... */ + $"FFFF FFFF EEEE EEEE EEEE" /* */ +}; + +data 'cicn' (142) { + $"0000 0000 8010 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0004 0001 0004 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 211E 79E0 2120 4110 2120" /* ......!.y! A.! */ + $"4110 211C 79E0 2102 4180 2102 4160 1E3C" /* A.!.y!.A!.A`.< */ + $"7910 0000 0000 0000 0000 0000 0004 0000" /* y............... */ + $"0038 0000 0040 0000 0080 0000 0100 0000" /* .8...@......... */ + $"0100 7FFF FFFC 7FFF FFFC 7FFF FFFC 7FFF" /* ...... */ + $"FFFC 7FFF FFFC 7FFF FFFC 7FFF FFFC 7FFF" /* .... */ + $"FFFC 7FFF FFFC 7FFF FFFC 7FFF FFFC 7FFF" /* .... */ + $"FFFC 7FFF FFFC 7FFF FFFC 0000 0000 0000" /* ........ */ + $"0000 0000 0000 211E 79E0 2120 4110 2120" /* ......!.y! A.! */ + $"4110 211C 79E0 2102 4180 2102 4160 1E3C" /* A.!.y!.A!.A`.< */ + $"7910 0000 0000 0000 0000 0000 0004 0000" /* y............... */ + $"0038 0000 0040 0000 0080 0000 0100 0000" /* .8...@......... */ + $"0100 7FFF FFFC 4000 0004 5555 5454 4000" /* ...@...UUTT@. */ + $"0004 4000 0004 5555 5554 4AAA 88A4 5555" /* ..@...UUUTJUU */ + $"5554 4AAA 80A4 5555 4154 4AAA 88A4 55FD" /* UTJUUATJU */ + $"5554 4000 0004 7FFF FFFC 0000 0000 0000" /* UT@.......... */ + $"0000 0000 0000 0000 0004 0000 FFFF FFFF" /* ............ */ + $"FFFF 0001 FFFF FFFF CCCC 0002 7777 7777" /* ....wwww */ + $"7777 0003 8888 8888 8888 000F 0000 0000" /* ww........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 00F0 000F 000F FFF0 0FFF F00F FFF0" /* ......... */ + $"0000 00F0 000F 00F0 0000 0F00 000F 000F" /* .............. */ + $"0000 00F0 000F 00F0 0000 0F00 000F 000F" /* .............. */ + $"0000 00F0 000F 000F FF00 0FFF F00F FFF0" /* .......... */ + $"0000 00F0 000F 0000 00F0 0F00 000F F000" /* ............. */ + $"0000 00F0 000F 0000 00F0 0F00 000F 0FF0" /* ............. */ + $"0000 000F FFF0 00FF FF00 0FFF F00F 000F" /* .......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0200 0000 0000 0000 0000 0000 0000 0022" /* ..............." */ + $"2000 0000 0000 0000 0000 0000 0000 0200" /* ............... */ + $"0000 0000 0000 0000 0000 0000 0000 2000" /* .............. . */ + $"0000 0000 0000 0000 0000 0000 0002 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0002 0000" /* ................ */ + $"0000 0333 3333 3333 3333 3333 3333 3333" /* ...3333333333333 */ + $"3300 0300 0000 0000 0000 0000 0000 0000" /* 3............... */ + $"0300 030F 1F1F 1F1F 1F1F 1F1F 1F11 1F1F" /* ................ */ + $"1300 0301 1111 1111 1111 1111 1111 1111" /* ................ */ + $"1300 0301 1111 1111 1111 1111 1111 1111" /* ................ */ + $"1300 030F 1F1F 1F1F 1F1F 1F1F 1F1F 1F1F" /* ................ */ + $"1300 0301 F1F1 F1F1 F1F1 F111 F111 F1F1" /* ...... */ + $"1300 030F 1F1F 1F1F 1F1F 1F1F 1F1F 1F1F" /* ................ */ + $"1300 0301 F1F1 F1F1 F1F1 F111 1111 F1F1" /* ....... */ + $"1300 030F 1F1F 1F1F 1F1F 1F11 111F 1F1F" /* ................ */ + $"1300 0301 F1F1 F1F1 F1F1 F111 F111 F1F1" /* ...... */ + $"1300 030F 1F1F FFFF FF1F 1F1F 1F1F 1F1F" /* ............. */ + $"1300 0301 1111 1111 1111 1111 1111 1111" /* ................ */ + $"1300 0333 3333 3333 3333 3333 3333 3333" /* ...3333333333333 */ + $"3300 0000 0000 0000 0000 0000 0000 0000" /* 3............... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000" /* .. */ +}; + +data 'ALRT' (200, "Quit") { + $"0042 006A 00D0 01DC 00C8 4444 300A" /* .B.j...DD0 */ +}; + diff --git a/bochs/build/macosx/diskimage.pl b/bochs/build/macosx/diskimage.pl new file mode 100755 index 00000000..b8485756 --- /dev/null +++ b/bochs/build/macosx/diskimage.pl @@ -0,0 +1,117 @@ +#!/usr/bin/perl + +# +# +# Copyright (C) 1991-2002 and beyond by Bungie Studios, Inc. +# and the "Aleph One" developers. +# +# 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. +# +# This license is contained in the file "COPYING", +# which is included with this source code; it is available online at +# http://www.gnu.org/licenses/gpl.html +# +# + +my $fullfolderPath = shift(@ARGV); +die "err: No folder specified" unless defined($fullfolderPath) && length($fullfolderPath); + +$fullfolderPath =~ s{/$}{}; +$fullfolderPath =~ m{([^/]+)$}; + +local $folderName = $1; +local $folderSize = undef; +local $imageName = "'$fullfolderPath.dmg'"; +local $imageSectors = undef; +local $imageTemp = "'$fullfolderPath-tmp.dmg'"; + +local $mount_point = "bochs-image-mount"; + +die "err: $folderName is not a directory\n" if(!-d $fullfolderPath); + +# Know a better way to get the first value from du? +($folderSize) = split(m/ /, `du -s "$fullfolderPath"`); +die "err: du failed with $?\n" if($?); + +# Inflate $folderSize for disk image overhead. Minimum 5 MB disk +local $fiveMBImage=20*(2048); +# BBD: I had to raise this to 20meg or the ditto command would run +# out of disk space. Apparently the technique of measuring the +# amount of space required is not working right. + +$imageSectors = $folderSize + int($folderSize * 0.15); +if($imageSectors < $fiveMBImage) +{ + $imageSectors = $fiveMBImage; +} +print "Minimum sectors = $fiveMBImage\n"; +print "Folder sectors = $folderSize\n"; +print "Image sectors = $imageSectors\n"; + +# Create image, overwriting prior version +`hdiutil create -ov -sectors $imageSectors $imageTemp`; +die "err: hdiutil create failed with $?\n" if($?); + +# Initialize the image +local $hdid_info=`hdid -nomount $imageTemp`; +die "err: hdid -nomount failed with $?\n" if($?); + +$hdid_info =~ s/( |\t|\n)+/~!/g; +local (@hdid_info) = split(m/~!/, $hdid_info); + +local ($disk_dev, $hfs_dev); + +$disk_dev = $hdid_info[0]; +$hfs_dev = $hdid_info[4]; +$mount_dev = $hdid_info[4]; + +$disk_dev =~ s{/dev/}{}; +$hfs_dev =~ s/disk/rdisk/; + +`newfs_hfs -v "$folderName" $hfs_dev`; +if($?) +{ + local $err = $?; + `hdiutil eject $disk_dev`; + die "err: newfs_hfs failed with $err\n"; +} + +# Fill the image + +`mkdir $mount_point`; +`/sbin/mount -t hfs $mount_dev $mount_point`; +if($?) +{ + local $err = $?; + `hdiutil eject $disk_dev`; + die "err: mount failed with $err\n"; +} + +`ditto -rsrcFork "$fullfolderPath" $mount_point`; +if($?) +{ + local $err = $?; + `umount $mount_dev`; + `hdiutil eject $disk_dev`; + `rmdir $mount_point`; + die "err: ditto failed with $err\n"; +} +`umount $mount_dev`; +`hdiutil eject $disk_dev`; +`rmdir $mount_point`; + +# Create the compressed image +`hdiutil convert $imageTemp -format UDCO -o $imageName`; +die "err: hdiutil convert failed with $?\n" if($?); + +`rm $imageTemp`; + +print "$imageName is your new diskimage\n"; diff --git a/bochs/build/macosx/make-dmg.sh b/bochs/build/macosx/make-dmg.sh new file mode 100755 index 00000000..8ba5ef9a --- /dev/null +++ b/bochs/build/macosx/make-dmg.sh @@ -0,0 +1,99 @@ +#!/bin/sh +# +# $Id$ +# +# Make a DMG of Bochs. This script must be run from the main source +# directory, e.g. "./build/macosx/make-dmg.sh". If you haven't run +# configure yet, it runs .conf.macosx for you. Then it creates a +# temporary directory _dmg_top and does a make install into that +# directory, and builds a disk image. At the end it cleans up the +# temporary directory. +# + +VERSION=@VERSION@ # substituted in with configure script +VERSION=2.0.pre4 +BUILDROOT=./_dmg_top +INSTALL_PREFIX=$BUILDROOT/Bochs-${VERSION} +DMG=./Bochs-${VERSION}.dmg + +# test if we're in the right directory. if not, bomb. +echo '-- Is the script run from the right directory?' +if test -f main.cc -a -f bochs.h; then + echo yes +else + echo no + echo ERROR: Run it from the top of the Bochs source tree, where bochs.h is found. + exit 10 +fi + +# test if configure has been run already. if not, run .conf.macosx. +configured=0 +echo '-- Has configure been run already?' +if test -f config.h -a -f Makefile; then + echo yes +else + echo no. I will run .conf.macosx now. + /bin/sh -x .conf.macosx + conf_retcode=$? + configured=1 + if test "$conf_retcode" != 0; then + echo ERROR: configure failed. Correct errors in .conf.macosx and try again. + exit 20 + fi +fi + +# remove any leftovers from previous image creation. +echo "-- Removing leftovers from previous runs" +rm -rf ${BUILDROOT} ${BUILDROOT}.dmg ${DMG} + +# make new buildroot directory +echo "-- Making ${BUILDROOT} directory" +mkdir ${BUILDROOT} && mkdir ${INSTALL_PREFIX} +if test $? != 0; then + echo ERROR: mkdir ${BUILDROOT} or mkdir ${INSTALL_PREFIX} failed + exit 30 +fi + +# run make and then make install into it +echo "-- Running make" +make +if test $? != 0; then + echo ERROR: make failed + exit 40 +fi + +echo "-- Running make install with prefix=${INSTALL_PREFIX}" +make install prefix=${INSTALL_PREFIX} +if test $? != 0; then + echo ERROR: make install with prefix=${INSTALL_PREFIX} failed + exit 50 +fi + +# create new disk image +echo "-- Making a disk image with root at ${BUILDROOT}, using diskimage.pl" +./build/macosx/diskimage.pl ${BUILDROOT} +if test $? != 0; then + echo ERROR: diskimage.pl script failed + exit 60 +fi + +if test ! -f ${BUILDROOT}.dmg; then + echo ERROR: diskimage.pl succeeded but I cannot find the image ${BUILDROOT}.dmg. + exit 70 +fi + +# rename to the right thing +echo "-- Renaming the output disk image to ${DMG}" +mv ${BUILDROOT}.dmg ${DMG} +if test $? != 0; then + echo ERROR: rename failed + exit 80 +fi + +echo "-- Done! The final disk image is " +ls -l ${DMG} + +echo "-- Cleaning up the temporary files in ${BUILDROOT}" +rm -rf ${BUILDROOT} + +exit 0 diff --git a/bochs/build/macosx/pbdevelopment.plist b/bochs/build/macosx/pbdevelopment.plist new file mode 100644 index 00000000..c42c04ab --- /dev/null +++ b/bochs/build/macosx/pbdevelopment.plist @@ -0,0 +1,8 @@ + + + + + PBXProjectSourcePath + /Users/bryce/bochs/bochs/bochs.pbproj + + diff --git a/bochs/build/macosx/script.data b/bochs/build/macosx/script.data new file mode 100755 index 00000000..d07649a6 Binary files /dev/null and b/bochs/build/macosx/script.data differ diff --git a/bochs/build/macosx/script.r b/bochs/build/macosx/script.r new file mode 100644 index 00000000..97288b47 --- /dev/null +++ b/bochs/build/macosx/script.r @@ -0,0 +1,2712 @@ +data 'scsz' (0) { + $"4000 0000 0000 0000 0000 0000 0000 0000" /* @............... */ + $"0000 0000 0000 0000 0000" /* .......... */ +}; + +data 'icns' (150) { + $"6963 6E73 0000 9D63 4943 4E23 0000 0108" /* icns..cICN#.... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 F000 0000 F000" /* .............. */ + $"0003 F800 0003 F000 000F F000 001F E000" /* ............ */ + $"002F F000 003F F800 00FF FC00 00FF FE00" /* ./..?..... */ + $"00FF FF00 007F FF80 00BF FF80 003F FF80" /* ......? */ + $"001F FF00 003F FF00 01FF FF80 03FF FFF0" /* ....?... */ + $"1FFF FFFC 3FFF FFFE 1FFF FFF8 07FF FFF4" /* .?.. */ + $"03FF FFE0 00FF FF80 007F FE40 001F FD00" /* ....@... */ + $"000F F000 0003 D000 0001 A000 0000 0000" /* ............. */ + $"696C 3332 0000 0739 AD00 040D 282F 1803" /* il32...9...(/.. */ + $"9700 0615 69AF C7A4 3902 9500 0715 6EC8" /* ...iǤ9....n */ + $"DEEB F58E 0D94 0008 156E C9DB EEF0 E9A0" /* ....n */ + $"1693 0009 166E C9DB EFF2 E6D1 7B0E 9200" /* ...n{.. */ + $"0A15 6EC9 DBEF F1E8 CC9B 3102 9100 0A15" /* .n̛1... */ + $"6EC9 DBEF F1E9 C8B7 610A 9100 0C15 6DCC" /* nȷa‘...m */ + $"DAEF F2E9 CAB3 BEA2 3D05 8F00 0E11 579C" /* ʳ=....W */ + $"BFF4 F1E9 CAB4 BCC1 CDA9 3F05 8D00 100A" /* ʴͩ?... */ + $"4B76 5A69 BDEF C9B4 BCC3 C7C8 D6B2 4206" /* KvZiɴֲB. */ + $"8C00 111E 787D 7479 89C8 B4BC C3C7 CBD1" /* ...x}tyȴ */ + $"D2E0 BA45 068B 0012 2385 9489 879C B4BC" /* E...# */ + $"C3C7 CCD1 D6DB DDEB C144 048A 0012 1677" /* D....w */ + $"AB9F 9AB2 BDC2 C7CC D1D6 DBE0 E6E6 F0A1" /* */ + $"1B8A 0012 0335 94B6 B1BD C2C7 CBD1 D6DB" /* ....5 */ + $"E0E5 E9EC DBAF 298B 0011 053B 9DBF C1C7" /* ۯ)...; */ + $"CCD1 D6DB E0E5 E9ED E1C6 921E 8C00 101E" /* ƒ.... */ + $"8AC6 C5CB D1D6 DAE0 E6E9 EDE6 C9AB 4E07" /* ɫN. */ + $"8A00 130C 4188 BEC8 CFD3 D5DB E0E5 E9EE" /* ...A */ + $"E9CE B598 3609 0187 0016 0A2E 71B3 CCC7" /* ε6....q */ + $"C0BB D3DD DEE6 E9ED ECD5 B3B6 CEA9 6F2E" /* ճΩo. */ + $"0A83 007F 020F 3975 B2D5 CEC3 BDB7 B2B4" /* ƒ....9uý */ + $"DBEB E7ED EEDA B9AF CFD1 D5D6 B275 390F" /* ڹֲu9. */ + $"0200 0008 3A84 BEDA D7CF CBBD B0AB ACAC" /* ....:˽ */ + $"8BCB F6EE DFC0 A9B3 BBC5 CFD0 D7DA BD83" /* ڽ */ + $"3A08 0017 84DA D6D0 D5D4 D0C5 B8AB A591" /* :...Ÿ */ + $"7075 D3E9 C5AB 9A98 A2B9 CDD4 D4D0 D4D6" /* puū */ + $"8317 0005 2770 C1DC D3D5 D4D1 CABF A896" /* ...'pʿ */ + $"8575 79C2 B38D 8694 AAC2 D0D4 D3D8 BC6E" /* uy³ؼn */ + $"2705 0000 1C01 0F44 96D7 D8D4 D5D3 D0B6" /* '......Dж */ + $"B49A 8470 938F 7995 B1C5 D0D3 D7D1 9242" /* pyђB */ + $"0F01 8200 1804 2166 BADD D4D5 D1C6 DDC8" /* .....!f */ + $"9A77 7579 9AB8 CBD2 D4DA B563 2004 8500" /* wuyڵc .. */ + $"1601 0C3B 8DD6 DCCE B6D9 EFB1 747E A9C5" /* ...;ζt~ */ + $"D2D5 DBCF 883A 0C01 8800 1203 1B5D B6DF" /* ψ:......] */ + $"BD9B 9F8E 92B9 D0D7 DADF AF5A 1A03 8C00" /* ߯Z... */ + $"0E09 3385 D1D1 B6BF D0D9 DCE4 D281 3209" /* .3Ѷҁ2 */ + $"8F00 0C02 1656 B2EE E3E0 E5E9 AE54 1602" /* ....VT.. */ + $"9200 0807 2F84 E0F6 D77F 2E07 9500 0602" /* .../...... */ + $"1453 9351 1402 9800 0206 1106 8B00 AD00" /* .SQ......... */ + $"040D 272E 1803 9700 0615 66AA C19F 3702" /* ..'......f7. */ + $"9500 0715 6BC3 D7E4 F28A 0D94 0008 156B" /* ...k....k */ + $"C3D4 E7E9 E29B 1593 0009 156B C3D4 E8EB" /* ...k */ + $"E0CB 770D 9200 0A15 6BC3 D5E8 EAE2 C696" /* w...kƖ */ + $"2F02 9100 0A15 6BC3 D4E8 EAE2 C2B2 5E09" /* /...k²^ */ + $"9100 0C14 6AC5 D3E8 EBE3 C4AE B89C 3B05" /* ...jĮ;. */ + $"8F00 0E11 5497 BAED EAE3 C4AF B7BB C7A4" /* ...TįǤ */ + $"3D05 8D00 100A 4A73 5865 B7E8 C3AF B6BD" /* =...JsXeï */ + $"C2C3 CFAD 4005 8C00 111D 7479 7175 85C2" /* ϭ@....tyqu */ + $"AFB6 BDC2 C6CB CCDA B543 068B 0012 2282" /* ڵC..." */ + $"9085 8398 AFB6 BDC2 C6CB D0D5 D6E4 BC42" /* B */ + $"048A 0012 1674 A69A 96AD B8BC C2C6 CBD0" /* ....t */ + $"D5D9 DFDF EA9C 1B8A 0012 0333 90B1 ACB8" /* ....3 */ + $"BCC1 C6CB CFD5 D9DE E3E6 D4AA 288B 0011" /* Ԫ(.. */ + $"0539 98B9 BBC2 C6CB D0D5 D9DF E3E6 DAC1" /* .9 */ + $"8D1D 8C00 101E 88C2 C0C5 CBCF D4DA DFE2" /* .... */ + $"E6DF C3A6 4C07 8A00 130C 4188 BEC8 CBCC" /* æL....A */ + $"CFD5 DADE E2E7 E2C8 B096 3609 0187 0016" /* Ȱ6... */ + $"0A2E 71B3 CCC7 C1BC CFD7 D8DF E3E6 E5CF" /* .q */ + $"ADB3 CFA9 6F2E 0A83 007F 020F 3975 B2D5" /* ϩo.ƒ....9u */ + $"CEC3 BDB7 B2B4 D7E4 E1E6 E8D4 B4AB CFD1" /* ýԴ */ + $"D5D6 B275 390F 0200 0008 3A84 BEDA D7CF" /* ֲu9.....: */ + $"CBBD B0AB ACAC 8AC6 EFE7 D9BB A5B3 BBC5" /* ˽ٻ */ + $"CFD0 D7DA BD83 3A08 0017 84DA D6D0 D5D4" /* ڽ:... */ + $"D0C5 B8AB A590 6C71 CDE2 BFA6 9999 A2B9" /* Ÿlq⿦ */ + $"CDD4 D4D0 D4D6 8317 0005 2770 C1DC D3D5" /* փ...'p */ + $"D4D1 CABF A791 8171 76BD AE8B 8794 AAC2" /* ʿqv */ + $"D0D4 D3D8 BC6E 2705 0000 1C01 0F44 96D7" /* ؼn'......D */ + $"D8D4 D5D3 D0B3 AF95 806D 8F8C 7995 B1C5" /* гmy */ + $"D0D3 D7D1 9242 0F01 8200 1804 2166 BADD" /* ђB.....!f */ + $"D4D5 D1C3 D7C2 9574 7279 9AB8 CBD2 D4DA" /* •try */ + $"B563 2004 8500 1601 0C3B 8DD6 DCCE B6D4" /* c .....;ζ */ + $"E8AB 717E A8C5 D2D5 DBCF 883A 0C01 8800" /* q~ψ:... */ + $"1203 1B5D B6DF BD9A 9D8C 92B9 D0D7 DADF" /* ...]߽ */ + $"AF5A 1A03 8C00 0E09 3385 D1D1 B7C0 D0D9" /* Z....3ѷ */ + $"DCE4 D281 3209 8F00 0C02 1656 B2EE E3E0" /* ҁ2Ə....V */ + $"E5E9 AE54 1602 9200 0807 2F84 E0F6 D77F" /* T...../. */ + $"2E07 9500 0602 1453 9351 1402 9800 0206" /* ......SQ..... */ + $"1106 8B00 AD00 040D 272E 1803 9700 0615" /* ......'...... */ + $"67AC C4A1 3802 9500 0715 6CC5 DAE7 F38C" /* gġ8....l */ + $"0D94 0008 156C C6D7 EAEC E59D 1593 0009" /* ....l.. */ + $"156C C5D7 EBEE E2CD 790E 9200 0A15 6CC6" /* .ly...l */ + $"D7EB EDE4 C998 3002 9100 0A15 6CC5 D7EB" /* ɘ0...l */ + $"EDE5 C5B4 600A 9100 0C15 6BC8 D6EB EEE5" /* Ŵ`‘...k */ + $"C7B0 BB9F 3C05 8F00 0E11 5699 BCF0 EDE5" /* ǰ<....V */ + $"C7B1 B9BE CAA7 3E05 8D00 100A 4B74 5967" /* DZʧ>...KtYg */ + $"BAEB C6B1 B9C0 C4C6 D2AF 4105 8C00 111D" /* ƱүA.... */ + $"767A 7277 86C4 B1B9 BFC4 C9CD CFDD B744" /* vzrwıݷD */ + $"068B 0012 2383 9187 859A B1B9 BFC4 C9CD" /* ...# */ + $"D2D8 D9E7 BE43 048A 0012 1676 A89C 98AF" /* C....v */ + $"BABF C3C9 CDD2 D8DC E2E2 ED9E 1B8A 0012" /* ... */ + $"0334 91B3 AEBA BFC4 C9CD D2D8 DCE1 E6E9" /* .4 */ + $"D7AC 288B 0011 053A 9BBC BEC4 C9CD D2D7" /* ׬(...: */ + $"DCE2 E6E9 DDC3 8F1E 8C00 101E 89C4 C2C8" /* Ï.... */ + $"CDD2 D7DC E2E5 E9E2 C5A8 4D07 8A00 130C" /* ŨM.... */ + $"4188 BEC7 CDCE D1D7 DCE1 E5EA E5CB B297" /* A˲ */ + $"3609 0187 0016 0A2E 71B3 CCC7 C1BC D1DA" /* 6....q */ + $"DBE2 E5E9 E8D2 AFB4 CFA9 6F2E 0A83 007C" /* үϩo.ƒ.| */ + $"020F 3975 B2D5 CEC3 BDB7 B2B4 D8E7 E3E9" /* ..9uý */ + $"EAD7 B6AD CED1 D5D6 B275 390F 0200 0008" /* ׶ֲu9..... */ + $"3A84 BEDA D7CF CBBD B0AB ACAC 8AC8 F2EA" /* :˽ */ + $"DBBD A6B3 BBC5 CFD0 D7DA BD83 3A00 0017" /* ۽ڽ:... */ + $"84DA D6D0 D5D4 D0C5 B8AB A591 6E73 D0E5" /* Ÿns */ + $"C2A8 9A99 A2B9 CDD4 D4D0 D4D6 8300 0005" /* ¨փ... */ + $"2770 C1DC D3D5 D4D1 CABF A893 8373 78BF" /* 'pʿsx */ + $"B08C 8794 AAC2 D0D4 D3D8 BC6E 2780 001C" /* ؼn'.. */ + $"010F 4496 D7D8 D4D5 D3D0 B5B1 9781 6F90" /* ..Dеo */ + $"8D79 95B1 C5D0 D3D7 D192 420F 0182 0018" /* yђB.... */ + $"0421 66BA DDD4 D5D1 C4D9 C497 7574 799A" /* .!fėuty */ + $"B8CB D2D4 DAB5 6320 0485 0016 010C 3B8D" /* ڵc .....; */ + $"D6DC CEB6 D6EB AE72 7EA9 C5D2 D5DB CF88" /* ζr~ψ */ + $"3A0C 0188 0012 031B 5DB6 DFBD 9A9E 8D92" /* :......]߽ */ + $"B9D0 D7DA DFAF 5A1A 038C 000E 0933 85D1" /* ߯Z....3 */ + $"D1B6 BFD0 D9DC E4D2 8132 098F 000C 0216" /* Ѷҁ2Ə.... */ + $"56B2 EEE3 E0E5 E9AE 5416 0292 0008 072F" /* VT...../ */ + $"84E0 F6D7 7F2E 0795 0006 0214 5393 5114" /* .......SQ. */ + $"0298 0002 0611 068B 006C 386D 6B00 0004" /* .......l8mk... */ + $"0800 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"000A 272E 1101 0000 0000 0000 0000 0000" /* .'............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"1473 CCD8 9324 0100 0000 0000 0000 0000" /* .sؓ$.......... */ + $"0000 0000 0000 0000 0000 0000 0000 0014" /* ................ */ + $"7CF3 FFFF F97B 0800 0000 0000 0000 0000" /* |{.......... */ + $"0000 0000 0000 0000 0000 0000 0000 147E" /* ...............~ */ + $"F4FF FFFF FEA5 1000 0000 0000 0000 0000" /* .......... */ + $"0000 0000 0000 0000 0000 0000 0014 7DF4" /* ..............} */ + $"FFFF FFFF FA7F 0800 0000 0000 0000 0000" /* ........... */ + $"0000 0000 0000 0000 0000 0000 157D F3FF" /* .............} */ + $"FFFF FFFD B029 0100 0000 0000 0000 0000" /* ).......... */ + $"0000 0000 0000 0000 0000 0014 7DF4 FFFF" /* ............} */ + $"FFFF FFED 5D06 0000 0000 0000 0000 0000" /* ]........... */ + $"0000 0000 0000 0000 0000 147D F4FF FFFF" /* ...........} */ + $"FFFF FFFE C23A 0400 0000 0000 0000 0000" /* :.......... */ + $"0000 0000 0000 0000 0014 7EF4 FFFF FFFF" /* ..........~ */ + $"FFFF FFFF FEC2 3A04 0000 0000 0000 0000" /* :......... */ + $"0000 0000 0000 0000 0A73 F3FF FFFF FFFF" /* ........s */ + $"FFFF FFFF FFFE C33A 0400 0000 0000 0000" /* :........ */ + $"0000 0000 0000 0000 27CD FFFF FFFF FFFF" /* ........' */ + $"FFFF FFFF FFFF FEC1 3904 0000 0000 0000" /* 9....... */ + $"0000 0000 0000 0000 2ED9 FFFF FFFF FFFF" /* ......... */ + $"FFFF FFFF FFFF FFFE C037 0200 0000 0000" /* 7...... */ + $"0000 0000 0000 0000 1297 FCFF FFFF FFFF" /* ......... */ + $"FFFF FFFF FFFF FFFF FDA3 1700 0000 0000" /* ...... */ + $"0000 0000 0000 0000 012B ADFD FFFF FFFF" /* .........+ */ + $"FFFF FFFF FFFF FFFF FFD9 2F00 0000 0000" /* /..... */ + $"0000 0000 0000 0000 0002 2BAD FDFF FFFF" /* ..........+ */ + $"FFFF FFFF FFFF FFFF FFBA 1F00 0000 0000" /* ...... */ + $"0000 0000 0000 0000 0000 0646 D5FF FFFF" /* ...........F */ + $"FFFF FFFF FFFF FFFF E554 0500 0000 0000" /* T...... */ + $"0000 0000 0000 0000 0622 61B8 FBFF FFFF" /* ........."a */ + $"FFFF FFFF FFFF FFFE B02D 0601 0000 0000" /* -...... */ + $"0000 0000 0000 0829 6DBC F3FF FFFF FFFF" /* .......)m */ + $"FFFF FFFF FFFF FFFF F9BB 6E29 0800 0000" /* n).... */ + $"0000 0001 0B31 7AC8 F6FF FFFF FFFF FFFF" /* .....1z */ + $"FFFF FFFF FFFF FFFF FFFF F6C8 7A31 0B01" /* z1.. */ + $"0000 0737 86D2 F9FF FFFF FFFF FFFF FFFF" /* ...7 */ + $"FFFF FFFF FFFF FFFF FFFF FFFF F9D2 8637" /* ҆7 */ + $"0700 1CA8 F9FF FFFF FFFF FFFF FFFF FFFF" /* ... */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF F9A9" /* */ + $"1C00 0C51 B8F7 FFFF FFFF FFFF FFFF FFFF" /* ...Q */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFF7 B851" /* Q */ + $"0C00 0109 2E80 DEFE FFFF FFFF FFFF FFFF" /* .... */ + $"FFFF FFFF FFFF FFFF FFFF FFFE DE80 2E09" /* ހ. */ + $"0100 0000 0314 4EAE F4FF FFFF FFFF FFFF" /* ......N */ + $"FFFF FFFF FFFF FFFF FFFF F4AE 4E14 0300" /* N... */ + $"0000 0000 0001 0727 76D6 FDFF FFFF FFFF" /* .......'v */ + $"FFFF FFFF FFFF FFFF FDD6 7627 0701 0000" /* v'.... */ + $"0000 0000 0000 0002 1145 A2F0 FFFF FFFF" /* .........E */ + $"FFFF FFFF FFFF FFF0 A245 1102 0000 0000" /* E...... */ + $"0000 0000 0000 0000 0006 226C CEFC FFFF" /* .........."l */ + $"FFFF FFFF FFFC CE6C 2206 0000 0000 0000" /* l"....... */ + $"0000 0000 0000 0000 0000 020E 3E98 EBFF" /* ............> */ + $"FFFF FFFF EB97 3D0E 0200 0000 0000 0000" /* =......... */ + $"0000 0000 0000 0000 0000 0000 051D 62C4" /* ..............b */ + $"FAFF FAC4 621D 0500 0000 0000 0000 0000" /* b........... */ + $"0000 0000 0000 0000 0000 0000 0001 0C36" /* ...............6 */ + $"8FCF 8F36 0C01 0000 0000 0000 0000 0000" /* Ϗ6............ */ + $"0000 0000 0000 0000 0000 0000 0000 0004" /* ................ */ + $"1838 1804 0000 0000 0000 0000 0000 0000" /* .8.............. */ + $"0069 6373 2300 0000 4800 0000 0000 0000" /* .ics#...H....... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 4001 E001" /* ............@.. */ + $"C007 C007 F00F F007 F807 F00F F83F FE3F" /* ......?? */ + $"FE1F F803 E805 D000 8069 7333 3200 0002" /* ....is32... */ + $"6584 0003 010F 1E09 8900 0412 6295 4703" /* e.....Ɖ...bG. */ + $"8700 0512 6CDA F37E 0986 0006 126C DCEF" /* ...l~Ɔ...l */ + $"C349 0385 0007 0F60 DCF0 CBB4 550A 8400" /* I....`˴U„. */ + $"0906 417C BAD2 B5CA C057 0B83 000A 0B64" /* .A|ҵW...d */ + $"8E96 BDC7 CFDC D154 0582 000A 0440 9FBB" /* T...@ */ + $"C7D1 DBE3 EF88 0D82 000A 0325 8FCC CDDA" /* ...% */ + $"E5EC C960 0880 003E 0418 4A92 C1C0 DFE7" /* `..>..J */ + $"EFD2 BE95 4A18 0408 3E95 C9D1 B3A7 A1E7" /* ҾJ...>ѳ */ + $"E1AB B6D5 C994 3D07 3899 D9D2 C5AD 7894" /* ᫶ɔ=.8ŭx */ + $"AD88 AACF D797 3700 031E 68BE DEC8 C476" /* ח7...hv */ + $"81B2 DBBA 661E 0380 000A 0A3A 8FC9 B69A" /* ۺf...:ɶ */ + $"CDDA 8E39 0A83 0008 0219 5EB7 EDBE 6019" /* ڎ9ƒ....^`. */ + $"0286 0004 0837 7535 0882 0084 0003 010F" /* ....7u5...... */ + $"1D09 8900 0412 5F90 4503 8700 0512 69D4" /* .Ɖ..._E....i */ + $"F07B 0886 0006 1269 D6E8 BD47 0385 0007" /* {....iG... */ + $"0E5D D6E9 C5AF 5209 8400 0905 3F79 B4CC" /* .]ůRƄ..?y */ + $"B0C4 BB55 0A83 000A 0B61 8A92 B8C1 C9D5" /* ĻUƒ..a */ + $"CB51 0582 000A 043E 9BB6 C1CB D4DC E884" /* Q...> */ + $"0D82 000A 0325 8DC7 C7D4 DEE5 C35D 0880" /* ...%]. */ + $"003E 0418 4A92 C1BF D9E0 E8CB BB95 4A18" /* .>..J˻J. */ + $"0408 3E95 C9D1 B3A7 9EE0 DBA7 B7D5 C994" /* ..>ѳۧɔ */ + $"3D07 3899 D9D2 C6AC 7490 A888 AACF D797" /* =.8Ƭtח */ + $"3700 031E 68BE DFC5 BE72 80B2 DBBA 661E" /* 7...hžrۺf. */ + $"0380 000A 0A3A 8FC8 B399 CDDA 8E39 0A83" /* ..:ȳڎ9ƒ */ + $"0008 0219 5EB7 EDBE 6019 0286 0004 0837" /* ....^`.....7 */ + $"7535 0882 0084 0003 010F 1E09 8900 0412" /* u5.......Ɖ... */ + $"6092 4603 8700 0512 6BD7 F27C 0986 0006" /* `F....k|Ɔ.. */ + $"126B D8EB C048 0385 0007 0F5F D9EC C8B1" /* .kH...._ȱ */ + $"530A 8400 0906 407A B6CE B2C7 BD56 0A83" /* S„..@zβǽVƒ */ + $"000A 0B62 8C94 BAC4 CCD8 CE52 0582 000A" /* ..bR.. */ + $"043F 9DB8 C4CD D7DF EB86 0D82 000A 0325" /* .?...% */ + $"8ECA CAD6 E1E8 C55E 0880 003D 0418 4A92" /* ^..=..J */ + $"C1C0 DCE3 EBCE BC96 4A18 0008 3E95 C9D1" /* μJ...> */ + $"B3A7 9FE3 DDA9 B6D5 C994 0807 3899 D9D2" /* ݩɔ..8 */ + $"C5AC 7692 AA88 AACF D797 0700 031E 68BE" /* Ŭvח....h */ + $"DEC6 C174 81B2 DBBA 661E 8100 0A0A 3A8F" /* tۺf..: */ + $"C8B4 99CD DA8E 390A 8300 0802 195E B7ED" /* ȴڎ9ƒ....^ */ + $"BE60 1902 8600 0408 3775 3508 8200 7338" /* `.....7u5..s8 */ + $"6D6B 0000 0108 0000 0000 0000 0001 0F1D" /* mk.............. */ + $"0700 0000 0000 0000 0000 0000 0014 6F9E" /* ..............o */ + $"4002 0000 0000 0000 0000 0000 147E F3FC" /* @............~ */ + $"8307 0000 0000 0000 0000 0014 7EF4 FFE6" /* ...........~ */ + $"4E02 0000 0000 0000 0000 147E F4FF FFEA" /* N..........~ */ + $"5F09 0000 0000 0000 0008 70F3 FFFF FFFF" /* _........p */ + $"E15A 0900 0000 0000 000F 9FFE FFFF FFFF" /* Z....... */ + $"FFE1 5304 0000 0000 0004 4BDB FFFF FFFF" /* S.......K */ + $"FFFE 9E0F 0000 0000 0002 1A8A F9FF FFFF" /* ........ */ + $"FFF6 7208 0000 0003 174F 9FED FFFF FFFF" /* r......O */ + $"FFFC BC4F 1703 0A46 A9EB FEFF FFFF FFFF" /* O..F */ + $"FFFF FEEB A947 0B53 CCFD FFFF FFFF FFFF" /* G.S */ + $"FFFF FFFD CC53 0008 3898 EEFF FFFF FFFF" /* S..8 */ + $"FFFF EE98 3808 0000 0216 5FC5 FBFF FFFF" /* 8....._ */ + $"FBC5 5F16 0200 0000 0000 0630 8DE9 FDE9" /* _........0 */ + $"8D30 0600 0000 0000 0000 0001 1255 B155" /* 0...........UU */ + $"1201 0000 0000 6974 3332 0000 4D55 0000" /* ......it32..MU.. */ + $"0000 FF00 FF00 FF00 FF00 FF00 FF00 B400" /* ......... */ + $"07C1 C1C3 C6CC D3DA E2F3 000B C1BC BABE" /* ... */ + $"C5CB D1D7 DDE4 EAF1 F000 0ECA B7B9 C0C5" /* ..ʷ */ + $"CCD3 D7DD E5EA EEF0 F1F2 ED00 0BCA B6B9" /* ..ʶ */ + $"BFC7 CBD2 D8DD E4EA EE80 F001 F1F2 EB00" /* .. */ + $"0BCF B7B9 BEC5 CBD1 D7DD E4E9 EE82 F000" /* .Ϸ. */ + $"F1EA 000B CAB7 B9C0 C5CC D2D7 DDE4 EAEE" /* ..ʷ */ + $"83F0 01F1 F1E8 000B CAB5 B9C0 C6CC D2D8" /* ...ʵ */ + $"DDE4 EAEE 84F0 01EF EBE7 000B CFB7 B9BE" /* ...Ϸ */ + $"C5CB D0D7 DDE3 E9EE 85F0 02EA E3E3 E500" /* .. */ + $"0BCA B7B9 C0C5 CCD2 D7DE E5EA EE84 F004" /* .ʷ. */ + $"EFEA E2DA D8E4 000B C9B5 B9C0 C6CC D2D8" /* ..ɵ */ + $"DDE5 EAEE 84F0 05EF EAE3 DAD3 D0E3 000B" /* ... */ + $"CEB6 B9BE C5CB D0D7 DDE3 EAEE 84F0 06EF" /* ζ. */ + $"EAE3 DBD3 CBC6 E200 0BCA B7B9 C0C5 CCD2" /* ..ʷ */ + $"D7DE E5E9 EE84 F007 EFEA E1DA D3CB C3C1" /* . */ + $"E100 0BC9 B5B9 C0C6 CCD2 D8DD E5EA EE84" /* ..ɵ */ + $"F008 EFEA E3DA D3CC C4BC C0E0 000B CEB6" /* .ļ..ζ */ + $"B9BF C5CB D1D7 DDE3 EAEE 84F0 09EF EAE3" /* */ + $"DBD3 CCC6 BCB6 BFDF 000B CDB8 B9BF C6CC" /* Ƽ..͸ */ + $"D1D7 DDE4 E9EE 84F0 0AEF EAE3 DBD3 CBC4" /* */ + $"BEB4 B6BE DE00 0BC9 B6B9 BFC5 CCD3 D8DD" /* ..ɶ */ + $"E4EA EE84 F00A EFEA E3DA D3CB C3BC B5AF" /* ü */ + $"B8DE 000B CEB6 B9BF C5CB D2D8 DDE3 EAEE" /* ..ζ */ + $"84F0 0AEF EAE3 DBD3 CCC5 BCB5 ACB6 DE00" /* ż. */ + $"0BCD B8B9 BFC6 CCD1 D7DE E4E9 EE84 F00B" /* .͸. */ + $"EFEA E3DB D3CB C4BD B4AC B6C8 DD00 0BC9" /* Ľ.. */ + $"B6B9 BFC5 CCD3 D7DD E5EA EE84 F00B EFEA" /* . */ + $"E3DA D3CB C3BC B4AB B8D1 DD00 0BCA B5B9" /* ü..ʵ */ + $"BFC5 CBD2 D8DD E4EA EE84 F00B EFEA E3DB" /* . */ + $"D3CC C5BC B5AC B9D1 DD00 0BCD B7B9 BFC6" /* ż..ͷ */ + $"CCD1 D7DE E4E9 EE84 F00B EFE9 E2DB D3CB" /* . */ + $"C4BD B4AC B7D3 DD00 0BC9 B6BA C0C5 CCD3" /* Ľ..ɶ */ + $"D7DD E5EA EE84 F00B EFEA E2DA D3CB C3BC" /* .ü */ + $"B4AC B8D1 DD00 0BCA B5B9 C0C7 CBD2 D8DD" /* ..ʵ */ + $"E4EA EE84 F00B EFEA E3DA D3CC C5BC B5AE" /* .ż */ + $"B2C5 DD00 0BCF B7B9 BEC5 CBD1 D7DD E4E9" /* ..Ϸ */ + $"EE85 F00C EAE3 DBD3 CBC5 BDB5 ADB0 BCBC" /* .Ž */ + $"C3DB 000B CAB7 B9C0 C5CC D2D7 DDE4 EAEE" /* ..ʷ */ + $"84F0 0FEF EAE2 DAD3 CBC4 BDB5 ADB1 BABC" /* .Ľ */ + $"BCBE C6D9 000B C9B5 B9C0 C6CC D2D8 DDE4" /* ..ɵ */ + $"EAEE 84F0 11EF EAE3 DAD3 CCC4 BCB5 AEB2" /* .ļ */ + $"BCBC BDBE BFC1 C8D7 000B CEB6 B9BE C5CB" /* ..ζ */ + $"D0D7 DDE3 E9EE 85F0 12EA E3DB D3CC C5BD" /* .Ž */ + $"B5AD B0BC BBBC BEBF C0C2 C4CA D500 0BCA" /* .. */ + $"B7B9 C0C5 CCD2 D7DE E5EA EE84 F015 EFEA" /* . */ + $"E2DA D3CB C4BD B4AD B2BB BCBC BEBF C1C2" /* Ľ */ + $"C4C4 C6CC D300 0BC9 B5B9 C0C6 CCD2 D8DD" /* ..ɵ */ + $"E5EA EE84 F017 EFEA E3DA D3CC C4BC B5AC" /* .ļ */ + $"B3BC BCBD BEC0 C1C2 C4C5 C6C7 C8CE D100" /* . */ + $"0BCE B7BC C3C9 CED2 D7DD E3EA EE84 F00A" /* .η */ + $"EFEA E3DB D3CC C5BD B5AD B280 BC06 BEBF" /* Ž. */ + $"C0C2 C4C5 C680 C801 CBD0 CF00 0BCE BAB4" /* ƀ...κ */ + $"ADAA B6C8 D8E4 E6E9 EE84 F014 EFEA E1DA" /* . */ + $"D3CB C4BD B4AD B2BB BCBD BEBF C1C2 C4C5" /* Ľ */ + $"C680 C803 CACB CDD2 CD00 0BCC A183 6B63" /* ƀ...̡kc */ + $"6164 6A83 B6E8 F484 F01D EFEA E3DA D3CC" /* adj. */ + $"C4BC B5AD B2BC BCBD BEC0 C1C2 C4C5 C6C8" /* ļ */ + $"C8C9 CACC CDCD D0D5 CB00 0EC9 8A6B 6261" /* ..Ɋkba */ + $"6061 6263 6263 84CE F6F1 81F0 1FEF EAE3" /* `abcbc. */ + $"DBD3 CCC6 BDB5 ADB2 BCBC BDBE BFC1 C2C4" /* ƽ */ + $"C5C7 C8C8 C9CB CCCD CECF D0D2 D6C9 0034" /* .4 */ + $"B288 6E6B 6662 6263 6567 6969 6771 C0F5" /* nkfbbcegiigq */ + $"F1F0 F0EF EAE3 DBD3 CBC4 BEB5 ADB0 BBBB" /* ľ */ + $"BCBE BFC1 C2C3 C5C6 C8C8 C9CA CCCC CECF" /* */ + $"D1D2 D3D5 D8C7 001D A67D 7774 6E67 6464" /* ..}wtngdd */ + $"6568 6A6B 6D71 7072 BFF6 F0EF EAE3 DAD3" /* ehjkmqpr */ + $"CBC3 BCB5 ADB2 80BC 15BE BFC1 C2C4 C5C6" /* ü. */ + $"C7C8 C9CA CBCD CECF D1D2 D3D5 D6D7 DAC5" /* */ + $"0038 B282 7D7C 7771 6B67 6768 6B6C 6E71" /* .8}|wqkgghklnq */ + $"7476 757E DAF4 EAE3 DBD3 CCC5 BCB5 ADB2" /* tvu~ż */ + $"BCBC BDBE BFC1 C2C4 C5C7 C8C8 C9CA CCCD" /* */ + $"CECF D1D2 D3D5 D6D7 D8D9 DDC4 0039 947C" /* .9| */ + $"8180 7B75 6E6A 696B 6D6F 7175 7779 7B77" /* {unjikmoquwy{w */ + $"9DEA E3DB D3CB C4BD B4AD B0BB BBBC BEBF" /* Ľ */ + $"C0C2 C4C5 C6C8 C8C9 CACC CDCE CFD1 D2D3" /* */ + $"D4D6 D7D8 D9DA DCE0 C200 1CB5 8582 8585" /* .. */ + $"817A 736F 6E6E 7174 7679 7B7D 7E7F 80C6" /* zsonnqtvy{}~. */ + $"DFD3 CBC3 BCB4 ACB2 80BC 1BBE BFC1 C2C4" /* ü. */ + $"C5C6 C7C8 C9CA CBCD CECF D1D2 D3D5 D6D7" /* */ + $"D8D9 DBDC DDDF E3C1 003C A481 8688 8985" /* .< */ + $"7F79 7471 7275 787A 7C7E 7F81 8483 AED8" /* .ytqruxz|~. */ + $"CDC5 BCB5 AEB2 BCBC BDBE BFC1 C2C4 C5C7" /* ż */ + $"C8C8 C9CA CCCD CED0 D1D2 D3D5 D6D7 D8D9" /* */ + $"DBDC DDDF E0E2 E5C0 003D 9A82 898B 8B89" /* .= */ + $"857E 7876 7678 7A7D 7F81 8184 888A A8CD" /* ~xvvxz}. */ + $"C6BD B5AD B0BC BBBC BEBF C0C2 C4C5 C6C8" /* ƽ */ + $"C8C9 CACC CCCE CFD0 D2D3 D5D6 D7D8 D9DA" /* */ + $"DCDD DEE0 E2E2 E4E7 BF00 088B 888C 8D8F" /* .. */ + $"8F8C 857F 807C 177F 8183 8485 888D 93A7" /* .|.. */ + $"C4BD B5AD B1BA BCBC BEBF C1C2 C4C5 C680" /* Ľƀ */ + $"C817 CACC CDCE CFD1 D2D3 D5D6 D7D8 D9DB" /* . */ + $"DCDD DFE0 E2E3 E4E5 E6E9 BE00 3F8B 8C8E" /* .? */ + $"9193 9492 8D87 8482 8283 8486 8789 8D94" /* */ + $"9BAB BCB5 AEB2 BCBC BDBE BFC1 C2C4 C5C7" /* */ + $"C8C8 C9CA CCCD CED0 D1D2 D4D5 D6D8 D8D9" /* */ + $"DBDC DEDF E0E2 E3E4 E6E7 E7E8 EABD 000A" /* . */ + $"9B8B 9093 9696 9794 908B 8780 8632 8789" /* 2 */ + $"8C92 9AA2 B1B6 ADB0 BCBB BCBE BFC0 C2C4" /* */ + $"C5C6 C8C8 C9CB CCCC CECF D0D2 D3D4 D6D7" /* */ + $"D8D9 DADC DDDE E0E2 E2E4 E6E7 E8E8 E9EA" /* */ + $"ECBC 0020 AE8E 9396 989A 9D9C 9994 8F8B" /* . */ + $"898A 8B8D 9299 A2A9 B3AE B1BA BCBC BEBF" /* */ + $"C1C2 C4C5 C680 C816 CACC CDCE CFD1 D2D3" /* ƀ. */ + $"D5D6 D7D8 D9DB DCDD DFE0 E2E3 E4E5 E780" /* */ + $"E803 EAEB ECE9 BB00 42C2 9696 999B 9FA1" /* ..B– */ + $"A2A0 9C96 908E 8D8F 9398 A0A9 B1B3 B1BC" /* */ + $"BCBD BEC0 C1C2 C4C5 C7C8 C8C9 CACC CDCE" /* */ + $"D0D1 D2D4 D5D6 D8D8 D9DB DCDE DFE0 E2E3" /* */ + $"E4E6 E7E8 E8E9 EAEC ECEB E7E5 BA00 43CC" /* .C */ + $"A295 9B9E A2A5 A6A6 A29B 9592 9194 979D" /* */ + $"A7AE B5B4 BABB BCBE BFC0 C2C4 C5C6 C8C8" /* */ + $"C9CB CCCC CECF D0D2 D3D4 D6D7 D8D9 DADC" /* */ + $"DDDE E0E2 E3E4 E6E7 E8E8 E9EA EBEC EBE9" /* */ + $"E2DD DCBA 001C C29A 9EA2 A5A8 AAAA A7A3" /* ܺ..š */ + $"9D99 9799 9EA5 ADB4 BBB9 BBBC BEBF C1C2" /* */ + $"C4C5 C680 C816 CACC CDCE D0D1 D2D3 D5D6" /* ƀ. */ + $"D7D8 D9DB DCDD DFE0 E2E3 E4E5 E780 E800" /* . */ + $"EA80 EC04 E9E4 DDD6 D3BB 0003 BAA0 A5A9" /* .ӻ.. */ + $"81AC 30A8 A4A0 9E9F A5AB B2BC BCBB BDBE" /* 0 */ + $"C0C1 C2C4 C5C6 C8C8 C9CA CCCD CED0 D1D2" /* */ + $"D4D5 D6D8 D8D9 DBDC DEDF E0E2 E3E4 E6E7" /* */ + $"E8E8 E9EA 80EC 06E9 E5DF D8D0 CAAC BA00" /* .ʬ. */ + $"42D5 B3A5 ABAC ADAE AEAC AAA6 A4A6 ABB0" /* Bճ */ + $"B8BB BABD BEBF C1C2 C4C5 C7C8 C8C9 CBCC" /* */ + $"CDCE CFD1 D2D3 D5D6 D7D8 D9DB DCDD DFE0" /* */ + $"E2E3 E4E6 E7E8 E8E9 EAEB ECED EBE6 E0DB" /* */ + $"D3CB C5AC BB00 41C6 B7AB ADAE AFAF B0AE" /* Ŭ.AƷ */ + $"ACAC ADB1 B5B8 BABC BEBF C1C2 C3C5 C6C8" /* */ + $"C8C9 CACC CCCE CFD1 D2D3 D5D6 D7D8 D9DB" /* */ + $"DCDD DFE0 E1E3 E4E5 E7E8 E8E9 EAEB ECED" /* */ + $"EBE7 E1DB D4CC C6BF ACBC 0004 CFBD ACAF" /* ƿ..Ͻ */ + $"B082 B236 B4B6 B8BA BDBE BFC0 C2C4 C5C6" /* 6 */ + $"C7C8 C9CA CBCD CECF D1D2 D3D5 D6D7 D8D9" /* */ + $"DBDC DDDF E0E2 E3E4 E5E6 E8E8 E9EA EBEC" /* */ + $"EDEC E8E2 DBD4 CDC7 BFB9 ACBD 003F D7BF" /* ǿ.?׿ */ + $"AEB1 B3B4 B5B6 B6B7 B9BB BDBE BFC1 C2C4" /* */ + $"C5C7 C8C8 C9CB CCCD CECF D1D2 D3D5 D6D7" /* */ + $"D8D9 DBDC DDDF E0E2 E3E4 E6E7 E8E8 E9EA" /* */ + $"EBEC EDED E9E4 DED6 CFC9 C2BA B4AC BE00" /* º. */ + $"3ED6 C0B1 B4B5 B7B7 B8B9 BABC BEBF C1C2" /* > */ + $"C3C5 C6C8 C8C9 CACC CCCE CFD1 D2D3 D4D6" /* */ + $"D7D8 D9DB DCDD DFE0 E2E3 E4E5 E7E8 E8E9" /* */ + $"EAEB ECED EDEA E5DF D7CF CAC3 BBB4 ADAC" /* û */ + $"BF00 3DD7 C2B3 B7B8 B9BA BBBD BEBF C1C2" /* .=³ */ + $"C4C5 C6C7 C8C9 CACB CDCE CFD1 D2D3 D5D6" /* */ + $"D7D8 D9DB DCDD DFE0 E2E3 E4E5 E6E8 E8E9" /* */ + $"EAEB ECED EEEA E6DF D9D1 C9C3 BDB5 ADA7" /* ý */ + $"ACC0 003C D8C4 B6B8 BABB BDBE BFC1 C2C4" /* .<Ķ */ + $"C5C7 C8C8 C9CA CCCD CECF D1D2 D3D5 D6D7" /* */ + $"D8D9 DBDC DDDF E0E2 E3E4 E6E7 E8E8 E9EA" /* */ + $"ECEC EDEE EBE7 E2DA D3CC C5BE B8AF A8A3" /* ž */ + $"ACC1 003A D8C6 B8BB BCBE BFC0 C2C4 C5C6" /* .:Ƹ */ + $"C8C8 C9CA CCCD CECF D1D2 D3D4 D6D7 D8D9" /* */ + $"DBDC DDDF E0E2 E3E4 E5E7 E8E8 E9EA EBEC" /* */ + $"EDEE ECE7 E3DB D3CD C6BE B8B1 A9A1 A5C3" /* ƾ */ + $"0039 DAC8 BDBF BFC1 C2C4 C5C6 C7C8 C9CA" /* .9Ƚ */ + $"CBCD CECF D1D2 D3D5 D6D7 D8D9 DBDC DDDF" /* */ + $"E0E2 E3E4 E5E6 E8E8 E9EA EBEC EDEE EDE9" /* */ + $"E3DD D5CD C7C0 B8B1 ABA2 A3C5 C400 37DB" /* .7 */ + $"CCC2 C1C2 C4C5 C7C8 C8C9 CACC CDCE D0D1" /* */ + $"D2D3 D5D6 D7D8 D9DB DCDE DFE0 E2E3 E4E6" /* */ + $"E7E8 E8E9 EAEC ECED EEEE EAE5 DED7 D0C8" /* */ + $"C3BB B3AC A59D CBC5 0036 FDE1 CEC8 C4C5" /* û.6 */ + $"C6C8 C8C9 CACC CCCE CFD0 D2D3 D5D6 D7D8" /* */ + $"D9DA DCDD DEE0 E2E2 E4E6 E7E8 E8E9 EAEB" /* */ + $"ECED EEEE EBE7 E0D8 D1CA C2BC B5AD A79C" /* ¼ */ + $"BEC4 0007 FDFD FFBF BED0 CDC6 80C8 16CA" /* ..ƀ. */ + $"CCCD CECF D1D2 D3D5 D6D7 D8D9 DBDC DDDF" /* */ + $"E0E2 E3E4 E5E7 80E8 12EA ECEC EDEE EEEB" /* . */ + $"E7E1 D9D1 CAC4 BCB5 AEA7 9DB2 C400 38FD" /* ļ.8 */ + $"AAAA BCC5 C9C8 D2D2 C9C9 CACC CDCE D0D1" /* */ + $"D2D4 D5D6 D8D8 D9DB DCDE DFE0 E2E3 E4E6" /* */ + $"E7E8 E8E9 EBEC ECED EEEE EDE8 E2DA D4CB" /* */ + $"C6BE B6B0 A99F A9E6 C200 39FD 7F7F BEC6" /* ƾ.9.. */ + $"CAC9 C9C8 C7D3 D5CB CCCC CECF D0D2 D3D4" /* */ + $"D6D7 D8D9 DADC DDDE E0E2 E3E4 E6E7 E8E8" /* */ + $"E9EA EBEC EDEE EEED EAE2 DBD5 CDC6 C1B9" /* */ + $"B1AB A2A1 DDC1 0023 FD7F 7FC4 C8CB CACA" /* .#.. */ + $"C9C9 C8C7 C5D4 D8CE CECF D1D2 D3D5 D6D7" /* */ + $"D8D9 DBDC DDDF E0E2 E3E4 E5E7 80E8 13EA" /* . */ + $"ECEC EDEE EFED EAE4 DCD5 CFC8 C0BA B2AA" /* */ + $"A3A0 C8C0 003D FD7F 7FC8 CACC CCCB CBCA" /* .=.. */ + $"C9C8 C7C5 C4C2 D5DC D0D1 D2D4 D5D6 D8D8" /* */ + $"D9DB DCDE DFE0 E2E3 E4E6 E7E8 E8E9 EBEC" /* */ + $"ECED EEEF EFEB E6DE D7CE CAC2 BBB4 ACA5" /* » */ + $"9BCB CBC6 BE00 3B7F 8EC8 CBCD CDCC CBCA" /* ƾ.;. */ + $"CAC8 C7C7 C5C4 C1C0 BED6 E0D3 D3D4 D6D7" /* */ + $"D8D9 DADC DDDE E0E2 E3E4 E6E7 E8E8 E9EA" /* */ + $"EBEC EDEE EFEF ECE6 DFD9 D0CA C4BC B4AE" /* ļ */ + $"A89C C280 CE02 CCC8 80BA 0001 AACC 80CE" /* €.Ȁ..̀ */ + $"1FCD CDCC CCCB CAC8 C7C6 C4C2 C0BE BCBA" /* . */ + $"D6E2 D5D6 D7D8 D9DB DCDD DFE0 E2E3 E4E5" /* */ + $"E780 E813 EAEC ECED EEEF EFED E8E0 D9D2" /* . */ + $"CBC4 BEB6 AEA8 9FBE 83D0 02CE CBAB B600" /* ľ.˫. */ + $"02B8 CBCF 80CE 36CD CCCC CBCA C9C7 C6C4" /* .π6 */ + $"C2C1 BFBC BBB9 B7B5 DCE6 D8D8 D9DB DCDE" /* */ + $"DFE0 E2E3 E4E6 E7E8 E8E9 EAEC ECED EEEF" /* */ + $"EFED E9E3 DBD3 CCC5 BEB8 B0A9 A0AD 80CF" /* ž */ + $"80D0 81CF 01CB B8B2 0003 C1CD D0D0 80CF" /* Ё.˸..Ѐ */ + $"27CE CCCB CAC9 C8C6 C4C3 C1BF BDBB BBB8" /* ' */ + $"B7B5 B4B3 D9EC D9DB DCDD DFE0 E2E3 E4E6" /* */ + $"E7E8 E8E9 EAEB ECED EE80 EF0D E9E4 DDD5" /* . */ + $"CEC8 C0B9 B3AB A39D CFCF 86D0 03D1 D1CD" /* φ. */ + $"C1AE 0004 C7D0 D3D2 D280 D137 CFCE CDCC" /* ..Ҁ7 */ + $"CBC9 C7C6 C4C2 C0BE BCBA B9B7 B6B4 B3B4" /* */ + $"B4CC EFDC DDDF E0E1 E3E4 E5E7 E8E8 E9EA" /* */ + $"EBEC EDEE EEEF EFEB E4DD D7CE C8C2 BAB2" /* º */ + $"ACA5 9DCD 81D0 85D2 80D3 01D0 C7AA 0001" /* ́ЅҀ.Ǫ.. */ + $"C8D2 80D4 3ED3 D3D2 D1D0 CFCE CDCB CAC8" /* Ҁ> */ + $"C5C3 C2C0 BEBC BBB9 B8B6 B5B4 B4B3 B2B2" /* */ + $"CAF3 DFE0 E2E3 E4E5 E6E8 E8E9 EAEB ECED" /* */ + $"EEEE F0EF EBE6 DDD7 D0C9 C2BB B3AC A69D" /* » */ + $"CBCF D0D0 81D1 00D2 83D3 81D4 01D2 C8A6" /* Ё.҃Ӂ.Ȧ */ + $"0001 CED3 82D5 16D4 D3D3 D2D1 CECD CBC9" /* ..ӂ. */ + $"C6C4 C2C0 BDBC BBB9 B8B6 B5B4 B4B5 82B4" /* */ + $"28CC F4E1 E3E4 E6E7 E8E8 E9EA ECEC EDEE" /* ( */ + $"EFF0 F0EC E7E1 D8D2 CBC4 BDB6 AEA7 9DB9" /* Ľ */ + $"CDCE CFCF D0D0 D1D1 D2D3 82D4 83D5 01D3" /* ӂԃ. */ + $"CEA1 0002 9FCE D384 D411 D3D2 D1D0 CFCE" /* Ρ..ӄ. */ + $"CBC8 C5C3 C0BC BAB7 B7B5 B4B3 82B1 01B2" /* . */ + $"B280 B12A B2CB F4E4 E5E7 E8E8 E9EA EBEC" /* * */ + $"EDEE EEEF F0EE E8E1 DAD2 CBC5 BEB6 AFA9" /* ž */ + $"A0AA C8C8 C9CA CACC CDCE D0D0 D1D2 D281" /* ҁ */ + $"D384 D402 D3CE 9F9C 0002 B8D0 D485 D548" /* ӄ.Ο..ԅH */ + $"D4D4 D3D2 D1CF CDCA C7C4 C1BC BAB7 B5B3" /* */ + $"B2B2 B1B0 B1B1 B0B0 B1B0 B1B1 B0B1 B0D2" /* */ + $"F4E7 E8E8 E9EA EBEC EDEE EEEF F0EE E9E2" /* */ + $"DBD3 CBC6 BFB7 AFA9 A1A4 C1C1 C3C6 C6C7" /* ƿ */ + $"C9CA CCCE D0D1 D1D3 D380 D486 D502 D4D0" /* ӀԆ. */ + $"B898 0001 C3D1 88D5 47D4 D3D2 D2D1 CECB" /* ..шG */ + $"C9C5 C2BD BAB7 B4B2 B0AF ADAD ACAD ADAF" /* ½ */ + $"AEB0 AFAE AEAC B097 7ED1 EFE8 E9EA ECEC" /* ~ */ + $"EDEE EEF0 F0EF EAE4 DCD6 CEC7 C1BA B2AA" /* */ + $"A49F BEBA BDBD BFC1 C3C4 C7C8 CACD D0D0" /* */ + $"D180 D300 D489 D501 D1C3 9400 01C7 D18A" /* р.ԉ.Ô..ъ */ + $"D515 D4D3 D2D2 D1CE CBC9 C5C0 BDB9 B5B2" /* . */ + $"B0AE ADAC ABAA ACAB 80AA 0FAB AAAB ADA5" /* . */ + $"7372 75C6 EFEB EBEC EDEE EE80 F01F EBE6" /* sru. */ + $"DED6 CFC9 C2BB B4AC A69C B7B2 B3B5 B7B8" /* » */ + $"BABC BEC3 C4C7 CBCD D0D1 D2D3 D3D4 8BD5" /* ԋ */ + $"01D1 C790 0002 CCD3 D78C D614 D5D4 D3D2" /* .ǐ..׌. */ + $"CFCD CBC7 C1BF BAB7 B3B1 AFAD ACAB ABAA" /* */ + $"AB80 AA32 ABA9 ABA1 7578 706E 75C5 F3EC" /* 2uxpnu */ + $"EDEE EEEF F0F0 ECE6 DFD8 CFCA C3BB B4AD" /* û */ + $"A69D B0AB ADAE AEAF B2B5 B8BB BEC3 C6C9" /* */ + $"CCD0 D2D3 D4D4 D58D D601 D3CC 8C00 03CD" /* Ս.̌.. */ + $"D1D3 D38C D516 D4D4 D3D2 D1CF CDCA C7C3" /* ӌ. */ + $"BFBA B8B3 B0AE ACAA A9A8 A7A6 A680 A531" /* 1 */ + $"A6A4 797C 7171 7270 78CA F4EE EEEF F0F0" /* y|qqrpx */ + $"EDE7 E0D9 D2CA C4BD B5AE A89E A9A6 A3A5" /* Ľ */ + $"A5A6 A8A9 AAAF B5B8 BDC1 C6C9 CED0 D2D3" /* */ + $"D3D4 8AD5 06D4 D4D3 D3D4 D2CD 8900 05B3" /* Ԋ.͉.. */ + $"D3D6 D4D3 D38B D525 D4D4 D3D2 D1D0 CECB" /* Ӌ% */ + $"C9C5 C1BE BAB6 B4B1 AEAB A9A7 A6A3 A3A4" /* */ + $"A4A1 A47D 8074 7272 7373 7078 CAF5 80F0" /* }trrsspx */ + $"22EE E9E2 DBD3 CCC5 BEB7 AFA9 A2A5 A29E" /* "ž */ + $"9D9C 9EA0 A0A1 A6AB AEB4 BBBF C5C9 CCD0" /* */ + $"D2D3 D3D4 89D5 08D4 D3D1 D0D1 D3D4 D1B3" /* ԉ.ѳ */ + $"8800 0A78 93C1 D8D7 D5D4 D4D5 D7D7 87D6" /* .xׇ */ + $"15D5 D4D4 D3D2 D1CF CCC9 C6C2 BFBD B9B6" /* .¿ */ + $"B3AE ADAB A8A6 A480 A331 8187 7B76 7474" /* 1{vtt */ + $"7373 7470 75C8 F8F1 EEE9 E3DC D4CD C6BF" /* sstpuƿ */ + $"B8B0 A9A2 A2A0 9B9B 9898 999A 9DA0 A3AA" /* */ + $"AFB4 BBC0 C5CA CDD1 D3D3 D4D5 88D6 09D5" /* Ո */ + $"D3D1 CFCE D0D3 BF93 7888 000C 6B89 8BA5" /* ӿx..k */ + $"D1D7 D6D3 D3D4 D6D6 D785 D61F D5D5 D4D4" /* ׅ. */ + $"D2D2 D1CE CCCA C7C3 C1BE BAB7 B3B0 ACAB" /* */ + $"A7A5 A5A3 8793 867C 7A78 7676 8074 2770" /* |zxvvt'p */ + $"78CC F6EA E3DD D5CE C8C1 B9B3 ABA4 AC90" /* x */ + $"9795 9493 9495 9799 9CA1 A6AD B4BA C0C5" /* */ + $"CBCD D2D2 D3D4 D586 D60B D5D4 D2CF CDCC" /* Ն. */ + $"CECB A38B 896B 8900 0B28 7889 8DBB D7D6" /* ˣk..(x */ + $"D4D2 D2D4 D686 D549 D4D4 D3D3 D1D1 CFCE" /* ֆI */ + $"CCCA C7C3 C1BE BBB7 B3AE ACA9 A6A4 918E" /* */ + $"9488 817D 7B79 7776 7574 7471 7BCA EADE" /* }{ywvuttq{ */ + $"D8D0 C8C3 BCB3 ACA6 AA8E 8F90 908D 8E8F" /* ü */ + $"9194 979C 9FA6 AEB5 BBC0 C6CA CFD1 D1D3" /* */ + $"D3D4 84D5 0CD4 D3D2 CFCD CBCC CEB6 8D89" /* Ԅ.ζ */ + $"7828 8C00 0651 8387 9CCF D8D5 80D2 01D4" /* x(..QՀ. */ + $"D685 D547 D4D3 D2D2 D1D1 D0CE CDCB C8C6" /* օG */ + $"C3C0 BCB9 B4B0 AEA9 9C8D 9E94 8E87 827F" /* . */ + $"7C7A 7876 7575 7470 78C8 DCD1 CAC2 BCB5" /* |zxvuutpx¼ */ + $"ADA7 A88B 8A89 8A88 898A 8D90 959B 9EA3" /* */ + $"ABB0 B7BD C3C8 CCCF D1D2 D3D4 84D5 0BD4" /* Ԅ. */ + $"D3D0 CECC CBCD C79B 8783 518F 000D 166F" /* ǛQ...o */ + $"8689 B4D6 D6D3 D1D1 D4D5 D6D6 84D5 45D3" /* քE */ + $"D3D2 D2D1 D0D0 CECC CAC7 C4C1 BEBA B5B2" /* */ + $"AE8B A89E 9A94 8C87 837F 7D7B 7977 7673" /* .}{ywvs */ + $"7470 8FD2 CCC4 BDB6 AFA7 A59A 8685 8687" /* tpĽ */ + $"8889 8B8E 9298 9FA3 ABB0 B7BC C2C6 CACE" /* */ + $"D0D1 D2D3 D482 D50C D4D3 D1CF CCCB CCCD" /* Ԃ. */ + $"AF89 866F 1692 000C 447E 8495 CADA D7D5" /* o...D~ */ + $"D2D3 D5D8 D784 D643 D5D4 D4D3 D2D2 D1D1" /* ׄC */ + $"CFCC CAC6 C3C2 BDB7 A8A5 A2A3 A19B 928C" /* ½ */ + $"8783 807D 7B79 7674 7576 73AE CBBF B8B1" /* }{yvtuvs˿ */ + $"A9A3 AC7D 8283 8489 888C 8F94 999E A5AD" /* } */ + $"B2B8 BDC3 C6CA CFD1 D2D3 D3D5 82D6 0BD5" /* Ղ. */ + $"D3D1 CFCD CDCE C394 847E 4495 000D 0E66" /* Ô~D...f */ + $"8285 AFD8 D9D6 D2D2 D3D6 D7D7 84D6 40D4" /* ׄ@ */ + $"D4D3 D3D2 D2D0 CFCD CAC9 C5C3 BF9A ACA6" /* ÿ */ + $"AAA9 A298 918C 8784 817D 7976 7576 7670" /* }yvuvvp */ + $"87C1 BAB1 ABA4 A978 7E7F 8182 8889 8D93" /* x~. */ + $"99A1 A7AD B2B9 BEC3 C7CB CFD0 D2D2 D3D5" /* */ + $"81D6 0CD5 D4D2 D0CD CCCD CDAA 8582 660E" /* .ͪf. */ + $"9800 0C39 7881 8EC7 DBD8 D4D1 D2D4 D6D7" /* ..9x */ + $"85D6 19D4 D4D3 D3D2 D1D0 CFCD C9C6 C2A6" /* .¦ */ + $"A8AD B2B1 ABA1 9991 8C88 847F 7B80 7820" /* .{x */ + $"7671 70AD B5AB A6A8 7179 7A7C 7F84 898E" /* vqpqyz|. */ + $"959B A2A7 B0B4 B9BE C4C8 CBCF D0D1 D2D3" /* */ + $"D581 D60B D5D3 D1CE CDCD CFBE 8D81 7839" /* Ձ.Ͼx9 */ + $"9B00 0C08 607F 81A8 D8DB D6D2 D1D2 D4D7" /* ...`. */ + $"85D6 3BD5 D4D4 D3D3 D2D0 D0CE C9C0 AFAE" /* ; */ + $"B4BA B9B3 AAA0 9891 8C87 817D 7C7B 7874" /* }|{xt */ + $"6F6B 9BB1 A6A8 8276 767A 7D83 888E 969A" /* okvvz} */ + $"A2A9 B1B7 BCC2 C4C9 CDCF D1D1 D3D3 D580" /* Հ */ + $"D60C D5D4 D2CF CDCC CECC A481 7F60 089E" /* .̤.`. */ + $"000D 2D74 808B C1DC D9D4 D1D1 D3D6 D7D7" /* ..-t */ + $"84D6 00D4 80D3 43D2 D1CF CBBF ACB5 B9C0" /* .ԀC˿ */ + $"C1BD B6AB A197 918A 8582 807C 7772 6D66" /* |wrmf */ + $"8DAC A593 6D72 777C 8087 8C94 9BA4 ACB3" /* mrw| */ + $"B9BE C2C7 CACD CFD1 D2D3 D3D5 D6D6 D5D4" /* */ + $"D3D1 CECC CDCF B989 8074 2DA2 000C 587E" /* Ϲt-..X~ */ + $"80A1 D6DD D9D4 D1D2 D5D8 D884 D700 D680" /* ؄.ր */ + $"D42E D3D1 CDC2 AFBC C1C7 CBC9 C3B9 ADA1" /* .¯ù */ + $"9790 8B89 857D 7770 6B65 8AA9 9E66 7074" /* }wpkefpt */ + $"7B80 868E 989F A6AF B4BC C1C5 C9CD D0D2" /* { */ + $"D280 D40E D6D7 D7D6 D5D3 D0CE CECF CB9D" /* Ҁ.˝ */ + $"807E 58A5 000C 246E 7F86 BEDE DAD6 D1D0" /* ~X..$n. */ + $"D2D5 D784 D642 D5D4 D2D2 D1CD C8BD C0C7" /* ׄBȽ */ + $"CED2 D4D0 C6B9 AA9F 9892 8D86 7D76 716B" /* ƹ}vqk */ + $"6791 AA61 6B70 7980 868E 98A1 A8AF B5BD" /* gakpy */ + $"C0C5 CACC CFD1 D1D3 D3D4 D6D6 D5D4 D3D0" /* */ + $"CECC CDCF B486 7F6E 24A8 000A 4D7A 7D9A" /* ϴ.n$.Mz} */ + $"D4DD D8D3 CFD0 D380 D781 D640 D5D4 D2D1" /* Ӏׁ@ */ + $"D0CB C6C3 C6CD D5D9 DDDB D4C7 B6AA A29A" /* Ƕ */ + $"9187 7D76 716A 6AA3 6769 6E79 8388 929B" /* }vqjjginy */ + $"A2AA B0B9 BFC2 C8CA CECF D1D2 D3D3 D4D6" /* */ + $"D6D5 D4D1 CFCD CDCE C697 7D7A 4DAB 0050" /* Ɨ}zM.P */ + $"1A69 7D81 B7E0 DBD7 D1D0 D2D6 D8D7 D8D7" /* .i} */ + $"D6D5 D5D4 D1CF CBC5 C2CD D4DC E2E5 E6E0" /* */ + $"D5C6 BAB0 A194 897E 7670 6782 7468 7079" /* ƺ~vpgthpy */ + $"848C 949E A5AF B5BD C1C5 CACD CFD2 D2D4" /* */ + $"D4D6 D6D7 D6D5 D4D1 CFCE CFD1 AE80 7D69" /* Ѯ}i */ + $"1AAE 004C 4676 7C93 D2E0 DAD5 D2D0 D3D7" /* ..LFv| */ + $"D9D9 D7D5 D4D4 D0CE C8C1 B9D3 DBE2 E8EB" /* */ + $"EBE6 DFD5 CABB A897 8A7F 766F 6E7C 6670" /* ʻ.von|fp */ + $"7985 8E97 A0AA B2B8 BDC2 C7CA CED0 D2D3" /* y */ + $"D4D4 D6D7 D7D6 D4D2 D0CE CED0 C690 7C76" /* Ɛ|v */ + $"46B1 004A 0E62 7B7D B0E1 DFDA D3D1 D3D6" /* F.J.b{} */ + $"D9D8 D7D5 D4D0 CEC8 C0B6 A7E3 E9EC EFED" /* */ + $"EBE7 E0D4 C3AE 9C8E 8076 6F80 6470 7D87" /* îvodp} */ + $"919A A5AE B6BA C1C6 CACD D0D3 D3D5 D5D7" /* */ + $"D7D8 D7D6 D4D2 D0CF D0D0 A87D 7B62 0EB4" /* Ш}{b. */ + $"0046 3972 7A8C CFE3 DED9 D3D2 D4D6 D7D7" /* .F9rz */ + $"D6D1 CDC8 BFB6 AA9B FCF0 EFEF EEEB E4D8" /* ȿ */ + $"C7B2 A192 8379 7763 727F 8A95 A1AA B1B9" /* Dzywcr. */ + $"C0C4 C9CE D0D3 D3D5 D6D6 D8D9 D8D8 D6D4" /* */ + $"D2D0 D1D3 C18A 7A72 39B7 0044 085A 7979" /* zr9.D.Zyy */ + $"A9E0 E3DE D7D4 D3D4 D6D4 D3CE C8C0 B7A9" /* */ + $"9E92 FDF4 F0F0 EDE1 D4C5 B2A2 9588 7D60" /* Ų}` */ + $"7784 8E9A A3AD B7BC C2C7 CCCF D3D4 D6D6" /* w */ + $"D7D8 D9DA D9D8 D6D4 D2D1 D3D0 A279 795A" /* ТyyZ */ + $"08BA 0040 2F6F 7987 C9E8 E1DC D5D4 D3D3" /* ..@/oy */ + $"D2CF CBC3 B7AD 9F94 96CF FDF6 EADC CDC0" /* ÷ */ + $"B1A7 976F 687D 8993 9DA7 B2B8 BFC7 CACE" /* oh} */ + $"D2D5 D5D7 D8D8 DADB DADA D8D6 D4D3 D3D5" /* */ + $"BD85 796F 2FBE 003C 5476 78A2 E2E4 DFD7" /* yo/. */ + $"8B8B 8882 7B78 787A 7B7D 7E80 8184 898F" /* {xxz{}~ */ + $"A2BF B8B0 A8AC B5B7 B7B9 B9BB BCBE BFC0" /* */ + $"C2C3 C4C4 C5C7 C8C9 CBCC CDCF CFD1 D2D3" /* */ + $"D5D6 D7D9 DADA DCDD DEDF E3BE 0018 8687" /* .. */ + $"8B8C 8F8F 8E89 8380 7E7E 7F80 8183 8489" /* ~~. */ + $"8F97 A6B7 B0A9 AD80 B723 B9BA BBBC BEBF" /* # */ + $"C0C2 C3C4 C4C6 C7C8 CACB CCCE CFD0 D0D2" /* */ + $"D3D5 D6D8 D9DA DBDC DDDF E0E0 E2E4 BD00" /* . */ + $"0A96 878C 8F91 9392 908B 8783 8082 3284" /* –2 */ + $"8588 8E96 9EAB B1A8 ABB7 B6B7 B9B9 BABC" /* */ + $"BEBF C0C2 C3C4 C4C5 C6C8 C9CA CCCD CFCF" /* */ + $"D0D1 D3D4 D6D7 D9D9 DADB DDDF DFE0 E2E3" /* */ + $"E4E5 BC00 41A8 8A8F 9194 9698 9795 8F8B" /* .A */ + $"8785 8687 898E 959E A4AD A9AC B5B7 B7B9" /* */ + $"B9BB BCBE BFC0 C2C3 C4C4 C5C7 C8C9 CBCC" /* */ + $"CDCF CFD1 D2D3 D5D6 D7D9 D9DA DCDD DEE0" /* */ + $"E1E2 E3E3 E5E5 E2BB 0015 BC91 9194 979A" /* .. */ + $"9D9D 9C97 918C 8A8A 8B8F 949C A3AB ADAC" /* */ + $"80B7 29B9 BABB BCBE BFC0 C2C3 C4C4 C6C7" /* ) */ + $"C8CA CBCC CECF CFD1 D2D3 D5D6 D8D9 DADB" /* */ + $"DCDD DFE0 E1E2 E3E4 E5E5 E4E0 DEBA 0043" /* ޺.C */ + $"C69D 9197 999E A0A1 A19D 9791 8E8D 8F93" /* Ɲ */ + $"99A1 A8AF AFB6 B6B7 B9B9 BABC BEBF C0C2" /* */ + $"C3C4 C4C5 C6C8 C9CA CCCD CFCF D0D2 D3D4" /* */ + $"D6D7 D9D9 DADC DDDF DFE0 E2E3 E4E4 E5E5" /* */ + $"E1DC D7D5 BA00 3ABC 9699 9EA1 A3A5 A5A2" /* պ.: */ + $"9D98 9493 9599 9FA7 AFB6 B4B6 B7B9 B9BB" /* */ + $"BCBE BFC0 C2C3 C4C4 C5C7 C8CA CBCC CDCF" /* */ + $"CFD1 D2D4 D5D6 D7D9 D9DA DCDD DEE0 E1E2" /* */ + $"E3E4 80E5 04E2 DDD6 D0CC BB00 03B4 9BA1" /* .̻.. */ + $"A481 A73A A39F 9B99 9A9F A6AD B7B7 B6B8" /* : */ + $"B9B9 BBBC BEBF C0C2 C3C4 C4C5 C7C8 CACB" /* */ + $"CCCE CFCF D1D2 D3D5 D6D8 D9DA DBDC DDDF" /* */ + $"E0E1 E2E3 E4E4 E5E5 E3DE D9D2 CAC4 A7BA" /* ħ */ + $"0042 CEAE A1A6 A7A8 A9A9 A7A5 A2A0 A0A5" /* .Bή */ + $"ABB2 B6B5 B8B9 B9BB BCBE BFC0 C2C3 C4C4" /* */ + $"C5C7 C8C9 CBCC CDCF D0D0 D2D3 D5D6 D7D9" /* */ + $"D9DA DCDD DFDF E1E2 E3E4 E4E5 E6E4 DFDA" /* */ + $"D4CD C5BF A7BB 0041 C0B1 A6A8 A9AA ABAB" /* ſ.A */ + $"A9A8 A6A7 ABAF B3B5 B7B9 B9BA BCBD BFC0" /* */ + $"C1C3 C4C4 C5C6 C8C9 CBCC CDCF CFD0 D2D3" /* */ + $"D5D6 D7D8 D9DA DCDD DEE0 E1E2 E3E4 E4E5" /* */ + $"E6E4 E0DA D5CE C6C0 BAA7 BC00 04C8 B8A7" /* ..ȸ */ + $"AAAB 82AD 36AE B1B3 B5B8 B9B9 BBBC BEBF" /* 6 */ + $"C0C2 C3C4 C4C5 C7C8 C9CB CCCD CFCF D0D2" /* */ + $"D3D5 D6D7 D8D9 DADC DDDE DFE1 E2E3 E4E4" /* */ + $"E5E6 E5E1 DCD5 CFC7 C0BA B3A7 BD00 3FCF" /* .? */ + $"B8A9 ACAE AEAF AFB1 B2B4 B6B8 B9BA BBBC" /* */ + $"BEBF C0C2 C3C4 C4C5 C7C8 C9CB CCCD CFD0" /* */ + $"D0D2 D3D5 D6D7 D9DA DBDC DDDF E0E1 E2E3" /* */ + $"E4E4 E5E6 E6E2 DED7 D0C9 C3BC B5AE A7BE" /* ü */ + $"003E CFBA ACAF AFB1 B2B3 B4B5 B7B9 B9BA" /* .>Ϻ */ + $"BCBD BFC0 C1C3 C4C4 C5C6 C8C9 CBCC CDCF" /* */ + $"CFD0 D2D3 D5D6 D7D8 D9DA DCDD DEE0 E1E2" /* */ + $"E3E4 E4E5 E6E6 E3DE D8D1 C9C3 BDB6 AFA8" /* ý */ + $"A7BF 003D D0BC AEB0 B2B4 B5B6 B8B9 BABB" /* .=м */ + $"BCBE BFC0 C2C3 C4C4 C5C7 C8C9 CBCC CDCF" /* */ + $"CFD0 D2D3 D5D6 D7D8 D9DA DCDD DEDF E1E2" /* */ + $"E3E4 E4E5 E6E7 E3DF D9D2 CBC3 BDB7 AFA8" /* ý */ + $"A2A7 C000 3CD1 BDB0 B3B5 B6B8 B9BA BBBC" /* .<ѽ */ + $"BEBF C0C2 C3C4 C4C5 C7C8 C9CB CCCD CFD0" /* */ + $"D0D2 D3D5 D6D7 D9DA DBDC DDDF E0E1 E2E3" /* */ + $"E4E4 E5E6 E7E5 E1DB D4CD C6BF B9B2 AAA4" /* ƿ */ + $"9EA7 C100 3AD1 C0B3 B6B7 B9B9 BABC BEBF" /* .: */ + $"C0C1 C3C4 C4C5 C7C8 C9CB CCCD CFCF D0D2" /* */ + $"D3D5 D6D7 D8D9 DADC DDDE E0E1 E2E3 E4E4" /* */ + $"E5E6 E7E5 E1DC D5CD C7C0 B9B3 ACA4 9D9F" /* */ + $"C300 39D3 C2B8 BABA BBBC BEBF C0C2 C3C4" /* .9¸ */ + $"C4C5 C7C8 C9CB CCCD CFCF D0D2 D3D5 D6D7" /* */ + $"D8D9 DADC DDDE DFE1 E2E3 E4E4 E5E6 E7E6" /* */ + $"E2DC D6CE C7C1 BBB3 ACA6 9D9E BFC4 0037" /* .7 */ + $"D4C5 BEBB BCBE BFC0 C2C3 C4C4 C6C7 C8CA" /* ž */ + $"CBCC CDCF CFD0 D2D3 D5D6 D8D9 DADB DCDD" /* */ + $"DFE0 E1E2 E3E4 E4E5 E6E7 E7E3 DED7 D0CA" /* */ + $"C2BD B5AE A7A0 98C5 C500 36FD DBC9 C4BE" /* ½.6ľ */ + $"BFC0 C2C3 C4C4 C5C6 C8C9 CACC CDCF CFD0" /* */ + $"D1D3 D4D6 D7D9 D9DA DBDD DFDF E0E2 E3E4" /* */ + $"E4E5 E6E7 E6E4 E0D9 D1CB C4BD B7B0 A8A2" /* Ľ */ + $"97B8 C400 37FD FDFF BFBD CAC8 C1C2 C3C4" /* .7 */ + $"C4C5 C7C8 C9CB CCCD CFCF D1D2 D3D5 D6D7" /* */ + $"D9D9 DADC DDDE E0E1 E2E3 E4E4 E5E6 E7E7" /* */ + $"E4E0 DAD3 CBC5 BEB7 B1A9 A298 AEC4 0008" /* ž.. */ + $"FDAA AABC C5C9 C8CE CD80 C42C C6C7 C8CA" /* ̀, */ + $"CBCC CECF D0D0 D2D3 D5D6 D8D9 DADB DCDD" /* */ + $"DFE0 E1E2 E3E4 E4E5 E6E7 E7E6 E1DB D5CD" /* */ + $"C5C0 B9B2 ABA4 9AA3 E0C2 0029 FD7F 7FBE" /* .).. */ + $"C6CA C9C9 C8C7 D0D1 C6C5 C6C8 C9CA CCCD" /* */ + $"CFCF D0D1 D3D4 D6D7 D9D9 DADC DDDF DFE0" /* */ + $"E2E3 E4E4 E5E6 80E7 0CE3 DCD5 CFC7 C0BB" /* . */ + $"B3AB A69D 9DD6 C100 3AFD 7F7F C4C8 CBCA" /* .:.. */ + $"CAC9 C9C8 C7C5 D1D3 C8C8 C9CB CCCD CFCF" /* */ + $"D1D2 D3D5 D6D7 D9D9 DADC DDDE E0E1 E2E3" /* */ + $"E4E4 E5E6 E7E8 E6E3 DED6 CFC9 C2BB B4AD" /* » */ + $"A59E 9CC3 C000 3DFD 7F7F C8CA CCCC CBCB" /* .=.. */ + $"CAC9 C8C7 C5C4 C2D2 D8CA CBCC CECF CFD1" /* */ + $"D2D3 D5D6 D8D9 DADB DCDD DFE0 E1E2 E3E4" /* */ + $"E4E5 E6E7 E8E8 E4DF D8D0 C9C4 BDB5 AFA7" /* Ľ */ + $"A096 C9CB C6BE 003B 7F8E C8CB CDCD CCCB" /* ƾ.;. */ + $"CACA C8C7 C7C5 C4C1 C0BE D2DC CECD CFCF" /* */ + $"D0D2 D3D4 D6D7 D9D9 DADC DDDF DFE0 E2E3" /* */ + $"E4E4 E5E6 E7E8 E8E5 E0D9 D2CB C4BE B7AF" /* ľ */ + $"A9A3 98BF 80CE 02CC C880 BA00 01AA CC80" /* .Ȁ..̀ */ + $"CE36 CDCD CCCC CBCA C8C7 C6C4 C2C0 BEBC" /* 6 */ + $"BAD4 DED0 D0D1 D2D4 D5D6 D7D9 D9DA DCDD" /* */ + $"DEE0 E1E2 E3E4 E4E5 E6E7 E8E8 E6E1 D9D3" /* */ + $"CCC5 BEB8 B1A9 A39A BA83 D002 CECB ABB6" /* ž.˫ */ + $"0002 B8CB CF80 CE36 CDCC CCCB CAC9 C7C6" /* ..π6 */ + $"C4C2 C1BF BCBB B9B7 B5D9 E2D1 D2D3 D5D6" /* */ + $"D8D9 DADB DCDD DFE0 E1E2 E3E4 E4E5 E6E7" /* */ + $"E8E8 E7E2 DCD4 CDC7 C0B9 B2AB A49C AA80" /* */ + $"CF80 D081 CF01 CBB8 B200 03C1 CDD0 D080" /* πЁ.˸..Ѐ */ + $"CF27 CECC CBCA C9C8 C6C4 C3C1 BFBD BBBB" /* ' */ + $"B8B7 B5B4 B3D6 E8D3 D5D6 D7D9 D9DA DCDD" /* */ + $"DFDF E1E2 E3E4 E4E5 E6E7 80E8 0DE3 DDD7" /* . */ + $"CFC8 C2BA B4AD A69E 98CF CF86 D003 D1D1" /* ºφ. */ + $"CDC1 AE00 04C7 D0D3 D2D2 80D1 37CF CECD" /* ..Ҁ7 */ + $"CCCB C9C7 C6C4 C2C0 BEBC BAB9 B7B6 B4B3" /* */ + $"B4B4 CBEB D6D7 D8D9 DADC DDDE E0E1 E2E3" /* */ + $"E4E4 E5E6 E7E7 E8E8 E4DD D7D1 C9C2 BCB5" /* ¼ */ + $"ADA7 A098 CB81 D085 D280 D301 D0C7 AA00" /* ˁЅҀ.Ǫ. */ + $"01C8 D280 D43E D3D3 D2D1 D0CF CECD CBCA" /* .Ҁ> */ + $"C8C5 C3C2 C0BE BCBB B9B8 B6B5 B4B4 B3B2" /* */ + $"B2C9 EED8 D9DA DCDD DEDF E1E2 E3E4 E4E5" /* */ + $"E6E7 E7E9 E8E5 DFD7 D1CA C3BC B6AE A7A1" /* ü */ + $"99C9 CFD0 D081 D100 D283 D381 D401 D2C8" /* Ё.҃Ӂ. */ + $"A600 01CE D382 D516 D4D3 D3D2 D1CE CDCB" /* ..ӂ. */ + $"C9C6 C4C2 C0BD BCBB B9B8 B6B5 B4B4 B582" /* */ + $"B428 CBF0 DBDC DDDF E0E1 E2E3 E4E4 E5E6" /* ( */ + $"E7E8 E9E9 E6E1 DAD2 CBC5 BEB7 B1A9 A298" /* ž */ + $"B6CD CECF CFD0 D0D1 D1D2 D382 D483 D501" /* ӂԃ. */ + $"D3CE A100 029F CED3 84D4 11D3 D2D1 D0CF" /* Ρ..ӄ. */ + $"CECB C8C5 C3C0 BCBA B7B7 B5B4 B382 B101" /* . */ + $"B2B2 80B1 2AB2 CBEE DDDE E0E1 E2E3 E4E4" /* * */ + $"E5E6 E7E7 E8E9 E7E1 DBD4 CCC5 C0B8 B1AA" /* */ + $"A49B A7C7 C8C9 CACA CCCD CED0 D0D1 D2D2" /* */ + $"81D3 84D4 02D3 CE9F 9C00 02B8 D0D4 85D5" /* ӄ.Ο..ԅ */ + $"48D4 D4D3 D2D1 CFCD CAC7 C4C1 BCBA B7B5" /* H */ + $"B3B2 B2B1 B0B1 B1B0 B0B1 B0B1 B1B0 B1B0" /* */ + $"CFF0 E0E1 E2E3 E4E4 E5E6 E7E7 E8E9 E7E2" /* */ + $"DBD5 CEC5 C0BA B2AB A59C 9FC1 C1C3 C6C6" /* */ + $"C7C9 CACC CED0 D1D1 D3D3 80D4 86D5 02D4" /* ӀԆ. */ + $"D0B8 9800 01C3 D188 D547 D4D3 D2D2 D1CE" /* и..шG */ + $"CBC9 C5C2 BDBA B7B4 B2B0 AFAD ADAC ADAD" /* ½ */ + $"AFAE B0AF AEAE ACB0 977B CCE8 E2E3 E4E4" /* { */ + $"E5E6 E7E7 E9E9 E8E3 DDD6 CFC8 C1BB B5AD" /* */ + $"A69F 9ABD BABD BDBF C1C3 C4C7 C8CA CDD0" /* */ + $"D0D1 80D3 00D4 89D5 01D1 C394 0001 C7D1" /* р.ԉ.Ô.. */ + $"8AD5 15D4 D3D2 D2D1 CECB C9C5 C0BD B9B5" /* . */ + $"B2B0 AEAD ACAB AAAC AB80 AA0F ABAA ABAD" /* . */ + $"A572 6F72 C1E9 E4E4 E5E6 E7E7 80E9 1FE4" /* ror. */ + $"DFD8 D0CA C3BC B5AF A7A1 97B5 B2B3 B5B7" /* ü */ + $"B8BA BCBE C3C4 C7CB CDD0 D1D2 D3D3 D48B" /* ԋ */ + $"D501 D1C7 9000 02CC D3D7 8CD6 14D5 D4D3" /* .ǐ..׌. */ + $"D2CF CDCB C7C1 BFBA B7B3 B1AF ADAC ABAB" /* */ + $"AAAB 80AA 32AB A9AB A173 756D 6B71 C0EB" /* 2sumkq */ + $"E5E6 E7E7 E8E9 E9E5 DFD9 D2CA C4BD B6AF" /* Ľ */ + $"A9A1 98AD ABAD AEAE AFB2 B5B8 BBBE C3C6" /* */ + $"C9CC D0D2 D3D4 D4D5 8DD6 01D3 CC8C 0003" /* Ս.̌.. */ + $"CDD1 D3D3 8CD5 16D4 D4D3 D2D1 CFCD CAC7" /* ӌ. */ + $"C3BF BAB8 B3B0 AEAC AAA9 A8A7 A6A6 80A5" /* ÿ */ + $"31A6 A477 796D 6E6F 6D75 C4ED E7E7 E8E9" /* 1wymnomu */ + $"E9E6 E1DA D3CC C4BF B8B0 AAA3 99A5 A5A3" /* Ŀ */ + $"A5A5 A6A8 A9AA AFB5 B8BD C1C6 C9CE D0D2" /* */ + $"D3D3 D48A D506 D4D4 D3D3 D4D2 CD89 0005" /* Ԋ.͉.. */ + $"B3D3 D6D4 D3D3 8BD5 25D4 D4D3 D2D1 D0CE" /* Ӌ% */ + $"CBC9 C5C1 BEBA B6B4 B1AE ABA9 A7A6 A3A3" /* */ + $"A4A4 A1A4 7C7C 706E 6F70 706D 74C5 EE80" /* ||pnoppmt */ + $"E922 E7E2 DBD4 CDC6 BFB9 B2AA A49D A1A1" /* "ƿ */ + $"9E9D 9C9E A0A0 A1A6 ABAE B4BB BFC5 C9CC" /* */ + $"D0D2 D3D3 D489 D508 D4D3 D1D0 D1D3 D4D1" /* ԉ. */ + $"B388 000A 7893 C1D8 D7D5 D4D4 D5D7 D787" /* .xׇ */ + $"D615 D5D4 D4D3 D2D1 CFCC C9C6 C2BF BDB9" /* .¿ */ + $"B6B3 AEAD ABA8 A6A4 80A3 0380 8477 7380" /* .ws */ + $"712A 7070 6C72 C2F1 E9E7 E2DC D5CE C7C0" /* q*pplr */ + $"BAB3 ABA4 9D9D A09B 9B98 9899 9A9D A0A3" /* */ + $"AAAF B4BB C0C5 CACD D1D3 D3D4 D588 D609" /* Ո */ + $"D5D3 D1CF CED0 D3BF 9378 8800 0C6B 898B" /* ӿx..k */ + $"A5D1 D7D6 D3D3 D4D6 D6D7 85D6 4AD5 D5D4" /* ׅJ */ + $"D4D2 D2D1 CECC CAC7 C3C1 BEBA B7B3 B0AC" /* */ + $"ABA7 A5A5 A386 8F82 7976 7473 7271 7071" /* yvtsrqpq */ + $"6D75 C6EF E4DD D8D0 C8C2 BBB3 ADA6 9FA7" /* mu» */ + $"8F97 9594 9394 9597 999C A1A6 ADB4 BAC0" /* */ + $"C5CB CDD2 D2D3 D4D5 86D6 0BD5 D4D2 CFCD" /* Ն. */ + $"CCCE CBA3 8B89 6B89 000B 2878 898D BBD7" /* ˣk..(x */ + $"D6D4 D2D2 D4D6 86D5 1FD4 D4D3 D3D1 D1CF" /* ֆ. */ + $"CECC CAC7 C3C1 BEBB B7B3 AEAC A9A6 A491" /* */ + $"8B8F 847C 7977 7574 7280 7126 6D77 C5E3" /* |ywutrq&mw */ + $"D8D1 CAC2 BDB6 AEA7 A1A4 8C8F 9090 8D8E" /* ½ */ + $"8F91 9497 9C9F A6AE B5BB C0C6 CACF D1D1" /* */ + $"D3D3 D484 D50C D4D3 D2CF CDCB CCCE B68D" /* Ԅ.ζ */ + $"8978 288C 0006 5183 879C CFD8 D580 D201" /* x(..QՀ. */ + $"D4D6 85D5 47D4 D3D2 D2D1 D1D0 CECD CBC8" /* օG */ + $"C6C3 C0BC B9B4 B0AE A99C 8A9A 9089 827F" /* . */ + $"7B78 7675 7372 7271 6D75 C2D6 CAC4 BDB7" /* {xvusrrqmuĽ */ + $"B0A8 A2A3 898A 898A 8889 8A8D 9095 9B9E" /* */ + $"A3AB B0B7 BDC3 C8CC CFD1 D2D3 D484 D50B" /* Ԅ. */ + $"D4D3 D0CE CCCB CDC7 9B87 8351 8F00 0D16" /* ǛQ... */ + $"6F86 89B4 D6D6 D3D1 D1D4 D5D6 D684 D545" /* oքE */ + $"D3D3 D2D2 D1D0 D0CE CCCA C7C4 C1BE BAB5" /* */ + $"B2AE 8AA3 9896 9088 837F 7C7A 7875 7473" /* .|zxuts */ + $"7071 6D8B CCC6 BFB8 B1AA A2A0 9786 8586" /* pqmƿ */ + $"8788 898B 8E92 989F A3AB B0B7 BCC2 C6CA" /* */ + $"CED0 D1D2 D3D4 82D5 0CD4 D3D1 CFCC CBCC" /* Ԃ. */ + $"CDAF 8986 6F16 9200 0C44 7E84 95CA DAD7" /* ͯo...D~ */ + $"D5D2 D3D5 D8D7 84D6 43D5 D4D4 D3D2 D2D1" /* ׄC */ + $"D1CF CCCA C6C3 C2BD B7A8 A09D 9E9C 958E" /* ½ */ + $"8883 7F7D 7A78 7573 7172 7370 AAC5 BAB2" /* .}zxusqrspź */ + $"ACA5 9EA8 7C82 8384 8988 8C8F 9499 9EA5" /* | */ + $"ADB2 B8BD C3C6 CACF D1D2 D3D3 D582 D60B" /* Ղ. */ + $"D5D3 D1CF CDCD CEC3 9484 7E44 9500 0D0E" /* Ô~D... */ + $"6682 85AF D8D9 D6D2 D2D3 D6D7 D784 D640" /* fׄ@ */ + $"D4D4 D3D3 D2D2 D0CF CDCA C9C5 C3BF 99A6" /* ÿ */ + $"A1A5 A49D 948C 8783 807D 7975 7372 7373" /* }yusrss */ + $"6D83 BBB4 ACA6 A0A4 777E 7F81 8288 898D" /* mw~. */ + $"9399 A1A7 ADB2 B9BE C3C7 CBCF D0D2 D2D3" /* */ + $"D581 D60C D5D4 D2D0 CDCC CDCD AA85 8266" /* Ձ.ͪf */ + $"0E98 000C 3978 818E C7DB D8D4 D1D2 D4D6" /* ...9x */ + $"D785 D63D D4D4 D3D3 D2D1 D0CF CDC9 C6C2" /* ׅ= */ + $"A2A3 A8AD ACA6 9C94 8D88 8480 7B77 7574" /* {wut */ + $"7472 6D6C A7B0 A6A1 A470 797A 7C7F 8489" /* trmlpyz|. */ + $"8E95 9BA2 A7B0 B4B9 BEC4 C8CB CFD0 D1D2" /* */ + $"D3D5 81D6 0BD5 D3D1 CECD CDCF BE8D 8178" /* Ձ.Ͼx */ + $"399B 000C 0860 7F81 A8D8 DBD6 D2D1 D2D4" /* 9...`. */ + $"D785 D63B D5D4 D4D3 D3D2 D0D0 CEC9 C0AB" /* ׅ; */ + $"A9AE B5B4 AEA4 9C93 8D88 837D 7A78 7774" /* }zxwt */ + $"716C 6897 ACA1 A380 7676 7A7D 8388 8E96" /* qlhvvz} */ + $"9AA2 A9B1 B7BC C2C4 C9CD CFD1 D1D3 D3D5" /* */ + $"80D6 0CD5 D4D2 CFCD CCCE CCA4 817F 6008" /* .̤.`. */ + $"9E00 0D2D 7480 8BC1 DCD9 D4D1 D1D3 D6D7" /* ..-t */ + $"D784 D600 D480 D343 D2D1 CFCB BFA7 B0B5" /* ׄ.ԀC˿ */ + $"BBBC B9B0 A69C 938D 8781 7E7C 7873 6F6A" /* ~|xsoj */ + $"6389 A7A0 8F6D 7277 7C80 878C 949B A4AC" /* cmrw| */ + $"B3B9 BEC2 C7CA CDCF D1D2 D3D3 D5D6 D6D5" /* */ + $"D4D3 D1CE CCCD CFB9 8980 742D A200 0C58" /* Ϲt-..X */ + $"7E80 A1D6 DDD9 D4D1 D2D5 D8D8 84D7 00D6" /* ~؄. */ + $"80D4 2ED3 D1CD C2AA B7BC C1C5 C3BD B4A8" /* .ªý */ + $"9C93 8C87 8481 7A73 6D68 6286 A499 6670" /* zsmhbfp */ + $"747B 8086 8E98 9FA6 AFB4 BCC1 C5C9 CDD0" /* t{ */ + $"D2D2 80D4 0ED6 D7D7 D6D5 D3D0 CECE CFCB" /* Ҁ. */ + $"9D80 7E58 A500 0C24 6E7F 86BE DEDA D6D1" /* ~X..$n. */ + $"D0D2 D5D7 84D6 42D5 D4D2 D2D1 CDC8 B9BA" /* ׄBȹ */ + $"C1C8 CCCD C9C1 B4A5 9A93 8E89 827A 736D" /* zsm */ + $"6864 8DA6 616B 7079 8086 8E98 A1A8 AFB5" /* hdakpy */ + $"BDC0 C5CA CCCF D1D1 D3D3 D4D6 D6D5 D4D3" /* */ + $"D0CE CCCD CFB4 867F 6E24 A800 0A4D 7A7D" /* ϴ.n$.Mz} */ + $"9AD4 DDD8 D3CF D0D3 80D7 81D6 40D5 D4D2" /* Ӏׁ@ */ + $"D1D0 CBC6 BFC0 C7CF D3D7 D5CD C1B1 A69D" /* ƿ */ + $"958D 837A 726E 6766 9E66 696E 7983 8892" /* zrngffiny */ + $"9BA2 AAB0 B9BF C2C8 CACE CFD1 D2D3 D3D4" /* */ + $"D6D6 D5D4 D1CF CDCD CEC6 977D 7A4D AB00" /* Ɨ}zM. */ + $"501A 697D 81B7 E0DB D7D1 D0D2 D6D8 D7D8" /* P.i} */ + $"D7D6 D5D5 D4D1 CFCB C5C0 C7CE D5DC DFDF" /* */ + $"DACE C0B5 AA9D 9085 7A72 6D64 7E73 6870" /* zrmd~shp */ + $"7984 8C94 9EA5 AFB5 BDC1 C5CA CDCF D2D2" /* y */ + $"D4D4 D6D6 D7D6 D5D4 D1CF CECF D1AE 807D" /* Ѯ} */ + $"691A AE00 4C46 767C 93D2 E0DA D5D2 D0D3" /* i..LFv| */ + $"D7D9 D9D7 D5D4 D4D0 CEC8 C1B9 CED5 DBE1" /* */ + $"E4E4 E0D9 CEC4 B6A3 9386 7B73 6B6A 7866" /* Ķ{skjxf */ + $"7079 858E 97A0 AAB2 B8BD C2C7 CACE D0D2" /* py */ + $"D3D4 D4D6 D7D7 D6D4 D2D0 CECE D0C6 907C" /* Ɛ| */ + $"7646 B100 4A0E 627B 7DB0 E1DF DAD3 D1D3" /* vF.J.b{} */ + $"D6D9 D8D7 D5D4 D0CE C8C0 B6A5 DDE2 E6E8" /* */ + $"E6E4 E0D9 CEBD A897 8A7D 736C 7C64 707D" /* ν}sl|dp} */ + $"8791 9AA5 AEB6 BAC1 C6CA CDD0 D3D3 D5D5" /* */ + $"D7D7 D8D7 D6D4 D2D0 CFD0 D0A8 7D7B 620E" /* Ш}{b. */ + $"B400 4639 727A 8CCF E3DE D9D3 D2D4 D6D7" /* .F9rz */ + $"D7D6 D1CD C8BF B6AA 99F5 E9E8 E8E7 E4DE" /* ȿ */ + $"D2C1 AD9C 8E7F 7674 6272 7F8A 95A1 AAB1" /* .vtbr. */ + $"B9C0 C4C9 CED0 D3D3 D5D6 D6D8 D9D8 D8D6" /* */ + $"D4D2 D0D1 D3C1 8A7A 7239 B700 4408 5A79" /* zr9.D.Zy */ + $"79A9 E0E3 DED7 D4D3 D4D6 D4D3 CEC8 C0B7" /* y */ + $"A99E 90F6 EDE9 E9E6 DBCE BFAD 9D90 8479" /* οy */ + $"5F77 848E 9AA3 ADB7 BCC2 C7CC CFD3 D4D6" /* _w */ + $"D6D7 D8D9 DAD9 D8D6 D4D2 D1D3 D0A2 7979" /* Тyy */ + $"5A08 BA00 402F 6F79 87C9 E8E1 DCD5 D4D3" /* Z..@/oy */ + $"D3D2 CFCB C3B7 AD9F 9494 CAF6 EFE3 D5C7" /* ÷ */ + $"BBAC A293 6D68 7D89 939D A7B2 B8BF C7CA" /* mh} */ + $"CED2 D5D5 D7D8 D8DA DBDA DAD8 D6D4 D3D3" /* */ + $"D5BD 8579 6F2F BE00 3C54 7678 A2E2 E4DF" /* սyo/. */ + $"8986 8A8B 8C8D 8983 7D7A 7A7B 7D7F 8081" /* }zz{}. */ + $"8385 8A90 A4C1 BAB2 AAAF B8B9 B9BB BCBE" /* */ + $"BFC1 C1C2 C4C5 C6C7 C9CA CBCC CDCD CFD1" /* */ + $"D2D4 D5D6 D8D9 D9DA DCDE DFE0 E1E2 E5BE" /* */ + $"003F 8889 8D8E 9091 908B 8581 807F 8182" /* .?. */ + $"8384 878B 9298 A8B9 B2AB AFB9 B9BA BBBC" /* */ + $"BEC0 C1C1 C2C4 C5C6 C8C9 CACB CDCD CECF" /* */ + $"D1D2 D3D5 D6D8 D9D9 DBDC DEDF E0E2 E3E3" /* */ + $"E5E7 BD00 0A98 898E 9093 9494 918D 8985" /* .˜ */ + $"8084 3285 878A 9097 9FAE B3AA AEB9 B8B9" /* 2 */ + $"BBBC BDBF C1C1 C2C4 C5C6 C8C8 C9CB CCCD" /* */ + $"CECF D0D2 D3D4 D6D8 D9D9 DADC DEDE E0E2" /* */ + $"E2E3 E5E6 E6E8 BC00 41AA 8C91 9395 979A" /* .A */ + $"9995 918C 8887 8788 8B8F 96A0 A7B0 ACAF" /* */ + $"B8B9 B9BB BCBE BFC1 C1C2 C4C5 C6C7 C9CA" /* */ + $"CBCC CDCD CFD1 D2D4 D5D6 D8D9 D9DA DCDE" /* */ + $"DFE0 E1E3 E4E5 E6E6 E7E8 E6BB 0042 C093" /* .B */ + $"9396 989C 9F9F 9D99 938E 8B8B 8D91 959D" /* */ + $"A6AE B0AF B9B9 BABB BDBE C0C1 C1C2 C4C5" /* */ + $"C6C8 C9CA CBCD CDCE CFD1 D2D4 D5D6 D8D9" /* */ + $"D9DA DCDE DFE0 E2E3 E4E5 E6E6 E8E8 E7E3" /* */ + $"E1BA 0043 C9A0 9398 9CA0 A2A3 A39F 9893" /* .Cɠ */ + $"908F 9195 9AA4 ABB1 B1B7 B8B9 BBBC BDBF" /* */ + $"C1C1 C2C4 C5C6 C8C8 C9CB CCCD CECF D0D2" /* */ + $"D3D5 D6D8 D9D9 DADC DEDF E0E2 E2E3 E5E6" /* */ + $"E6E7 E8E7 E5DF DAD9 BA00 42BF 989C A0A3" /* ٺ.B */ + $"A5A7 A7A4 A099 9695 969B A2AA B1B8 B6B8" /* */ + $"B9BB BCBE BFC1 C1C2 C4C5 C6C7 C9CA CBCC" /* */ + $"CDCD CFD1 D2D4 D5D7 D8D9 D9DA DCDE DFE0" /* */ + $"E1E3 E4E5 E6E6 E7E8 E8E5 E0D9 D2D0 BB00" /* л. */ + $"03B7 9DA2 A681 A930 A5A1 9D9B 9DA3 A8AF" /* .0 */ + $"B9B9 B8BA BBBD BEBF C1C1 C2C4 C5C6 C8C9" /* */ + $"CACB CDCD CECF D1D2 D4D5 D6D8 D9D9 DADC" /* */ + $"DEDF E0E2 E3E4 E5E6 E680 E806 E6E1 DBD4" /* . */ + $"CDC7 AABA 0042 D2B0 A3A8 A9AA ABAB A9A6" /* Ǫ.BҰ */ + $"A3A1 A3A8 ADB4 B8B7 BABB BCBE C0C1 C1C2" /* */ + $"C4C5 C6C8 C9CA CBCC CDCE CFD1 D2D3 D5D6" /* */ + $"D8D9 D9DB DCDE DFE0 E2E2 E4E5 E6E7 E7E8" /* */ + $"E9E7 E2DC D7CF C8C1 AABB 0041 C3B3 A8AA" /* .Aó */ + $"ABAC ADAD ABAA A9AA ADB1 B5B7 B9BB BCBE" /* */ + $"BFC1 C1C2 C3C5 C6C7 C9C9 CBCC CDCD CFD1" /* */ + $"D2D3 D5D6 D8D9 D9DA DCDD DFE0 E1E3 E4E5" /* */ + $"E6E6 E7E8 E9E7 E3DD D7D1 C9C2 BCAA BC00" /* ¼. */ + $"04CB BAA9 ACAD 82AF 12B0 B3B5 B7BA BBBC" /* .˺. */ + $"BDBF C0C1 C2C4 C5C6 C7C8 CACB 80CD 20CF" /* ˀ */ + $"D1D2 D4D5 D6D8 D9D9 DADC DEDF E0E1 E2E4" /* */ + $"E5E6 E6E7 E8E9 E8E4 DED8 D1CA C3BC B6AA" /* ü */ + $"BD00 3FD2 BBAB AEB0 B1B2 B2B3 B4B6 B8BA" /* .?һ */ + $"BBBC BEC0 C1C1 C2C4 C5C6 C8C9 CACB CCCD" /* */ + $"CECF D1D2 D3D5 D6D8 D9D9 DBDC DEDF E0E2" /* */ + $"E3E4 E5E6 E7E7 E8E9 E9E5 E1DA D3CC C5BF" /* ſ */ + $"B7B0 AABE 003E D2BD AEB1 B2B3 B4B5 B6B7" /* .>ҽ */ + $"B9BB BCBE BFC1 C1C2 C3C5 C6C7 C9C9 CBCC" /* */ + $"CDCD CFD0 D2D4 D5D6 D8D9 D9DA DCDE DFE0" /* */ + $"E1E3 E4E5 E6E6 E7E8 E9E9 E6E1 DBD4 CCC6" /* */ + $"C0B8 B1AA AABF 0016 D3BF B0B3 B4B6 B7B8" /* ..ӿ */ + $"BABB BCBE BFC0 C1C2 C4C5 C6C7 C8CA CB80" /* ˀ */ + $"CD23 CFD1 D2D4 D5D6 D8D9 D9DA DCDE DFE0" /* # */ + $"E1E2 E4E5 E6E6 E7E8 E9EA E6E2 DBD5 CDC6" /* */ + $"C0BA B1AA A5AA C000 3CD5 C1B2 B5B7 B8BA" /* .< */ + $"BBBC BEC0 C1C1 C2C4 C5C6 C8C9 CACB CCCD" /* */ + $"CECF D1D2 D3D5 D6D8 D9D9 DBDC DEDF E0E2" /* */ + $"E3E4 E5E6 E6E8 E8E9 EAE7 E4DE D6D0 C9C2" /* */ + $"BBB5 ACA6 A0AA C100 3AD5 C2B5 B8B9 BBBC" /* .:µ */ + $"BDBF C1C1 C2C3 C5C6 C7C9 CACB CCCD CDCF" /* */ + $"D0D2 D4D5 D6D8 D9D9 DADC DEDF E0E1 E3E4" /* */ + $"E5E6 E6E7 E8E9 EAE8 E3DF D7D0 C9C3 BBB5" /* û */ + $"AEA7 9FA2 C300 10D7 C5BA BCBC BEBF C1C1" /* ..ź */ + $"C2C4 C5C6 C7C8 CACB 80CD 25CF D1D2 D4D5" /* ˀ% */ + $"D6D8 D9D9 DADC DEDF E0E1 E2E4 E5E6 E6E7" /* */ + $"E8E9 EAE9 E5DF D9D1 C9C4 BDB5 AEA8 9FA0" /* Ľ */ + $"C2C4 0037 D8C9 C0BE C0C1 C1C2 C4C5 C6C8" /* .7 */ + $"C9CA CBCD CDCE CFD1 D2D3 D5D6 D8D9 D9DB" /* */ + $"DCDE DFE0 E2E3 E4E5 E6E6 E8E8 E9EA EAE6" /* */ + $"E1DA D4CC C5BF B8B0 A9A2 9AC7 C500 36FD" /* ſ.6 */ + $"DECC C7C2 C1C2 C4C5 C6C7 C8C9 CBCC CDCE" /* */ + $"CFD1 D2D3 D4D6 D8D9 D9DA DCDE DEE0 E2E2" /* */ + $"E3E5 E6E6 E7E8 E9EA EAE7 E3DC D4CD C7BF" /* ǿ */ + $"BAB2 AAA5 99BB C400 37FD FDFF BFBD CCC9" /* .7 */ + $"C2C4 C5C6 C7C9 CACB CCCD CDCF D1D2 D4D5" /* */ + $"D6D8 D9D9 DADC DEDF E0E1 E3E4 E5E6 E6E7" /* */ + $"E8E9 EAEA E7E3 DDD6 CDC8 C1B9 B2AB A49A" /* */ + $"B0C4 0038 FDAA AABC C5C9 C8D0 CEC6 C6C8" /* .8 */ + $"C9CA CBCD CDCE CFD1 D2D3 D5D6 D8D9 D9DA" /* */ + $"DCDE DFE0 E2E3 E4E5 E6E6 E8E8 E9EA EAE9" /* */ + $"E4DE D8D0 C8C3 BBB4 ADA6 9CA6 E4C2 000B" /* û.. */ + $"FD7F 7FBE C6CA C9C9 C8C7 D1D2 80C9 1ACB" /* ..Ҁ. */ + $"CCCD CECF D0D2 D3D4 D6D8 D9D9 DADC DEDF" /* */ + $"E0E2 E2E3 E5E6 E6E7 E8E9 80EA 0CE6 DFD8" /* . */ + $"D1CA C3BD B5AE A89F 9EDA C100 3AFD 7F7F" /* ý.:.. */ + $"C4C8 CBCA CAC9 C9C8 C7C5 D2D5 CBCB CCCD" /* */ + $"CDCF D1D2 D4D5 D6D8 D9D9 DADC DEDF E0E1" /* */ + $"E3E4 E5E6 E6E7 E8E9 EAEB E9E6 E0D8 D2CB" /* */ + $"C4BD B7AF A8A0 9EC5 C000 3DFD 7F7F C8CA" /* Ľ.=.. */ + $"CCCC CBCB CAC9 C8C7 C5C4 C2D5 DACD CDCE" /* */ + $"CFD1 D2D4 D5D6 D8D9 D9DA DCDE DFE0 E2E3" /* */ + $"E4E5 E6E6 E8E8 E9EA EBEB E7E1 DAD3 CCC6" /* */ + $"BFB7 B1A9 A298 CACB C6BE 003B 7F8E C8CB" /* ƾ.;. */ + $"CDCD CCCB CACA C8C7 C7C5 C4C1 C0BE D5DD" /* */ + $"D0CF D0D2 D3D5 D6D8 D9D9 DADC DEDF E0E2" /* */ + $"E2E3 E5E6 E6E7 E8E9 EAEB EBE8 E2DC D5CD" /* */ + $"C6C1 B9B1 ABA5 99C0 80CE 02CC C880 BA00" /* .Ȁ. */ + $"01AA CC80 CE36 CDCD CCCC CBCA C8C7 C6C4" /* .̀6 */ + $"C2C0 BEBC BAD5 DFD1 D2D4 D5D7 D8D9 D9DA" /* */ + $"DCDE DFE0 E1E3 E4E5 E6E6 E7E8 E9EA EBEB" /* */ + $"E9E3 DCD6 CFC7 C0BB B3AB A59C BC83 D002" /* . */ + $"CECB ABB6 0002 B8CB CF80 CE36 CDCC CCCB" /* ˫..π6 */ + $"CAC9 C7C6 C4C2 C1BF BCBB B9B7 B5DA E3D4" /* */ + $"D5D6 D8D9 D9DA DCDE DFE0 E2E3 E4E5 E6E6" /* */ + $"E8E8 E9EA EBEB E9E5 DFD7 D0C9 C2BB B5AD" /* » */ + $"A69D AB80 CF80 D081 CF01 CBB8 B200 03C1" /* πЁ.˸.. */ + $"CDD0 D080 CF38 CECC CBCA C9C8 C6C4 C3C1" /* Ѐ8 */ + $"BFBD BBBB B8B7 B5B4 B3D8 EBD6 D8D9 D9DB" /* */ + $"DCDE DFE0 E2E2 E4E5 E6E7 E7E8 E9EA EBEB" /* */ + $"EAE6 E0DA D1CA C4BD B6AF A8A0 9ACF CF86" /* Ľφ */ + $"D003 D1D1 CDC1 AE00 04C7 D0D3 D2D2 80D1" /* ...Ҁ */ + $"37CF CECD CCCB C9C7 C6C4 C2C0 BEBC BAB9" /* 7 */ + $"B7B6 B4B3 B4B4 CBED D9D9 DADC DDDF E0E1" /* */ + $"E3E4 E5E6 E6E7 E8E9 EAEA EBEB E7E0 DAD3" /* */ + $"CBC5 BFB7 AFA9 A29A CC81 D085 D280 D301" /* ſ́ЅҀ. */ + $"D0C7 AA00 01C8 D280 D43E D3D3 D2D1 D0CF" /* Ǫ..Ҁ> */ + $"CECD CBCA C8C5 C3C2 C0BE BCBB B9B8 B6B5" /* */ + $"B4B4 B3B2 B2C9 F0DA DCDE DFE0 E1E2 E4E5" /* */ + $"E6E6 E7E8 E9EA EAEC EBE8 E2DA D3CC C5BF" /* ſ */ + $"B8B0 A9A3 9ACA CFD0 D081 D100 D283 D381" /* Ё.҃Ӂ */ + $"D401 D2C8 A600 01CE D382 D516 D4D3 D3D2" /* .Ȧ..ӂ. */ + $"D1CE CDCB C9C6 C4C2 C0BD BCBB B9B8 B6B5" /* */ + $"B4B4 B582 B428 CBF2 DDDF E0E2 E3E4 E5E6" /* ( */ + $"E6E8 E8E9 EAEB ECEC E8E4 DDD5 CFC8 C1B9" /* */ + $"B3AB A59A B7CD CECF CFD0 D0D1 D1D2 D382" /* ӂ */ + $"D483 D501 D3CE A100 029F CED3 84D4 11D3" /* ԃ.Ρ..ӄ. */ + $"D2D1 D0CF CECB C8C5 C3C0 BCBA B7B7 B5B4" /* */ + $"B382 B101 B2B2 80B1 2AB2 CBF0 E0E1 E3E4" /* .* */ + $"E5E6 E6E7 E8E9 EAEA EBEC EAE3 DED6 CEC8" /* */ + $"C2BB B3AD A69D A7C8 C8C9 CACA CCCD CED0" /* » */ + $"D0D1 D2D2 81D3 84D4 02D3 CE9F 9C00 02B8" /* ҁӄ.Ο.. */ + $"D0D4 85D5 48D4 D4D3 D2D1 CFCD CAC7 C4C1" /* ԅH */ + $"BCBA B7B5 B3B2 B2B1 B0B1 B1B0 B0B1 B0B1" /* */ + $"B1B0 B1B0 D1F2 E3E4 E5E6 E6E7 E8E9 EAEA" /* */ + $"EBEC EAE5 DED7 D0C8 C2BC B4AD A79E A1C1" /* ¼ */ + $"C1C3 C6C6 C7C9 CACC CED0 D1D1 D3D3 80D4" /* Ӏ */ + $"86D5 02D4 D0B8 9800 01C3 D188 D547 D4D3" /* .и..шG */ + $"D2D2 D1CE CBC9 C5C2 BDBA B7B4 B2B0 AFAD" /* ½ */ + $"ADAC ADAD AFAE B0AF AEAE ACB0 977C CFEB" /* | */ + $"E5E6 E6E8 E8E9 EAEA ECEC EBE6 E0D9 D2CB" /* */ + $"C3BD B7AF A8A1 9CBD BABD BDBF C1C3 C4C7" /* ý */ + $"C8CA CDD0 D0D1 80D3 00D4 89D5 01D1 C394" /* р.ԉ.Ô */ + $"0001 C7D1 8AD5 15D4 D3D2 D2D1 CECB C9C5" /* ..ъ. */ + $"C0BD B9B5 B2B0 AEAD ACAB AAAC AB80 AA0F" /* . */ + $"ABAA ABAD A573 7073 C4EC E7E7 E8E9 EAEA" /* sps */ + $"80EC 1FE7 E2DA D3CC C6BE B8B1 A9A3 99B6" /* .ƾ */ + $"B2B3 B5B7 B8BA BCBE C3C4 C7CB CDD0 D1D2" /* */ + $"D3D3 D48B D501 D1C7 9000 02CC D3D7 8CD6" /* ԋ.ǐ..׌ */ + $"14D5 D4D3 D2CF CDCB C7C1 BFBA B7B3 B1AF" /* . */ + $"ADAC ABAB AAAB 80AA 32AB A9AB A174 766F" /* 2tvo */ + $"6D73 C2EF E8E9 EAEA EBEC ECE8 E2DC D4CD" /* ms */ + $"C6C0 B8B1 ABA4 9AAE ABAD AEAE AFB2 B5B8" /* */ + $"BBBE C3C6 C9CC D0D2 D3D4 D4D5 8DD6 01D3" /* Ս. */ + $"CC8C 0003 CDD1 D3D3 8CD5 16D4 D4D3 D2D1" /* ̌..ӌ. */ + $"CFCD CAC7 C3BF BAB8 B3B0 AEAC AAA9 A8A7" /* ÿ */ + $"A6A6 80A5 31A6 A478 7A6F 6F71 6E76 C7F0" /* 1xzooqnv */ + $"EAEA EBEC ECE9 E3DC D6CF C7C1 BAB2 ABA5" /* */ + $"9BA7 A6A3 A5A5 A6A8 A9AA AFB5 B8BD C1C6" /* */ + $"C9CE D0D2 D3D3 D48A D506 D4D4 D3D3 D4D2" /* Ԋ. */ + $"CD89 0005 B3D3 D6D4 D3D3 8BD5 25D4 D4D3" /* ͉..Ӌ% */ + $"D2D1 D0CE CBC9 C5C1 BEBA B6B4 B1AE ABA9" /* */ + $"A7A6 A3A3 A4A4 A1A4 7C7E 7270 7071 726E" /* |~rppqrn */ + $"76C7 F180 EC22 EAE5 DED6 D0C9 C2BB B4AD" /* v"» */ + $"A69F A2A2 9E9D 9C9E A0A0 A1A6 ABAE B4BB" /* */ + $"BFC5 C9CC D0D2 D3D3 D489 D508 D4D3 D1D0" /* ԉ. */ + $"D1D3 D4D1 B388 000A 7893 C1D8 D7D5 D4D4" /* ѳ.x */ + $"D5D7 D787 D615 D5D4 D4D3 D2D1 CFCC C9C6" /* ׇ. */ + $"C2BF BDB9 B6B3 AEAD ABA8 A6A4 80A3 0381" /* ¿. */ + $"8578 7480 722A 7172 6E73 C5F4 EDEA E5DF" /* xtr*qrns */ + $"D8D0 CAC3 BCB5 ADA7 9F9F A09B 9B98 9899" /* ü */ + $"9A9D A0A3 AAAF B4BB C0C5 CACD D1D3 D3D4" /* */ + $"D588 D609 D5D3 D1CF CED0 D3BF 9378 8800" /* Ոӿx. */ + $"0C6B 898B A5D1 D7D6 D3D3 D4D6 D6D7 85D6" /* .kׅ */ + $"4AD5 D5D4 D4D2 D2D1 CECC CAC7 C3C1 BEBA" /* J */ + $"B7B3 B0AC ABA7 A5A5 A387 9084 7B77 7675" /* {wvu */ + $"7473 7272 6E76 C8F2 E6E0 DAD2 CBC4 BEB6" /* tsrrnvľ */ + $"B0A8 A1A9 9097 9594 9394 9597 999C A1A6" /* */ + $"ADB4 BAC0 C5CB CDD2 D2D3 D4D5 86D6 0BD5" /* Ն. */ + $"D4D2 CFCD CCCE CBA3 8B89 6B89 000B 2878" /* ˣk..(x */ + $"898D BBD7 D6D4 D2D2 D4D6 86D5 1FD4 D4D3" /* ֆ. */ + $"D3D1 D1CF CECC CAC7 C3C1 BEBB B7B3 AEAC" /* */ + $"A9A6 A491 8D91 867E 7B79 7775 7480 7326" /* ~{ywuts& */ + $"6F78 C8E6 DBD5 CDC5 C0B9 B0AA A3A6 8D8F" /* ox */ + $"9090 8D8E 8F91 9497 9C9F A6AE B5BB C0C6" /* */ + $"CACF D1D1 D3D3 D484 D50C D4D3 D2CF CDCB" /* Ԅ. */ + $"CCCE B68D 8978 288C 0006 5183 879C CFD8" /* ζx(..Q */ + $"D580 D201 D4D6 85D5 47D4 D3D2 D2D1 D1D0" /* Հ.օG */ + $"CECD CBC8 C6C3 C0BC B9B4 B0AE A99C 8C9B" /* */ + $"928B 8480 7D7A 7876 7574 7373 6F77 C4D9" /* }zxvutssow */ + $"CEC7 BFB9 B2AA A4A5 8A8A 898A 8889 8A8D" /* ǿ */ + $"9095 9B9E A3AB B0B7 BDC3 C8CC CFD1 D2D3" /* */ + $"D484 D50B D4D3 D0CE CCCB CDC7 9B87 8351" /* Ԅ.ǛQ */ + $"8F00 0D16 6F86 89B4 D6D6 D3D1 D1D4 D5D6" /* ...o */ + $"D684 D545 D3D3 D2D2 D1D0 D0CE CCCA C7C4" /* քE */ + $"C1BE BAB5 B2AE 8AA5 9B98 918A 8580 7D7B" /* }{ */ + $"7977 7574 7372 6F8D CFC9 C1BA B3AC A5A2" /* ywutsro */ + $"9886 8586 8788 898B 8E92 989F A3AB B0B7" /* */ + $"BCC2 C6CA CED0 D1D2 D3D4 82D5 0CD4 D3D1" /* Ԃ. */ + $"CFCC CBCC CDAF 8986 6F16 9200 0C44 7E84" /* ͯo...D~ */ + $"95CA DAD7 D5D2 D3D5 D8D7 84D6 43D5 D4D4" /* ׄC */ + $"D3D2 D2D1 D1CF CCCA C6C3 C2BD B7A8 A29F" /* ½ */ + $"A09E 988F 8984 817E 7B79 7774 7373 7472" /* ~{ywtsstr */ + $"ABC7 BCB5 AEA7 A0AA 7D82 8384 8988 8C8F" /* Ǽ} */ + $"9499 9EA5 ADB2 B8BD C3C6 CACF D1D2 D3D3" /* */ + $"D582 D60B D5D3 D1CF CDCD CEC3 9484 7E44" /* Ղ.Ô~D */ + $"9500 0D0E 6682 85AF D8D9 D6D2 D2D3 D6D7" /* ...f */ + $"D784 D640 D4D4 D3D3 D2D2 D0CF CDCA C9C5" /* ׄ@ */ + $"C3BF 99A8 A3A7 A69F 958E 8985 827E 7A77" /* ÿ~zw */ + $"7473 7475 6E84 BEB7 AEA8 A2A6 777E 7F81" /* tstunw~. */ + $"8288 898D 9399 A1A7 ADB2 B9BE C3C7 CBCF" /* */ + $"D0D2 D2D3 D581 D60C D5D4 D2D0 CDCC CDCD" /* Ձ. */ + $"AA85 8266 0E98 000C 3978 818E C7DB D8D4" /* f...9x */ + $"D1D2 D4D6 D785 D619 D4D4 D3D3 D2D1 D0CF" /* ׅ. */ + $"CDC9 C6C2 A3A5 AAB0 AEA8 9E96 8F8A 8682" /* £ */ + $"7D79 8076 2074 6F6E AAB2 A8A3 A571 797A" /* }yv tonqyz */ + $"7C7F 8489 8E95 9BA2 A7B0 B4B9 BEC4 C8CB" /* |. */ + $"CFD0 D1D2 D3D5 81D6 0BD5 D3D1 CECD CDCF" /* Ձ. */ + $"BE8D 8178 399B 000C 0860 7F81 A8D8 DBD6" /* x9...`. */ + $"D2D1 D2D4 D785 D63B D5D4 D4D3 D3D2 D0D0" /* ׅ; */ + $"CEC9 C0AD ABB1 B6B6 B1A7 9E95 8F89 857F" /* . */ + $"7B7A 7876 736D 6999 AFA3 A581 7676 7A7D" /* {zxvsmivvz} */ + $"8388 8E96 9AA2 A9B1 B7BC C2C4 C9CD CFD1" /* */ + $"D1D3 D3D5 80D6 0CD5 D4D2 CFCD CCCE CCA4" /* Հ.̤ */ + $"817F 6008 9E00 0D2D 7480 8BC1 DCD9 D4D1" /* .`...-t */ + $"D1D3 D6D7 D784 D600 D480 D343 D2D1 CFCB" /* ׄ.ԀC */ + $"BFA9 B2B7 BDBE BBB2 A89E 958F 8883 807E" /* ~ */ + $"7A76 706B 648B A9A2 906D 7277 7C80 878C" /* zvpkdmrw| */ + $"949B A4AC B3B9 BEC2 C7CA CDCF D1D2 D3D3" /* */ + $"D5D6 D6D5 D4D3 D1CE CCCD CFB9 8980 742D" /* Ϲt- */ + $"A200 0C58 7E80 A1D6 DDD9 D4D1 D2D5 D8D8" /* ..X~ */ + $"84D7 00D6 80D4 2ED3 D1CD C2AC B9BE C3C8" /* .ր.¬ */ + $"C6C0 B6AA 9E95 8E89 8682 7C74 6F6A 6387" /* |tojc */ + $"A69B 6670 747B 8086 8E98 9FA6 AFB4 BCC1" /* fpt{ */ + $"C5C9 CDD0 D2D2 80D4 0ED6 D7D7 D6D5 D3D0" /* Ҁ. */ + $"CECE CFCB 9D80 7E58 A500 0C24 6E7F 86BE" /* ˝~X..$n. */ + $"DEDA D6D1 D0D2 D5D7 84D6 42D5 D4D2 D2D1" /* ׄB */ + $"CDC8 BBBD C4CA CFD1 CCC3 B6A7 9C95 908B" /* Ȼö */ + $"847C 746F 6A65 8FA7 616B 7079 8086 8E98" /* |tojeakpy */ + $"A1A8 AFB5 BDC0 C5CA CCCF D1D1 D3D3 D4D6" /* */ + $"D6D5 D4D3 D0CE CCCD CFB4 867F 6E24 A800" /* ϴ.n$. */ + $"0A4D 7A7D 9AD4 DDD8 D3CF D0D3 80D7 81D6" /* Mz}Ӏׁ */ + $"40D5 D4D2 D1D0 CBC6 C1C2 CAD1 D6D9 D8D0" /* @ */ + $"C3B3 A89F 978F 857B 746F 6868 A067 696E" /* ó{tohhgin */ + $"7983 8892 9BA2 AAB0 B9BF C2C8 CACE CFD1" /* y */ + $"D2D3 D3D4 D6D6 D5D4 D1CF CDCD CEC6 977D" /* Ɨ} */ + $"7A4D AB00 501A 697D 81B7 E0DB D7D1 D0D2" /* zM.P.i} */ + $"D6D8 D7D8 D7D6 D5D5 D4D1 CFCB C5C1 C9D0" /* */ + $"D8DE E1E2 DDD1 C3B7 AD9F 9186 7B74 6E65" /* ÷{tne */ + $"8074 6870 7984 8C94 9EA5 AFB5 BDC1 C5CA" /* thpy */ + $"CDCF D2D2 D4D4 D6D6 D7D6 D5D4 D1CF CECF" /* */ + $"D1AE 807D 691A AE00 4C46 767C 93D2 E0DA" /* Ѯ}i..LFv| */ + $"D5D2 D0D3 D7D9 D9D7 D5D4 D4D0 CEC8 C1B9" /* */ + $"D0D7 DEE4 E7E7 E3DB D1C6 B8A5 9588 7C74" /* Ƹ|t */ + $"6D6B 7A66 7079 858E 97A0 AAB2 B8BD C2C7" /* mkzfpy */ + $"CACE D0D2 D3D4 D4D6 D7D7 D6D4 D2D0 CECE" /* */ + $"D0C6 907C 7646 B100 4A0E 627B 7DB0 E1DF" /* Ɛ|vF.J.b{} */ + $"DAD3 D1D3 D6D9 D8D7 D5D4 D0CE C8C0 B6A6" /* */ + $"DFE5 E8EB E9E7 E3DC D1C0 AB99 8C7F 756D" /* .um */ + $"7D64 707D 8791 9AA5 AEB6 BAC1 C6CA CDD0" /* }dp} */ + $"D3D3 D5D5 D7D7 D8D7 D6D4 D2D0 CFD0 D0A8" /* Ш */ + $"7D7B 620E B400 4639 727A 8CCF E3DE D9D3" /* }{b..F9rz */ + $"D2D4 D6D7 D7D6 D1CD C8BF B6AA 9AF8 ECEB" /* ȿ */ + $"EBEA E7E1 D4C3 AF9E 9080 7776 6372 7F8A" /* ïwvcr. */ + $"95A1 AAB1 B9C0 C4C9 CED0 D3D3 D5D6 D6D8" /* */ + $"D9D8 D8D6 D4D2 D0D1 D3C1 8A7A 7239 B700" /* zr9. */ + $"4408 5A79 79A9 E0E3 DED7 D4D3 D4D6 D4D3" /* D.Zyy */ + $"CEC8 C0B7 A99E 91FA F0EC ECE9 DDD1 C1AF" /* */ + $"A092 857B 6077 848E 9AA3 ADB7 BCC2 C7CC" /* {`w */ + $"CFD3 D4D6 D6D7 D8D9 DAD9 D8D6 D4D2 D1D3" /* */ + $"D0A2 7979 5A08 BA00 402F 6F79 87C9 E8E1" /* ТyyZ..@/oy */ + $"DCD5 D4D3 D3D2 CFCB C3B7 AD9F 9495 CCF9" /* ÷ */ + $"F2E6 D8C9 BDAE A495 6E68 7D89 939D A7B2" /* ɽnh} */ + $"B8BF C7CA CED2 D5D5 D7D8 D8DA DBDA DAD8" /* */ + $"D6D4 D3D3 D5BD 8579 6F2F BE00 3C54 7678" /* սyo/.K */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"F79E 4B3E 2E1E 1108 0401 0000 0000 0000" /* K>............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0102" /* ................ */ + $"050C 1625 3544 65CE FFFF FFFF FFFF FFFF" /* ...%5De */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFCE" /* */ + $"6544 3525 160C 0502 0100 0000 0000 0000" /* eD5%............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0103 0810 1D2C 3C4A 92F3 FFFF FFFF FFFF" /* .....,L */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFFF FAA2 4B3E 2F1F 1209 0401 0000 0000" /* K>/........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0102 050C" /* ................ */ + $"1725 3546 66D1 FFFF FFFF FFFF FFFF FFFF" /* .%5Ff */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"FFD1 6545 3525 170C 0502 0100 0000 0000" /* eE5%.......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0103" /* ................ */ + $"0810 1D2D 3D4A 92F6 FFFF FFFF FFFF FFFF" /* ...-=J */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFF6" /* */ + $"924A 3D2D 1D10 0803 0100 0000 0000 0000" /* J=-............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0205 0B16 2434 435F C5FF FFFF FFFF FFFF" /* ....$4C_ */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF C55F" /* _ */ + $"4334 2416 0B05 0200 0000 0000 0000 0000" /* C4$............. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0001 0307 0F1B 2B3B 4988 EEFF FFFF FFFF" /* ......+;I */ + $"FFFF FFFF FFFF FFFF FFFF FFFF EE88 493B" /* I; */ + $"2B1B 0F07 0301 0000 0000 0000 0000 0000" /* +............... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0001 040A 1422 3241 58BB FFFF FFFF" /* ......"2AX */ + $"FFFF FFFF FFFF FFFF FFFF FFBB 5841 3222" /* XA2" */ + $"140A 0401 0000 0000 0000 0000 0000 0000" /* ............... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0103 060E 1A29 3947 7EE7 FFFF" /* .........)9G~ */ + $"FFFF FFFF FFFF FFFF FFE7 7E47 3929 1A0E" /* ~G9).. */ + $"0603 0100 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0104 0913 2031 4052 AEFC" /* ......... 1@R */ + $"FFFF FFFF FFFF FFFC AE52 4031 2013 0904" /* R@1 .. */ + $"0100 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0001 0306 0D19 2838 4670" /* ............(8Fp */ + $"E1FF FFFF FFFF E170 4638 2819 0D06 0301" /* pF8(..... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0001 0409 121F 2F3E" /* ............./> */ + $"4FA2 FAFF FAA2 4F3E 2F1F 1209 0401 0000" /* OO>/...... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0102 060C 1726" /* ...............& */ + $"3645 69D3 6945 3626 170C 0602 0100 0000" /* 6EiiE6&........ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0103 0811" /* ................ */ + $"1E2D 3A40 3A2D 1E11 0803 0100 0000 0000" /* .-:@:-.......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0205" /* ................ */ + $"0C15 2026 2015 0C05 0200 0000 0000 0000" /* .. & ........... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0001" /* ................ */ + $"0307 0C0F 0C07 0301 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0001 0304 0301 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 00" /* ... */ +}; + +data 'plst' (0) { + $"3C3F 786D 6C20 7665 7273 696F 6E3D 2231" /* ....CFBund */ + $"6C65 4465 7665 6C6F 706D 656E 7452 6567" /* leDevelopmentReg */ + $"696F 6E3C 2F6B 6579 3E0D 093C 7374 7269" /* ion.English.CFBund */ + $"6C65 4963 6F6E 4669 6C65 3C2F 6B65 793E" /* leIconFile */ + $"0D09 3C73 7472 696E 673E 3135 303C 2F73" /* .150.CFB */ + $"756E 646C 6549 6E66 6F44 6963 7469 6F6E" /* undleInfoDiction */ + $"6172 7956 6572 7369 6F6E 3C2F 6B65 793E" /* aryVersion */ + $"0D09 3C73 7472 696E 673E 362E 303C 2F73" /* .6.0.CFB */ + $"756E 646C 6550 6163 6B61 6765 5479 7065" /* undlePackageType */ + $"3C2F 6B65 793E 0D09 3C73 7472 696E 673E" /* . */ + $"4150 504C 3C2F 7374 7269 6E67 3E0D 093C" /* APPL.< */ + $"6B65 793E 4346 4275 6E64 6C65 5369 676E" /* key>CFBundleSign */ + $"6174 7572 653C 2F6B 6579 3E0D 093C 7374" /* ature.aplt.LSPrefe */ + $"7273 4361 7262 6F6E 3C2F 6B65 793E 0D09" /* rsCarbon. */ + $"3C74 7275 652F 3E0D 3C2F 6469 6374 3E0D" /* .. */ + $"3C2F 706C 6973 743E 0D" /* . */ +}; + +data 'scpt' (128) { + $"4661 7364 5541 5320 312E 3130 312E 3130" /* FasdUAS 1.101.10 */ + $"0E00 0000 040F FFFF 0001 0002 0003 01FF" /* ............. */ + $"FF00 000D 0001 0002 6C00 0100 0000 00FF" /* .......l...... */ + $"FE00 0401 FFFE 0000 0C00 0400 2000 1A20" /* ......... .. */ + $"4E75 6C6C 2053 6372 6970 742C 206E 6565" /* Null Script, nee */ + $"6420 7468 6520 6170 7000 0200 000E 0002" /* d the app....... */ + $"0000 0F10 0003 0002 FFFD 0005 01FF FD00" /* ............ */ + $"0010 0005 0000 6173 6372 0001 000C FADE" /* ......ascr.... */ + $"DEAD" /* ޭ */ +}; + +data 'spsh' (0) { + $"0000" /* .. */ +}; + +data 'CODE' (0, purgeable) { + $"0000 0028 0000 0000 0000 0008 0000 0020" /* ...(........... */ + $"0064 3F3C 0001 A9F0" /* .d?<.. */ +}; + +data 'CODE' (1, locked, preload) { + $"0000 0001 4E56 FFF8 2F03 7600 2F03 303C" /* ....NV/.v./.0< */ + $"A1AD A746 261F 2D48 FFF8 2F03 303C A89F" /* F&.-H/.0< */ + $"A746 261F 202E FFF8 B1C0 6720 2F03 203C" /* F&. .g /. < */ + $"6370 6E74 41EE FFFC 2248 A1AD 2288 261F" /* cpntA"H"&. */ + $"4A40 6608 4AAE FFFC 6702 7601 1003 262E" /* J@f.Jg.v...&. */ + $"FFF4 4E5E 4E75 8F47 6F74 436F 6D70 6F6E" /* N^NuGotCompon */ + $"656E 744D 6772 0000 4E56 0000 2F0C 4EBA" /* entMgr..NV../.N */ + $"FF94 4A00 672A 598F 2F3C 6170 6C74 2F3C" /* J.g*Y/ So, is there a better way, in RPM 3, to populate %files? +> Because I know +> 'buildroot' and it has nothing to do with %files. + +I found this bit of code in a .spec file to build a %files list on the fly +and have been using it ever since. I've always thought RPM should be able +to provide a default %files list in the event one isn't present in the .spec +file. + +-- +John Ross Hunt +bigboote@mediaone.net + + + +%define pkg_name foo + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT + +cd $RPM_BUILD_ROOT +find . -type d | sed '1,2d;s,^\.,\%attr(-\,root\,root) \%dir ,' > \ + $RPM_BUILD_DIR/file.list.%{pkg_name} + +find . -type f | sed -e 's,^\.,\%attr(-\,root\,root) ,' \ + -e '/\/etc\//s|^|%config|' >> \ + $RPM_BUILD_DIR/file.list.%{pkg_name} + +find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> \ + $RPM_BUILD_DIR/file.list.%{pkg_name} + +%clean +rm -rf $RPM_BUILD_ROOT $RPM_BUILD_DIR/file.list.%{pkg_name} + +%files -f ../file.list.%{pkg_name} +%doc README TODO example +----------------------------------------------------------------- diff --git a/bochs/build/redhat/bochs.rpmspec.template b/bochs/build/redhat/bochs.rpmspec.template new file mode 100644 index 00000000..f48ec8d7 --- /dev/null +++ b/bochs/build/redhat/bochs.rpmspec.template @@ -0,0 +1,81 @@ +Summary: Bochs Project x86 PC Emulator +Name: bochs +Version: @SEDVERSION@ +Release: 1 +License: LGPL +Group: Applications/Emulators +URL:http://bochs.sourceforge.net +Packager:Volker Ruppert +Source:bochs-@SEDVERSION@.tar.gz +BuildRoot: /var/tmp/%{name}-buildroot + +%description +Bochs is a highly portable open source IA-32 (x86) PC emulator written +in C++, that runs on most popular platforms. It includes emulation of +the Intel x86 CPU, common I/O devices, and a custom BIOS. Currently, +Bochs can be compiled to emulate a 386, 486, Pentium, Pentium Pro or +AMD64 CPU, including optional MMX, SSEx and 3DNow! instructions. +Bochs is capable of running most Operating Systems inside the emulation +including Linux, DOS, Windows 9X/NT/2000/XP or Windows 7. + +%define pkg_name bochs + +%prep + rm -rf $RPM_BUILD_DIR/bochs-@SEDVERSION@ + tar xzvf $RPM_SOURCE_DIR/bochs-@SEDVERSION@.tar.gz + if test "/" != $RPM_BUILD_ROOT; then + rm -rf $RPM_BUILD_ROOT + fi +%build + cd $RPM_BUILD_DIR/bochs-@SEDVERSION@ + CONFIGURE_ARGS="--prefix=/usr --mandir=$RPM_BUILD_ROOT/%{_mandir}" + export CONFIGURE_ARGS + sh .conf.linux + make + make unpack_dlx # must use prefix=/usr since this step sets up + # the paths in dlx bochsrc file. +%install + pwd + cd $RPM_BUILD_DIR/bochs-@SEDVERSION@ + for i in "" usr usr/bin usr/lib usr/share usr/share/doc %{_mandir}; do + if ! test -d $RPM_BUILD_ROOT/$i; then mkdir $RPM_BUILD_ROOT/$i; fi + done + make install install_dlx prefix=$RPM_BUILD_ROOT/usr + # Build list of plugins on the fly (if any). This allows the + # spec file to support RPM building with or without plugins. + cd $RPM_BUILD_ROOT + find ./usr/lib -type d | sed '1,2d;s,^\.,\%attr(-\,root\,root) \%dir ,' > \ + $RPM_BUILD_DIR/file.list.%{pkg_name} + find ./usr/lib -type f | sed -e 's,^\.,\%attr(-\,root\,root) ,' \ + -e '/\/etc\//s|^|%config|' >> \ + $RPM_BUILD_DIR/file.list.%{pkg_name} + find ./usr/lib -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> \ + $RPM_BUILD_DIR/file.list.%{pkg_name} + # We could use the same technique to produce the complete file list, + # with only one very minor problem: it lists directories that are + # used by other programs, so when you remove the package you get + # errors like + # error: cannot remove /usr/share/doc - directory not empty + +%files -f file.list.%{pkg_name} +%defattr(-, root, root) + /usr/bin/bochs + /usr/bin/bochs-dlx + /usr/bin/bxcommit + /usr/bin/bximage + /usr/share/bochs/* + /usr/share/doc/* + %{_mandir}/* + +%clean + rm -rf $RPM_BUILD_DIR/bochs-@SEDVERSION@ + rm -rf $RPM_BUILD_DIR/file.list.%{pkg_name} + if test "/" != $RPM_BUILD_ROOT; then + rm -rf $RPM_BUILD_ROOT + fi +%preun + # clean up the bochsout.txt that is always produced if you + # run bochs-dlx. + rm -rf /usr/share/bochs/dlxlinux/bochsout.txt +%postun + rmdir /usr/share/bochs > /dev/null 2>&1 diff --git a/bochs/build/redhat/make-rpm b/bochs/build/redhat/make-rpm new file mode 100755 index 00000000..d281be7b --- /dev/null +++ b/bochs/build/redhat/make-rpm @@ -0,0 +1,100 @@ +#!/bin/bash -x +######################################################################### +# $Id$ +######################################################################### +# build/redhat/make-rpm +# +# This script creates an RPM from the bochs directory. You must run +# it as root from the top of the source directory (where the configure +# scripts are). Then just run: +# ./build/redhat/make-rpm +# +######################################################################### + +CAT=cat +RM=rm +CP=cp +MV=mv +MKDIR=mkdir +GREP=grep +ECHO=echo +RPM=rpm +RPMBUILD=/usr/bin/rpmbuild +SED=sed +TAR=tar +RPMSRCPATH=_rpm_top +SOURCES=${RPMSRCPATH}/SOURCES +SPECS=${RPMSRCPATH}/SPECS +RPMSPEC="build/redhat/bochs.rpmspec.template" +TMPDIR=/tmp + +echo Reading version from configure.in script. +VERSION='unknown' +eval `${GREP} '^VERSION="' configure.in` +if test $? != 0 -o "$VERSION" = unknown; then + echo Could not get version number from configure.in script. + echo Exiting. + exit 1 +fi + +# clean up previous rpm builds +${RM} -rf *.rpm ${RPMSRCPATH} +if test -f Makefile; then + make dist-clean +fi + +# make a TAR.GZ of the entire source directory, exactly as it is. The +# tar is placed in $SOURCES/bochs-$VERSION.tar.gz. Because the current +# directory could be named nearly anything, I copy all the contents into +# $SOURCES/bochs-$VERSION and then build a tar in $SOURCES. + +${RM} -rf ${TMPDIR}/bochs-${VERSION} +test $? = 0 || exit 1 +${MKDIR} ${TMPDIR}/bochs-${VERSION} +test $? = 0 || exit 1 +${TAR} cf - * .??* | (cd ${TMPDIR}/bochs-${VERSION} && tar xf -) +test $? = 0 || exit 1 +(cd ${TMPDIR}; tar czf bochs-${VERSION}.tar.gz --exclude=CVS bochs-${VERSION}) +test $? = 0 || exit 1 +${RM} -rf ${TMPDIR}/bochs-${VERSION} +test $? = 0 || exit 1 + +# create RPM build area +rm -rf ${RPMSRCPATH} +mkdir ${RPMSRCPATH} ${RPMSRCPATH}/SOURCES ${RPMSRCPATH}/SPECS ${RPMSRCPATH}/BUILD ${RPMSRCPATH}/RPMS ${RPMSRCPATH}/SRPMS +test $? = 0 || exit 1 # test that mkdir succeeded + +# copy source into sources +${MV} ${TMPDIR}/bochs-${VERSION}.tar.gz ${SOURCES} +test $? = 0 || exit 1 + +# copy the spec into SPECS. The template is in $RPMSPEC, and we use +# SED to substitute in the version number. +${RM} -f ${SPECS}/bochs.spec +test $? = 0 || exit 1 +${CAT} ${RPMSPEC} | ${SED} "s/@SEDVERSION@/${VERSION}/g" > ${SPECS}/bochs.spec +test $? = 0 || exit 1 + +# finally, start the rpm build. +if [ -x ${RPMBUILD} ] +then + ${RPMBUILD} -ba --define "_topdir `pwd`/${RPMSRCPATH}" ${SPECS}/bochs.spec +else + ${RPM} -ba --define "_topdir `pwd`/${RPMSRCPATH}" ${SPECS}/bochs.spec +fi + +# test status +if test $? = 0; then + echo RPM build succeeded +else + echo RPM build failed. + exit 1 +fi + +# copy all rpms out into main directory +ALLRPMS=`find ${RPMSRCPATH} -name '*.rpm'` +if test "$ALLRPMS" != ""; then + echo Moving .rpm files into the main directory. + mv ${ALLRPMS} . + ls -l *.rpm +fi diff --git a/bochs/build/win32/README.win32-binary b/bochs/build/win32/README.win32-binary new file mode 100644 index 00000000..e69de29b diff --git a/bochs/build/win32/bochs.win32.manifest b/bochs/build/win32/bochs.win32.manifest new file mode 100755 index 00000000..c0a09c97 --- /dev/null +++ b/bochs/build/win32/bochs.win32.manifest @@ -0,0 +1,22 @@ + + + +Quartus + + + + + + diff --git a/bochs/build/win32/bochs.win64.manifest b/bochs/build/win32/bochs.win64.manifest new file mode 100755 index 00000000..58fb3e66 --- /dev/null +++ b/bochs/build/win32/bochs.win64.manifest @@ -0,0 +1,22 @@ + + + +Quartus + + + + + + diff --git a/bochs/build/win32/cc2cpp b/bochs/build/win32/cc2cpp new file mode 100755 index 00000000..8cc1fa22 --- /dev/null +++ b/bochs/build/win32/cc2cpp @@ -0,0 +1,6 @@ +#!/bin/sh + +list=`find . -name '*.cc' | sed 's/\.cc$//'` +for i in $list; do + mv ${i}.cc ${i}.cpp +done diff --git a/bochs/build/win32/cpp2cc b/bochs/build/win32/cpp2cc new file mode 100755 index 00000000..f63e7ea9 --- /dev/null +++ b/bochs/build/win32/cpp2cc @@ -0,0 +1,6 @@ +#!/bin/sh + +list=`find . -name '*.cpp' | sed 's/\.cpp$//'` +for i in $list; do + mv ${i}.cpp ${i}.cc +done diff --git a/bochs/build/win32/diffcc2cpp b/bochs/build/win32/diffcc2cpp new file mode 100755 index 00000000..165ab40f --- /dev/null +++ b/bochs/build/win32/diffcc2cpp @@ -0,0 +1,6 @@ +#!/bin/sh + +list=`find . -name '*.cpp' | sed 's/\.cpp$//'` +for i in $list; do + diff -u ${i}.cc ${i}.cpp +done diff --git a/bochs/build/win32/nsis/Makefile.in b/bochs/build/win32/nsis/Makefile.in new file mode 100644 index 00000000..efa3404d --- /dev/null +++ b/bochs/build/win32/nsis/Makefile.in @@ -0,0 +1,30 @@ +# To build an NSIS installer, get NSIS version 2.0a7 from +# http://sourceforge.net/projects/nsis +# Fix the MAKENSIS variable so that you have the correct path. +# Unzip the windows binary release into a subdirectory of this +# directory, for example "2.0.pre2". Make sure the VERSION +# variable has the same name as the directory, and in bochs.nsi +# the VER_MAJOR, VER_MINOR, and VER_REV values should also match. +# +# Type make, and it should build an installer called Bochs-${VERSION}.exe + +MAKENSIS='c:/Program Files/NSIS/makensis' + +VERSION=@VERSION@ +TARGET=Bochs-${VERSION}.exe +DLXDIR=bochs-${VERSION}/dlxlinux + +all: ${TARGET} + +fixups:: + if test -f ${DLXDIR}/bochsrc.txt; then mv ${DLXDIR}/bochsrc.txt ${DLXDIR}/bochsrc.bxrc; fi + rm -f ${DLXDIR}/*.bat + +${TARGET}: fixups bochs.nsi + rm -rf ${TARGET} + ${MAKENSIS} bochs.nsi + test -f ${TARGET} + ls -l ${TARGET} + +clean:: + rm -rf ${TARGET} diff --git a/bochs/build/win32/nsis/bochs.ico b/bochs/build/win32/nsis/bochs.ico new file mode 100644 index 00000000..53b9b548 Binary files /dev/null and b/bochs/build/win32/nsis/bochs.ico differ diff --git a/bochs/build/win32/nsis/bochs.nsi.in b/bochs/build/win32/nsis/bochs.nsi.in new file mode 100644 index 00000000..da534137 --- /dev/null +++ b/bochs/build/win32/nsis/bochs.nsi.in @@ -0,0 +1,290 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; $Id$ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Setup Script for NSIS Installer +; +; Created: Michael Rich (istan) +; +; Based on Example Script by Joost Verburg +; also original BOCHS script by Robert (segra) +; updated for NSIS 2.44 by Volker Ruppert +; +;--------------------- +;Include Modern UI + + !include "MUI.nsh" + +;-------------------------------- + +!define VERSION @VERSION@ +!define NAME "Bochs ${VERSION}" + + +!define CURRENTPAGE $9 + +!define TEMP1 $R0 +!define TEMP2 $R1 + +!define SRCDIR bochs-${VERSION} +!define PGDIR "$SMPROGRAMS\Bochs ${VERSION}" +!define DESKTOP_DLXLINK "$DESKTOP\Linux Demo in ${NAME}.lnk" +!define DESKTOP_DLX_PIF "$DESKTOP\Linux Demo in ${NAME}.pif" + +;-------------------------------- + +;General + Name "${NAME}" + OutFile Bochs-${VERSION}.exe + SetOverwrite on + + ; Installation Types + InstType "Normal" + InstType "Full (with DLX Linux demo)" + + ;Folder-select dialog + InstallDir $PROGRAMFILES\Bochs-${VERSION} + InstallDirRegKey HKLM "Software\${NAME}" "" + + ;Request application privileges for Windows Vista + RequestExecutionLevel admin + +;-------------------------------- +;Interface Settings + + !define MUI_ABORTWARNING + !define MUI_COMPONENTSPAGE_NODESC + !define MUI_ICON "bochs.ico" + !define MUI_UNICON "unbochs.ico" + +;-------------------------------- +;Pages + + !insertmacro MUI_PAGE_LICENSE ${SRCDIR}\COPYING.txt + !insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + !insertmacro MUI_PAGE_INSTFILES + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Installer Sections + +Section "Bochs Program (required)" SecCore + SectionIn 1 2 RO + + SetOutPath "$INSTDIR" + + File "${SRCDIR}\*.exe" + File "${SRCDIR}\*.txt" + File "*.ico" + + ; Install keymaps + SetOutPath "$INSTDIR\keymaps" + File "${SRCDIR}\keymaps\*" + +SectionEnd + +Section "ROM Images (required)" SecROMs + SectionIn 1 2 RO + + SetOutPath "$INSTDIR" + + File "${SRCDIR}\BIOS-bochs-*" + File "${SRCDIR}\VGABIOS-*" +SectionEnd + +Section "Documentation in HTML" SecDocs + SectionIn 1 2 + SetOutPath "$INSTDIR\docs" + File "${SRCDIR}\share\doc\bochs\index.html" + SetOutPath "$INSTDIR\docs\user" + File "${SRCDIR}\share\doc\bochs\user\*" + SetOutPath "$INSTDIR\docs\development" + File "${SRCDIR}\share\doc\bochs\development\*" + SetOutPath "$INSTDIR\docs\documentation" + File "${SRCDIR}\share\doc\bochs\documentation\*" + SetOutPath "$INSTDIR\docs\images" + File "${SRCDIR}\share\doc\bochs\images\*" +SectionEnd + +Section "DLX Linux Demo" SecDLX + SectionIn 2 + + SetOutPath "$INSTDIR\dlxlinux" + File "${SRCDIR}\dlxlinux\*" + + ; Fix up the path to the Bochs executable + FileOpen $1 "$INSTDIR\dlxlinux\run.bat" w + FileWrite $1 'cd "$INSTDIR\dlxlinux"$\r$\n' + FileWrite $1 "..\bochs -q -f bochsrc.bxrc$\r$\n" + FileClose $1 +SectionEnd + +Section "Add Bochs to the Start Menu and Desktop" SecIcons + SectionIn 1 2 + + ; Set the Program Group as output to ensure it exists + SetOutPath "${PGDIR}" + + ; Change the output back to the install folder so the "Start In" paths get set properly + SetOutPath "$INSTDIR" + + CreateShortCut "${PGDIR}\${NAME}.lnk" "$INSTDIR\Bochs.exe" "" "$INSTDIR\bochs.ico" "0" + + CreateShortCut "${PGDIR}\Readme.lnk" \ + "$INSTDIR\Readme.txt" + + CreateShortCut "${PGDIR}\Bochs Sample Setup.lnk" \ + "$INSTDIR\bochsrc-sample.txt" + + CreateShortCut "${PGDIR}\Disk Image Creation Tool.lnk" \ + "$INSTDIR\bximage.exe" + + CreateShortCut "${PGDIR}\NIC Lister.lnk" \ + "$INSTDIR\niclist.exe" + + WriteINIStr "${PGDIR}\Help.url" \ + "InternetShortcut" "URL" "file://$INSTDIR/docs/index.html" + + WriteINIStr "${PGDIR}\Home Page.url" \ + "InternetShortcut" "URL" "http://bochs.sourceforge.net/" + + CreateShortCut "${PGDIR}\${NAME} Folder.lnk" \ + "$INSTDIR" + + CreateShortCut "${PGDIR}\Uninstall Bochs.lnk" \ + "$INSTDIR\Uninstall.exe" "" "$INSTDIR\unbochs.ico" "0" + + ; Create shortcut to DLX Linux if it was installed + IfFileExists "$INSTDIR\dlxlinux\*" 0 no + CreateShortCut "${PGDIR}\DLX Linux.lnk" "$INSTDIR\dlxlinux\run.bat" "" "$INSTDIR\penguin.ico" "0" + + ; Add a link to the DLX demo to the desktop + CreateShortCut "${DESKTOP_DLXLINK}" "$INSTDIR\dlxlinux\run.bat" "" "$INSTDIR\bochs.ico" "0" +no: + + +SectionEnd + +Section "Register .bxrc Extension" SecExtension + SectionIn 1 2 RO + + ; back up old value of .bxrc + ReadRegStr $1 HKCR ".bxrc" "" + + StrCmp $1 "" Label1 + StrCmp $1 "BochsConfigFile" Label1 + WriteRegStr HKCR ".bxrc" "backup_val" $1 + + Label1: + WriteRegStr HKCR ".bxrc" "" "BochsConfigFile" + WriteRegStr HKCR "BochsConfigFile" "" "${NAME} Config File" + WriteRegStr HKCR "BochsConfigFile\DefaultIcon" "" "$INSTDIR\bochs.ico,0" + WriteRegStr HKCR "BochsConfigFile\shell" "" "Configure" + WriteRegStr HKCR "BochsConfigFile\shell\Configure\command" "" '"$INSTDIR\Bochs.exe" -f "%1"' + WriteRegStr HKCR "BochsConfigFile\shell" "" "Edit" + WriteRegStr HKCR "BochsConfigFile\shell\Edit\command" "" '$WINDIR\NOTEPAD.EXE "%1"' + WriteRegStr HKCR "BochsConfigFile\shell" "" "Debugger" + WriteRegStr HKCR "BochsConfigFile\shell\Debugger\command" "" '"$INSTDIR\Bochsdbg.exe" -f "%1"' + WriteRegStr HKCR "BochsConfigFile\shell" "" "Run" + WriteRegStr HKCR "BochsConfigFile\shell\Run\command" "" '"$INSTDIR\Bochs.exe" -q -f "%1"' +SectionEnd + + +Section -post + ; Register Uninstaller + WriteRegStr HKLM "SOFTWARE\${NAME}" "" $INSTDIR + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "DisplayName" "${NAME} (remove only)" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "DisplayIcon" "$INSTDIR\bochs.ico,0" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "DisplayVersion" "${VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "Publisher" "The Bochs Project" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "URLInfoAbout" "http://bochs.sourceforge.net" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "Readme" '$INSTDIR\Readme.txt' + WriteRegDWord HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoModify" "1" + WriteRegDWord HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "NoRepair" "1" + WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "InstallLocation" '$INSTDIR\' + WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"' + + ; Write the uninstaller + WriteUninstaller "$INSTDIR\Uninstall.exe" +SectionEnd + +;-------------------------------- +;Installer Functions + +Function .onInstSuccess + MessageBox MB_YESNO|MB_ICONQUESTION \ + "Would you like to see a list of changes?" \ + IDNO NoChanges + ExecWait 'notepad.exe $INSTDIR\CHANGES.TXT' + NoChanges: + MessageBox MB_YESNO|MB_ICONQUESTION \ + "Setup has completed. Show README now?" \ + IDNO NoReadme + ExecWait 'notepad.exe $INSTDIR\README.txt' + + NoReadme: + MessageBox MB_OK "Thank you for installing Bochs, think inside the bochs." +FunctionEnd + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + + ReadRegStr $1 HKCR ".bxrc" "" + + StrCmp $1 "BochsConfigFile" 0 NoOwn ; only do this if we own it + ReadRegStr $1 HKCR ".bxrc" "backup_val" + StrCmp $1 "" 0 RestoreBackup ; if backup == "" then delete the whole key + DeleteRegKey HKCR ".bxrc" + Goto NoOwn + RestoreBackup: + WriteRegStr HKCR ".bxrc" "" $1 + DeleteRegValue HKCR ".bxrc" "backup_val" + NoOwn: + + DeleteRegKey HKCR "BochsConfigFile" + DeleteRegKey HKLM "SOFTWARE\${NAME}" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}" + + Delete "${PGDIR}\*.lnk" + Delete "${PGDIR}\*.pif" + Delete "${PGDIR}\*.url" + RMDir "${PGDIR}" + + Delete "${DESKTOP_DLXLINK}" + Delete "${DESKTOP_DLX_PIF}" + + Delete "$INSTDIR\*.exe" + Delete "$INSTDIR\*.txt" + Delete "$INSTDIR\*.ico" + Delete "$INSTDIR\keymaps\*" + Delete "$INSTDIR\BIOS-bochs-*" + Delete "$INSTDIR\VGABIOS-*" + Delete "$INSTDIR\dlxlinux\*" + Delete "$INSTDIR\docs\index.html" + Delete "$INSTDIR\docs\user\*" + Delete "$INSTDIR\docs\development\*" + Delete "$INSTDIR\docs\documentation\*" + Delete "$INSTDIR\docs\images\*" + + RMDIR "$INSTDIR\keymaps" + RMDIR "$INSTDIR\dlxlinux" + RMDIR "$INSTDIR\docs\user" + RMDIR "$INSTDIR\docs\development" + RMDIR "$INSTDIR\docs\documentation" + RMDIR "$INSTDIR\docs\images" + RMDIR "$INSTDIR\docs" + RMDIR "$INSTDIR" + +SectionEnd + +;eof diff --git a/bochs/build/win32/nsis/lgban.ico b/bochs/build/win32/nsis/lgban.ico new file mode 100755 index 00000000..f4bbdd4d Binary files /dev/null and b/bochs/build/win32/nsis/lgban.ico differ diff --git a/bochs/build/win32/nsis/logo.ico b/bochs/build/win32/nsis/logo.ico new file mode 100755 index 00000000..34e66cd6 Binary files /dev/null and b/bochs/build/win32/nsis/logo.ico differ diff --git a/bochs/build/win32/nsis/penguin.ico b/bochs/build/win32/nsis/penguin.ico new file mode 100644 index 00000000..a3202602 Binary files /dev/null and b/bochs/build/win32/nsis/penguin.ico differ diff --git a/bochs/build/win32/nsis/unbochs.ico b/bochs/build/win32/nsis/unbochs.ico new file mode 100644 index 00000000..4031cde7 Binary files /dev/null and b/bochs/build/win32/nsis/unbochs.ico differ diff --git a/bochs/build/win32/vs2008ex-workspace.zip b/bochs/build/win32/vs2008ex-workspace.zip new file mode 100644 index 00000000..81faaa71 Binary files /dev/null and b/bochs/build/win32/vs2008ex-workspace.zip differ diff --git a/bochs/bx_debug/Makefile.in b/bochs/bx_debug/Makefile.in new file mode 100644 index 00000000..6befd8cc --- /dev/null +++ b/bochs/bx_debug/Makefile.in @@ -0,0 +1,141 @@ +# Copyright (C) 2001 The Bochs Project +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + +@SUFFIX_LINE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_builddir = .. +top_srcdir = @top_srcdir@ + +SHELL = /bin/sh + +@SET_MAKE@ + +CC = @CC@ +CFLAGS = @CFLAGS@ @GUI_CFLAGS@ +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ @GUI_CXXFLAGS@ + +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +RANLIB = @RANLIB@ + +# Definitely use flex. Use flex version >= 2.5.4 +# Flex version 2.5.2 was reported not to work +LEX = flex +YACC = yacc + + +# =========================================================== +# end of configurable options +# =========================================================== + + +BX_OBJS = \ + dbg_main.o \ + symbols.o \ + linux.o \ + +BX_PARSER_OBJS = \ + parser.o \ + lexer.o + +BX_INCLUDES = debug.h + +BX_INCDIRS = -I.. -I$(srcdir)/.. -I../@INSTRUMENT_DIR@ -I$(srcdir)/../@INSTRUMENT_DIR@ -I. -I$(srcdir)/. + +all: libdebug.a + +.@CPP_SUFFIX@.o: + $(CXX) @DASH@c $(BX_INCDIRS) $(CXXFLAGS) @CXXFP@$< @OFP@$@ + + +.c.o: + $(CC) @DASH@c $(BX_INCDIRS) $(CFLAGS) @CFP@$< @OFP@$@ + + + +libdebug.a: $(BX_OBJS) $(BX_PARSER_OBJS) + @RMCOMMAND@ libdebug.a + @MAKELIB@ $(BX_OBJS) $(BX_PARSER_OBJS) + $(RANLIB) libdebug.a + +$(BX_OBJS): $(BX_INCLUDES) + + +clean: + @RMCOMMAND@ *.o + @RMCOMMAND@ libdebug.a + +dist-clean: clean + @RMCOMMAND@ Makefile + +parse-clean: + @RMCOMMAND@ -f lexer.c + @RMCOMMAND@ -f parser.c + @RMCOMMAND@ -f parser.h + +dbg_main.o: debug.h +sim2.o: debug.h + +parser.c: parser.y + @/bin/rm -f y.tab.c parser.c + @/bin/rm -f y.tab.h parser.h + $(YACC) -p bx -d $< + @/bin/mv -f y.tab.c parser.c + @/bin/mv -f y.tab.h parser.h + @echo '#endif /* if BX_DEBUGGER */' >> parser.c + @echo '/* The #endif is appended by the makefile after running yacc. */' >> parser.c + +lexer.c: lexer.l + $(LEX) -Pbx -t $< > lexer.c + +########################################### +# dependencies generated by +# gcc -MM -I. -I.. -I../instrument/stubs *.c *.cc | sed 's/\.cc/.@CPP_SUFFIX@/g' +########################################### +lexer.o: lexer.c debug.h ../config.h ../osdep.h +parser.o: parser.c debug.h ../config.h ../osdep.h +dbg_main.o: dbg_main.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \ + ../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \ + ../gui/siminterface.h ../gui/paramtree.h ../memory/memory.h \ + ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \ + ../instrument/stubs/instrument.h ../param_names.h ../cpu/cpu.h \ + ../cpu/model_specific.h ../cpu/crregs.h ../cpu/descriptor.h \ + ../cpu/instr.h ../cpu/ia_opcodes.h ../cpu/lazy_flags.h ../cpu/icache.h \ + ../cpu/apic.h ../cpu/i387.h ../fpu/softfloat.h ../fpu/tag_w.h \ + ../fpu/status_w.h ../fpu/control_w.h ../cpu/xmm.h ../iodev/iodev.h +linux.o: linux.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \ + ../config.h ../osdep.h ../bxversion.h ../gui/siminterface.h \ + ../gui/paramtree.h ../memory/memory.h ../pc_system.h ../plugin.h \ + ../extplugin.h ../ltdl.h ../gui/gui.h ../instrument/stubs/instrument.h \ + ../cpu/cpu.h ../cpu/model_specific.h ../cpu/crregs.h \ + ../cpu/descriptor.h ../cpu/instr.h ../cpu/ia_opcodes.h \ + ../cpu/lazy_flags.h ../cpu/icache.h ../cpu/apic.h ../cpu/i387.h \ + ../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \ + ../cpu/xmm.h +symbols.o: symbols.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \ + ../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \ + ../gui/siminterface.h ../gui/paramtree.h ../memory/memory.h \ + ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \ + ../instrument/stubs/instrument.h ../cpu/cpu.h ../cpu/model_specific.h \ + ../cpu/crregs.h ../cpu/descriptor.h ../cpu/instr.h ../cpu/ia_opcodes.h \ + ../cpu/lazy_flags.h ../cpu/icache.h ../cpu/apic.h ../cpu/i387.h \ + ../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \ + ../cpu/xmm.h diff --git a/bochs/bx_debug/dbg_main.cc b/bochs/bx_debug/dbg_main.cc new file mode 100644 index 00000000..0104c33b --- /dev/null +++ b/bochs/bx_debug/dbg_main.cc @@ -0,0 +1,3884 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2009 The Bochs Project +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +///////////////////////////////////////////////////////////////////////// + +extern "C" { +#include +} + +#include "bochs.h" +#include "param_names.h" +#include "cpu/cpu.h" +#include "iodev/iodev.h" + +#if BX_DEBUGGER + +#include "disasm/disasm.h" + +#define LOG_THIS genlog-> + +#if HAVE_LIBREADLINE +extern "C" { +#include +#include +#if HAVE_READLINE_HISTORY_H +#include +#endif +} +#endif + +// default CPU in the debugger. For commands like "dump_cpu" it will +// use the default instead of always dumping all cpus. +unsigned dbg_cpu = 0; +bx_list_c *dbg_cpu_list = 0; + +extern const char* cpu_mode_string(unsigned cpu_mode); +extern void bx_sr_after_restore_state(void); + +void bx_dbg_print_descriptor(Bit32u lo, Bit32u hi); +void bx_dbg_print_descriptor64(Bit32u lo1, Bit32u hi1, Bit32u lo2, Bit32u hi2); + +static bx_param_bool_c *sim_running = NULL; + +static char tmp_buf[512]; +static char tmp_buf_prev[512]; +static char *tmp_buf_ptr; +static char *argv0 = NULL; + +static FILE *debugger_log = NULL; + +static struct { + // some fields used for single CPU debugger + bx_bool auto_disassemble; + unsigned disassemble_size; + char default_display_format; + char default_unit_size; + bx_address default_addr; + unsigned next_bpoint_id; + unsigned next_wpoint_id; +} bx_debugger; + +typedef struct { + FILE *fp; + char fname[BX_MAX_PATH]; + unsigned lineno; +} bx_infile_stack_entry_t; + +bx_infile_stack_entry_t bx_infile_stack[BX_INFILE_DEPTH]; +int bx_infile_stack_index = 0; + +static int bx_nest_infile(char *path); + +void CDECL bx_debug_ctrlc_handler(int signum); + +static void bx_unnest_infile(void); +static void bx_get_command(void); +static void bx_dbg_print_guard_results(); +static void bx_dbg_breakpoint_changed(void); + +bx_guard_t bx_guard; + +// DMA stuff +void bx_dbg_post_dma_reports(void); +#define BX_BATCH_DMA_BUFSIZE 512 + +static struct { + unsigned this_many; // batch this many max before posting events + unsigned Qsize; // this many have been batched + struct { + bx_phy_address addr; // address of DMA op + unsigned len; // number of bytes in op + unsigned what; // BX_READ or BX_WRITE + Bit32u val; // value of DMA op + Bit64u time; // system time at this dma op + } Q[BX_BATCH_DMA_BUFSIZE]; +} bx_dbg_batch_dma; + +// some buffers for disassembly +static disassembler bx_disassemble; +static Bit8u bx_disasm_ibuf[32]; +static char bx_disasm_tbuf[512]; + +static bx_bool watchpoint_continue = 0; +unsigned num_write_watchpoints = 0; +unsigned num_read_watchpoints = 0; +bx_watchpoint write_watchpoint[BX_DBG_MAX_WATCHPONTS]; +bx_watchpoint read_watchpoint[BX_DBG_MAX_WATCHPONTS]; + +#define DBG_PRINTF_BUFFER_LEN 1024 + +void dbg_printf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + char buf[DBG_PRINTF_BUFFER_LEN+1]; + vsnprintf(buf, DBG_PRINTF_BUFFER_LEN, fmt, ap); + va_end(ap); + if (debugger_log != NULL) { + fprintf(debugger_log,"%s", buf); + fflush(debugger_log); + } + SIM->debug_puts(buf); // send to debugger, which will free buf when done. +} + +void bx_dbg_init_infile(void) +{ + bx_infile_stack_index = 0; + bx_infile_stack[0].fp = stdin; + bx_infile_stack[0].lineno = 0; +} + +int bx_dbg_set_rcfile(const char *rcfile) +{ + strncpy(bx_infile_stack[0].fname, rcfile, BX_MAX_PATH); + bx_infile_stack[0].fname[BX_MAX_PATH-1] = 0; + BX_INFO(("debugger using rc file '%s'.", rcfile)); + return bx_nest_infile((char*)rcfile); +} + +int bx_dbg_main(void) +{ + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + bx_dbg_batch_dma.this_many = 1; + bx_dbg_batch_dma.Qsize = 0; + + memset(&bx_guard, 0, sizeof(bx_guard)); + bx_guard.async.irq = 1; + bx_guard.async.dma = 1; + + memset(&bx_debugger, 0, sizeof(bx_debugger)); + bx_debugger.auto_disassemble = 1; + bx_debugger.disassemble_size = 0; + bx_debugger.default_display_format = 'x'; + bx_debugger.default_unit_size = 'w'; + bx_debugger.default_addr = 0; + bx_debugger.next_bpoint_id = 1; + bx_debugger.next_wpoint_id = 1; + + dbg_cpu_list = (bx_list_c*) SIM->get_param("cpu0", SIM->get_bochs_root()); + const char *debugger_log_filename = SIM->get_param_string(BXPN_DEBUGGER_LOG_FILENAME)->getptr(); + + // Open debugger log file if needed + if (strlen(debugger_log_filename) > 0 && (strcmp(debugger_log_filename, "-") != 0)) + { + debugger_log = fopen(debugger_log_filename, "w"); + if (!debugger_log) { + BX_PANIC(("Can not open debugger log file '%s'", debugger_log_filename)); + } + else { + BX_INFO(("Using debugger log file %s", debugger_log_filename)); + } + } + + memset(bx_disasm_ibuf, 0, sizeof(bx_disasm_ibuf)); + + // create a boolean parameter that will tell if the simulation is + // running (continue command) or waiting for user response. This affects + // some parts of the GUI. + if (sim_running == NULL) { + bx_list_c *base = (bx_list_c*) SIM->get_param("general"); + sim_running = new bx_param_bool_c(base, + "debug_running", + "Simulation is running", "", 0); + } else { + sim_running->set(0); + } + // setup Ctrl-C handler + if (!SIM->has_debug_gui()) { + signal(SIGINT, bx_debug_ctrlc_handler); + BX_INFO(("set SIGINT handler to bx_debug_ctrlc_handler")); + } + + // Print disassembly of the first instruction... you wouldn't think it + // would have to be so hard. First initialize guard_found, since it is used + // in the disassembly code to decide what instruction to print. + for (int i=0; iguard_found.cs = BX_CPU(i)->sregs[BX_SEG_REG_CS].selector.value; + BX_CPU(i)->guard_found.eip = BX_CPU(i)->get_instruction_pointer(); + BX_CPU(i)->guard_found.laddr = + BX_CPU(i)->get_laddr(BX_SEG_REG_CS, BX_CPU(i)->guard_found.eip); + // 00 - 16 bit, 01 - 32 bit, 10 - 64-bit, 11 - illegal + if (BX_CPU(i)->sregs[BX_SEG_REG_CS].cache.u.segment.d_b) + BX_CPU(i)->guard_found.code_32_64 |= 0x1; + if (BX_CPU(i)->get_cpu_mode() == BX_MODE_LONG_64) + BX_CPU(i)->guard_found.code_32_64 |= 0x2; + } + // finally, call the usual function to print the disassembly + dbg_printf("Next at t=" FMT_LL "d\n", bx_pc_system.time_ticks()); + bx_dbg_disassemble_current(-1, 0); // all cpus, don't print time + + bx_dbg_user_input_loop(); + + if(debugger_log != NULL) + fclose(debugger_log); + + bx_dbg_exit(0); + return(0); // keep compiler happy +} + +void bx_dbg_interpret_line(char *cmd) +{ + bx_add_lex_input(cmd); + bxparse(); +} + +void bx_dbg_user_input_loop(void) +{ + int reti; + unsigned include_cmd_len = strlen(BX_INCLUDE_CMD); + + while(1) { + SIM->refresh_ci(); + SIM->set_display_mode(DISP_MODE_CONFIG); + bx_get_command(); +reparse: + if ((*tmp_buf_ptr == '\n') || (*tmp_buf_ptr == 0)) + { + if ((*tmp_buf_prev != '\n') && (*tmp_buf_prev != 0)) { + strncpy(tmp_buf, tmp_buf_prev, sizeof(tmp_buf_prev)); + goto reparse; + } + } + else if ((strncmp(tmp_buf_ptr, BX_INCLUDE_CMD, include_cmd_len) == 0) && + (tmp_buf_ptr[include_cmd_len] == ' ' || + tmp_buf_ptr[include_cmd_len] == '\t')) + { + char *ptr = tmp_buf_ptr + include_cmd_len + 1; + while(*ptr==' ' || *ptr=='\t') + ptr++; + + int len = strlen(ptr); + if (len == 0) { + dbg_printf("%s: no filename given to 'source' command.\n", argv0); + if (bx_infile_stack_index > 0) { + dbg_printf("%s: ERROR in source file causes exit.\n", argv0); + bx_dbg_exit(1); + } + continue; + } + ptr[len-1] = 0; // get rid of newline + reti = bx_nest_infile(ptr); + if (reti==0 && bx_infile_stack_index > 0) { + dbg_printf("%s: ERROR in source file causes exit.\n", argv0); + bx_dbg_exit(1); + } + } + else { + // Give a chance to the command line extensions, to + // consume the command. If they return 0, then + // we need to process the command. A return of 1 + // means, the extensions have handled the command + if (bx_dbg_extensions(tmp_buf_ptr)==0) { + // process command here + bx_add_lex_input(tmp_buf_ptr); + bxparse(); + } + } + } +} + +void bx_get_command(void) +{ + char *charptr_ret; + + bx_infile_stack[bx_infile_stack_index].lineno++; + + char prompt[256]; + if (bx_infile_stack_index == 0) { + sprintf(prompt, " ", bx_infile_stack[bx_infile_stack_index].lineno); + } + if (SIM->has_debug_gui() && bx_infile_stack_index == 0) { + // wait for wxWidgets to send another debugger command + charptr_ret = SIM->debug_get_next_command(); + if (charptr_ret) { + strncpy(tmp_buf, charptr_ret, sizeof(tmp_buf)); + strcat(tmp_buf, "\n"); + // The returned string was allocated in wxmain.cc by "new char[]". + // Free it with delete[]. + delete [] charptr_ret; + charptr_ret = &tmp_buf[0]; + } else { + // if debug_get_next_command returned NULL, probably the GUI is + // shutting down + } + } +#if HAVE_LIBREADLINE + else if (bx_infile_stack_index == 0) { + charptr_ret = readline(prompt); + // beware, returns NULL on end of file + if (charptr_ret && strlen(charptr_ret) > 0) { + add_history(charptr_ret); + strcpy(tmp_buf, charptr_ret); + strcat(tmp_buf, "\n"); + free(charptr_ret); + charptr_ret = &tmp_buf[0]; + } + } else { + charptr_ret = fgets(tmp_buf, sizeof(tmp_buf), bx_infile_stack[bx_infile_stack_index].fp); + } +#else /* !HAVE_LIBREADLINE */ + else { + if (bx_infile_stack_index == 0) + dbg_printf("%s", prompt); + strncpy(tmp_buf_prev, tmp_buf, sizeof(tmp_buf)); + charptr_ret = fgets(tmp_buf, sizeof(tmp_buf), bx_infile_stack[bx_infile_stack_index].fp); + } +#endif + if (charptr_ret == NULL) { + // see if error was due to EOF condition + if (feof(bx_infile_stack[bx_infile_stack_index].fp)) { + if (bx_infile_stack_index > 0) { + // nested level of include files, pop back to previous one + bx_unnest_infile(); + } + else { + // not nested, sitting at stdin prompt, user wants out + bx_dbg_quit_command(); + BX_PANIC(("bx_dbg_quit_command should not return, but it did")); + } + + // call recursively + bx_get_command(); + return; + } + + // error was not EOF, see if it was from a Ctrl-C + if (bx_guard.interrupt_requested) { + tmp_buf[0] = '\n'; + tmp_buf[1] = 0; + tmp_buf_ptr = &tmp_buf[0]; + bx_guard.interrupt_requested = 0; + return; + } + + dbg_printf("fgets() returned ERROR.\n"); + dbg_printf("intr request was %u\n", bx_guard.interrupt_requested); + bx_dbg_exit(1); + } + tmp_buf_ptr = &tmp_buf[0]; + + if (debugger_log != NULL) { + fprintf(debugger_log, "%s", tmp_buf); + fflush(debugger_log); + } + + // look for first non-whitespace character + while (((*tmp_buf_ptr == ' ') || (*tmp_buf_ptr == '\t')) && + (*tmp_buf_ptr != '\n') && (*tmp_buf_ptr != 0)) + { + tmp_buf_ptr++; + } +} + +int bx_nest_infile(char *path) +{ + FILE *tmp_fp; + + tmp_fp = fopen(path, "r"); + if (!tmp_fp) { + dbg_printf("%s: can not open file '%s' for reading.\n", argv0, path); + return(0); + } + + if ((bx_infile_stack_index+1) >= BX_INFILE_DEPTH) { + dbg_printf("%s: source files nested too deeply\n", argv0); + return(0); + } + + bx_infile_stack_index++; + bx_infile_stack[bx_infile_stack_index].fp = tmp_fp; + strncpy(bx_infile_stack[bx_infile_stack_index].fname, path, BX_MAX_PATH); + bx_infile_stack[bx_infile_stack_index].fname[BX_MAX_PATH-1] = 0; + bx_infile_stack[bx_infile_stack_index].lineno = 0; + return(1); +} + +void bx_unnest_infile(void) +{ + if (bx_infile_stack_index <= 0) { + dbg_printf("%s: ERROR: unnest_infile(): nesting level = 0\n", argv0); + bx_dbg_exit(1); + } + + fclose(bx_infile_stack[bx_infile_stack_index].fp); + bx_infile_stack_index--; +} + +int bxwrap(void) +{ + dbg_printf("%s: ERROR: bxwrap() called\n", argv0); + bx_dbg_exit(1); + return(0); // keep compiler quiet +} + +#ifdef WIN32 +char* bxtext; +#endif + +void bxerror(char *s) +{ + dbg_printf("%s:%d: %s at '%s'\n", bx_infile_stack[bx_infile_stack_index].fname, + bx_infile_stack[bx_infile_stack_index].lineno, s, bxtext); + + if (bx_infile_stack_index > 0) { + dbg_printf("%s: ERROR in source file causes exit\n", argv0); + bx_dbg_exit(1); + } +} + +void CDECL bx_debug_ctrlc_handler(int signum) +{ + UNUSED(signum); + if (SIM->has_debug_gui()) { + // in a multithreaded environment, a signal such as SIGINT can be sent to all + // threads. This function is only intended to handle signals in the + // simulator thread. It will simply return if called from any other thread. + // Otherwise the BX_PANIC() below can be called in multiple threads at + // once, leading to multiple threads trying to display a dialog box, + // leading to GUI deadlock. + if (!SIM->is_sim_thread()) { + BX_INFO(("bx_signal_handler: ignored sig %d because it wasn't called from the simulator thread", signum)); + return; + } + } + BX_INFO(("Ctrl-C detected in signal handler.")); + + signal(SIGINT, bx_debug_ctrlc_handler); + bx_debug_break(); +} + +void bx_debug_break() +{ + bx_guard.interrupt_requested = 1; +} + +void bx_dbg_exception(unsigned cpu, Bit8u vector, Bit16u error_code) +{ + static const char *exception[] = { + "(#DE) divide by zero", + "(#DB) debug break", + "(#NMI)", + "(#BP) breakpoint match", + "(#OF) overflow", + "(#BR) boundary check", + "(#UD) undefined opcode", + "(#NM) device not available", + "(#DF) double fault", + "(#CO) coprocessor overrun", + "(#TS) invalid TSS", + "(#NP) segment not present", + "(#SS) stack fault", + "(#GP) general protection fault", + "(#PF) page fault", + "(#RESERVED)", + "(#MF) floating point error", + "(#AC) alignment check", + "(#MC) machine check", + "(#XF) SIMD floating point exception", + }; + + if (BX_CPU(dbg_cpu)->trace || bx_dbg.exceptions) + { + if (vector <= BX_XM_EXCEPTION) { + dbg_printf("CPU %d: Exception 0x%02x - %s occured (error_code=0x%04x)\n", + cpu, vector, exception[vector], error_code); + } + else { + dbg_printf("CPU %d: Exception 0x%02x occured (error_code=0x%04x)\n", + cpu, vector, error_code); + } + } +} + +void bx_dbg_interrupt(unsigned cpu, Bit8u vector, Bit16u error_code) +{ + if (BX_CPU(dbg_cpu)->trace || bx_dbg.interrupts) + { + dbg_printf("CPU %d: Interrupt 0x%02x occured (error_code=0x%04x)\n", + cpu, vector, error_code); + } +} + +void bx_dbg_halt(unsigned cpu) +{ + if (BX_CPU(dbg_cpu)->trace) + { + dbg_printf("CPU %d: HALTED\n", cpu); + } +} + +void bx_dbg_watchpoint_continue(bx_bool watch_continue) +{ + watchpoint_continue = watch_continue; + if (watchpoint_continue) { + dbg_printf("Will stop on watch points\n"); + } + else { + dbg_printf("Will not stop on watch points (they will still be logged)\n"); + } +} + +void bx_dbg_check_memory_watchpoints(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw) +{ + bx_phy_address phy_end = phy + len - 1; + + if (rw & 1) { + // Check for physical write watch points + for (unsigned i = 0; i < num_write_watchpoints; i++) { + bx_phy_address watch_end = write_watchpoint[i].addr + write_watchpoint[i].len - 1; + if (watch_end < phy || phy_end < write_watchpoint[i].addr) continue; + BX_CPU(cpu)->watchpoint = phy; + BX_CPU(cpu)->break_point = BREAK_POINT_WRITE; + break; + } + } + else { + // Check for physical read watch points + for (unsigned i = 0; i < num_read_watchpoints; i++) { + bx_phy_address watch_end = read_watchpoint[i].addr + read_watchpoint[i].len - 1; + if (watch_end < phy || phy_end < read_watchpoint[i].addr) continue; + BX_CPU(cpu)->watchpoint = phy; + BX_CPU(cpu)->break_point = BREAK_POINT_READ; + break; + } + } +} + +void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsigned len, unsigned pl, unsigned rw, Bit8u *data) +{ + bx_dbg_check_memory_watchpoints(cpu, phy, len, rw); + + if (! BX_CPU(cpu)->trace_mem) + return; + + bx_bool write = rw & 1; + + dbg_printf("[CPU%d %s]: LIN 0x" FMT_ADDRX " PHY 0x" FMT_PHY_ADDRX " (len=%d, pl=%d)", + cpu, + (write) ? "WR" : "RD", + lin, phy, + len, pl); + + if (len == 1) { + Bit8u val8 = *data; + dbg_printf(": 0x%02X", (unsigned) val8); + } + else if (len == 2) { + Bit16u val16 = *((Bit16u*) data); + dbg_printf(": 0x%04X", (unsigned) val16); + } + else if (len == 4) { + Bit32u val32 = *((Bit32u*) data); + dbg_printf(": 0x%08X", (unsigned) val32); + } + else if (len == 8) { + Bit64u data64 = * (Bit64u*)(data); + dbg_printf(": 0x%08X 0x%08X", GET32H(data64), GET32L(data64)); + } +#if BX_CPU_LEVEL >= 6 + else if (len == 16) { + const BxPackedXmmRegister *xmmdata = (const BxPackedXmmRegister*)(data); + dbg_printf(": 0x%08X 0x%08X 0x%08X 0x%08X", + xmmdata->xmm32u(3), xmmdata->xmm32u(2), xmmdata->xmm32u(1), xmmdata->xmm32u(0)); + } +#endif + + dbg_printf("\n"); +} + +void bx_dbg_phy_memory_access(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw, Bit8u *data) +{ + bx_dbg_check_memory_watchpoints(cpu, phy, len, rw); + + if (! BX_CPU(cpu)->trace_mem) + return; + + unsigned access = rw >> 4; + + static const char *access_string[] = { + "", + "PDPTR0", + "PDPTR1", + "PDPTR2", + "PDPTR3", + "PTE", + "PDE", + "PDPTE", + "PML4E", + "EPT PTE", + "EPT PDE", + "EPT PDPTE", + "EPT PML4E", + "VMCS", + "VMX MSR BITMAP", + "VMX I/O BITMAP", + "VMX LDMSR", + "VMX STMSR", + "VMX VTPR", + "SMRAM" + }; + + bx_bool write = rw & 1; + + dbg_printf("[CPU%d %s]: PHY 0x" FMT_PHY_ADDRX " (len=%d)", + cpu, + (write) ? "WR" : "RD", + phy, + len); + + if (len == 1) { + Bit8u val8 = *data; + dbg_printf(": 0x%02X", (unsigned) val8); + } + else if (len == 2) { + Bit16u val16 = *((Bit16u*) data); + dbg_printf(": 0x%04X", (unsigned) val16); + } + else if (len == 4) { + Bit32u val32 = *((Bit32u*) data); + dbg_printf(": 0x%08X", (unsigned) val32); + } + else if (len == 8) { + Bit64u data64 = * (Bit64u*)(data); + dbg_printf(": 0x%08X 0x%08X", GET32H(data64), GET32L(data64)); + } +#if BX_CPU_LEVEL >= 6 + else if (len == 16) { + const BxPackedXmmRegister *xmmdata = (const BxPackedXmmRegister*)(data); + dbg_printf(": 0x%08X 0x%08X 0x%08X 0x%08X", + xmmdata->xmm32u(3), xmmdata->xmm32u(2), xmmdata->xmm32u(1), xmmdata->xmm32u(0)); + } +#endif + + if (access != 0) + dbg_printf("\t; %s\n", access_string[access]); + else + dbg_printf("\n"); +} + +void bx_dbg_exit(int code) +{ + BX_DEBUG(("dbg: before exit")); + for (int cpu=0; cpu < BX_SMP_PROCESSORS; cpu++) { + if (BX_CPU(cpu)) BX_CPU(cpu)->atexit(); + } + + bx_atexit(); + BX_EXIT(code); +} + +// +// functions for browsing of cpu state +// + +void bx_dbg_print_sse_state(void) +{ +#if BX_CPU_LEVEL >= 6 + Bit32u isa_extensions_bitmask = SIM->get_param_num("isa_extensions_bitmask", dbg_cpu_list)->get(); + + if ((isa_extensions_bitmask & BX_CPU_SSE) != 0) { + Bit32u mxcsr = SIM->get_param_num("SSE.mxcsr", dbg_cpu_list)->get(); + dbg_printf("MXCSR: 0x%08x: %s %s RC:%d %s %s %s %s %s %s %s %s %s %s %s %s %s\n", mxcsr, + (mxcsr & (1<<17)) ? "ULE" : "ule", + (mxcsr & (1<<15)) ? "FUZ" : "fuz", + (mxcsr >> 13) & 3, + (mxcsr & (1<<12)) ? "PM" : "pm", + (mxcsr & (1<<11)) ? "UM" : "um", + (mxcsr & (1<<10)) ? "OM" : "om", + (mxcsr & (1<<9)) ? "ZM" : "zm", + (mxcsr & (1<<8)) ? "DM" : "dm", + (mxcsr & (1<<7)) ? "IM" : "im", + (mxcsr & (1<<6)) ? "DAZ" : "daz", + (mxcsr & (1<<5)) ? "PE" : "pe", + (mxcsr & (1<<4)) ? "UE" : "ue", + (mxcsr & (1<<3)) ? "OE" : "oe", + (mxcsr & (1<<2)) ? "ZE" : "ze", + (mxcsr & (1<<1)) ? "DE" : "de", + (mxcsr & (1<<0)) ? "IE" : "ie"); + + char param_name[20]; + for(unsigned i=0;iget_param_num(param_name, dbg_cpu_list)->get64(); + sprintf(param_name, "SSE.xmm%02d_0", i); + Bit64u lo = SIM->get_param_num(param_name, dbg_cpu_list)->get64(); + dbg_printf("XMM[%02u]: %08x:%08x:%08x:%08x\n", i, + GET32H(hi), GET32L(hi), GET32H(lo), GET32L(lo)); + } + } + else +#endif + { + dbg_printf("The CPU doesn't support SSE state !\n"); + } +} + +void bx_dbg_print_mmx_state(void) +{ +#if BX_CPU_LEVEL >= 5 + Bit32u isa_extensions_bitmask = SIM->get_param_num("isa_extensions_bitmask", dbg_cpu_list)->get(); + + if ((isa_extensions_bitmask & BX_CPU_MMX) != 0) { + char param_name[20]; + for(unsigned i=0;i<8;i++) { + sprintf(param_name, "FPU.st%d.fraction", i); + Bit64u mmreg = SIM->get_param_num(param_name, dbg_cpu_list)->get64(); + dbg_printf("MM[%d]: %08x:%08x\n", i, GET32H(mmreg), GET32L(mmreg)); + } + } + else +#endif + { + dbg_printf("The CPU doesn't support MMX state !\n"); + } +} + +void bx_dbg_print_fpu_state(void) +{ +#if BX_SUPPORT_FPU + BX_CPU(dbg_cpu)->print_state_FPU(); +#else + dbg_printf("The CPU doesn't support FPU state !\n"); +#endif +} + +void bx_dbg_info_flags(void) +{ + dbg_printf("%s %s %s %s %s %s %s IOPL=%1u %s %s %s %s %s %s %s %s %s\n", + BX_CPU(dbg_cpu)->get_ID() ? "ID" : "id", + BX_CPU(dbg_cpu)->get_VIP() ? "VIP" : "vip", + BX_CPU(dbg_cpu)->get_VIF() ? "VIF" : "vif", + BX_CPU(dbg_cpu)->get_AC() ? "AC" : "ac", + BX_CPU(dbg_cpu)->get_VM() ? "VM" : "vm", + BX_CPU(dbg_cpu)->get_RF() ? "RF" : "rf", + BX_CPU(dbg_cpu)->get_NT() ? "NT" : "nt", + BX_CPU(dbg_cpu)->get_IOPL(), + BX_CPU(dbg_cpu)->get_OF() ? "OF" : "of", + BX_CPU(dbg_cpu)->get_DF() ? "DF" : "df", + BX_CPU(dbg_cpu)->get_IF() ? "IF" : "if", + BX_CPU(dbg_cpu)->get_TF() ? "TF" : "tf", + BX_CPU(dbg_cpu)->get_SF() ? "SF" : "sf", + BX_CPU(dbg_cpu)->get_ZF() ? "ZF" : "zf", + BX_CPU(dbg_cpu)->get_AF() ? "AF" : "af", + BX_CPU(dbg_cpu)->get_PF() ? "PF" : "pf", + BX_CPU(dbg_cpu)->get_CF() ? "CF" : "cf"); +} + +void bx_dbg_info_debug_regs_command(void) +{ + bx_address dr0 = SIM->get_param_num("DR0", dbg_cpu_list)->get(); + bx_address dr1 = SIM->get_param_num("DR1", dbg_cpu_list)->get(); + bx_address dr2 = SIM->get_param_num("DR2", dbg_cpu_list)->get(); + bx_address dr3 = SIM->get_param_num("DR3", dbg_cpu_list)->get(); + Bit32u dr6 = SIM->get_param_num("DR6", dbg_cpu_list)->get(); + Bit32u dr7 = SIM->get_param_num("DR7", dbg_cpu_list)->get(); + + dbg_printf("DR0=0x" FMT_ADDRX "\n", dr0); + dbg_printf("DR1=0x" FMT_ADDRX "\n", dr1); + dbg_printf("DR2=0x" FMT_ADDRX "\n", dr2); + dbg_printf("DR3=0x" FMT_ADDRX "\n", dr3); + + static const char *dr_ln[4] = { "Byte", "Word", "QWord", "Dword" }; + static const char *dr_rw[4] = { "Code", "DataW", "I/O", "DataRW" }; + + dbg_printf("DR6=0x%08x: %s %s %s %s %s %s %s\n", dr6, + (dr6 & (1<<15)) ? "BT" : "bt", + (dr6 & (1<<14)) ? "BS" : "bs", + (dr6 & (1<<13)) ? "BD" : "bd", + (dr6 & (1<<3)) ? "B3" : "b3", + (dr6 & (1<<2)) ? "B2" : "b2", + (dr6 & (1<<1)) ? "B1" : "b1", + (dr6 & (1<<0)) ? "B0" : "b0"); + + dbg_printf("DR7=0x%08x: DR3=%s-%s DR2=%s-%s DR1=%s-%s DR0=%s-%s %s | %s %s | %s %s %s %s %s %s %s %s\n", dr7, + dr_rw[(dr7 >> 28) & 3], dr_ln[(dr7 >> 30) & 3], + dr_rw[(dr7 >> 24) & 3], dr_ln[(dr7 >> 26) & 3], + dr_rw[(dr7 >> 20) & 3], dr_ln[(dr7 >> 22) & 3], + dr_rw[(dr7 >> 16) & 3], dr_ln[(dr7 >> 18) & 3], + (dr7 & (1<<13)) ? "GD" : "gd", + (dr7 & (1<<9)) ? "GE" : "ge", + (dr7 & (1<<8)) ? "LE" : "le", + (dr7 & (1<<7)) ? "G3" : "g3", + (dr7 & (1<<6)) ? "L3" : "l3", + (dr7 & (1<<5)) ? "G2" : "g2", + (dr7 & (1<<4)) ? "L2" : "l2", + (dr7 & (1<<3)) ? "G1" : "g1", + (dr7 & (1<<2)) ? "L1" : "l1", + (dr7 & (1<<1)) ? "G0" : "g0", + (dr7 & (1<<0)) ? "L0" : "l0"); +} + +void bx_dbg_info_control_regs_command(void) +{ + Bit32u cr0 = SIM->get_param_num("CR0", dbg_cpu_list)->get(); + bx_address cr2 = (bx_address) SIM->get_param_num("CR2", dbg_cpu_list)->get64(); + bx_phy_address cr3 = (bx_phy_address) SIM->get_param_num("CR3", dbg_cpu_list)->get64(); + dbg_printf("CR0=0x%08x: %s %s %s %s %s %s %s %s %s %s %s\n", cr0, + (cr0 & (1<<31)) ? "PG" : "pg", + (cr0 & (1<<30)) ? "CD" : "cd", + (cr0 & (1<<29)) ? "NW" : "nw", + (cr0 & (1<<18)) ? "AC" : "ac", + (cr0 & (1<<16)) ? "WP" : "wp", + (cr0 & (1<<5)) ? "NE" : "ne", + (cr0 & (1<<4)) ? "ET" : "et", + (cr0 & (1<<3)) ? "TS" : "ts", + (cr0 & (1<<2)) ? "EM" : "em", + (cr0 & (1<<1)) ? "MP" : "mp", + (cr0 & (1<<0)) ? "PE" : "pe"); + dbg_printf("CR2=page fault laddr=0x" FMT_ADDRX "\n", cr2); + dbg_printf("CR3=0x" FMT_PHY_ADDRX "\n", cr3); + dbg_printf(" PCD=page-level cache disable=%d\n", (cr3>>4) & 1); + dbg_printf(" PWT=page-level write-through=%d\n", (cr3>>3) & 1); +#if BX_CPU_LEVEL >= 4 + Bit32u cr4 = SIM->get_param_num("CR4", dbg_cpu_list)->get(); + dbg_printf("CR4=0x%08x: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", cr4, + (cr4 & (1<<18)) ? "OSXSAVE" : "osxsave", + (cr4 & (1<<17)) ? "PCID" : "pcid", + (cr4 & (1<<16)) ? "FSGSBASE" : "fsgsbase", + (cr4 & (1<<14)) ? "SMX" : "smx", + (cr4 & (1<<13)) ? "VMX" : "vmx", + (cr4 & (1<<10)) ? "OSXMMEXCPT" : "osxmmexcpt", + (cr4 & (1<<9)) ? "OSFXSR" : "osfxsr", + (cr4 & (1<<8)) ? "PCE" : "pce", + (cr4 & (1<<7)) ? "PGE" : "pge", + (cr4 & (1<<6)) ? "MCE" : "mce", + (cr4 & (1<<5)) ? "PAE" : "pae", + (cr4 & (1<<4)) ? "PSE" : "pse", + (cr4 & (1<<3)) ? "DE" : "de", + (cr4 & (1<<2)) ? "TSD" : "tsd", + (cr4 & (1<<1)) ? "PVI" : "pvi", + (cr4 & (1<<0)) ? "VME" : "vme"); +#endif +#if BX_SUPPORT_X86_64 + Bit32u efer = SIM->get_param_num("MSR.EFER", dbg_cpu_list)->get(); + dbg_printf("EFER=0x%08x: %s %s %s %s %s\n", efer, + (efer & (1<<14)) ? "FFXSR" : "ffxsr", + (efer & (1<<11)) ? "NXE" : "nxe", + (efer & (1<<10)) ? "LMA" : "lma", + (efer & (1<<8)) ? "LME" : "lme", + (efer & (1<<0)) ? "SCE" : "sce"); +#endif +} + +void bx_dbg_info_segment_regs_command(void) +{ + static const char *segname[] = { "es", "cs", "ss", "ds", "fs", "gs" }; + + bx_dbg_sreg_t sreg; + bx_dbg_global_sreg_t global_sreg; + + for(int s=0;s<6;s++) { + BX_CPU(dbg_cpu)->dbg_get_sreg(&sreg, s); + dbg_printf("%s:0x%04x, dh=0x%08x, dl=0x%08x, valid=%u\n", segname[s], + (unsigned) sreg.sel, (unsigned) sreg.des_h, + (unsigned) sreg.des_l, (unsigned) sreg.valid); + if (sreg.valid) { + dbg_printf("\t"); + bx_dbg_print_descriptor(sreg.des_l, sreg.des_h); + } + } + + BX_CPU(dbg_cpu)->dbg_get_ldtr(&sreg); + dbg_printf("ldtr:0x%04x, dh=0x%08x, dl=0x%08x, valid=%u\n", + (unsigned) sreg.sel, (unsigned) sreg.des_h, + (unsigned) sreg.des_l, (unsigned) sreg.valid); + + BX_CPU(dbg_cpu)->dbg_get_tr(&sreg); + dbg_printf("tr:0x%04x, dh=0x%08x, dl=0x%08x, valid=%u\n", + (unsigned) sreg.sel, (unsigned) sreg.des_h, + (unsigned) sreg.des_l, (unsigned) sreg.valid); + + BX_CPU(dbg_cpu)->dbg_get_gdtr(&global_sreg); + dbg_printf("gdtr:base=0x"FMT_ADDRX", limit=0x%x\n", + global_sreg.base, (unsigned) global_sreg.limit); + + BX_CPU(dbg_cpu)->dbg_get_idtr(&global_sreg); + dbg_printf("idtr:base=0x"FMT_ADDRX", limit=0x%x\n", + global_sreg.base, (unsigned) global_sreg.limit); +} + +void bx_dbg_info_registers_command(int which_regs_mask) +{ + bx_address reg; + + if (which_regs_mask & BX_INFO_GENERAL_PURPOSE_REGS) { +#if BX_SUPPORT_SMP + dbg_printf("CPU%d:\n", BX_CPU(dbg_cpu)->bx_cpuid); +#endif +#if BX_SUPPORT_X86_64 == 0 + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_EAX); + dbg_printf("eax: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_ECX); + dbg_printf("ecx: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_EDX); + dbg_printf("edx: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_EBX); + dbg_printf("ebx: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_ESP); + dbg_printf("esp: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_EBP); + dbg_printf("ebp: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_ESI); + dbg_printf("esi: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_EDI); + dbg_printf("edi: 0x%08x %d\n", (unsigned) reg, (int) reg); + reg = bx_dbg_get_eip(); + dbg_printf("eip: 0x%08x\n", (unsigned) reg); +#else + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RAX); + dbg_printf("rax: 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RCX); + dbg_printf("rcx: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RDX); + dbg_printf("rdx: 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RBX); + dbg_printf("rbx: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RSP); + dbg_printf("rsp: 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RBP); + dbg_printf("rbp: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RSI); + dbg_printf("rsi: 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RDI); + dbg_printf("rdi: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R8); + dbg_printf("r8 : 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R9); + dbg_printf("r9 : 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R10); + dbg_printf("r10: 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R11); + dbg_printf("r11: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R12); + dbg_printf("r12: 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R13); + dbg_printf("r13: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R14); + dbg_printf("r14: 0x%08x:%08x ", GET32H(reg), GET32L(reg)); + reg = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_R15); + dbg_printf("r15: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); + reg = bx_dbg_get_instruction_pointer(); + dbg_printf("rip: 0x%08x:%08x\n", GET32H(reg), GET32L(reg)); +#endif + reg = BX_CPU(dbg_cpu)->read_eflags(); + dbg_printf("eflags 0x%08x: ", (unsigned) reg); + bx_dbg_info_flags(); + } + +#if BX_SUPPORT_FPU + if (which_regs_mask & BX_INFO_FPU_REGS) { + bx_dbg_print_fpu_state(); + } +#endif + + if (which_regs_mask & BX_INFO_MMX_REGS) { + bx_dbg_print_mmx_state(); + } + + if (which_regs_mask & BX_INFO_SSE_REGS) { + bx_dbg_print_sse_state(); + } +} + +// +// commands invoked from parser +// + +void bx_dbg_quit_command(void) +{ + BX_INFO(("dbg: Quit")); + bx_dbg_exit(0); +} + +void bx_dbg_trace_command(bx_bool enable) +{ + BX_CPU(dbg_cpu)->trace = enable; + dbg_printf("Tracing %s for CPU%d\n", enable ? "enabled" : "disabled", + BX_CPU(dbg_cpu)->which_cpu()); +} + +void bx_dbg_trace_reg_command(bx_bool enable) +{ + BX_CPU(dbg_cpu)->trace_reg = enable; + dbg_printf("Register-Tracing %s for CPU%d\n", enable ? "enabled" : "disabled", + BX_CPU(dbg_cpu)->which_cpu()); +} + +void bx_dbg_trace_mem_command(bx_bool enable) +{ + BX_CPU(dbg_cpu)->trace_mem = enable; + dbg_printf("Memory-Tracing %s for CPU%d\n", enable ? "enabled" : "disabled", + BX_CPU(dbg_cpu)->which_cpu()); +} + +void bx_dbg_ptime_command(void) +{ + dbg_printf("ptime: " FMT_LL "d\n", bx_pc_system.time_ticks()); +} + +int timebp_timer = -1; +Bit64u timebp_queue[MAX_CONCURRENT_BPS]; +int timebp_queue_size = 0; + +void bx_dbg_timebp_command(bx_bool absolute, Bit64u time) +{ + Bit64u abs_time = (absolute) ? time : time + bx_pc_system.time_ticks(); + + if (abs_time < bx_pc_system.time_ticks()) { + dbg_printf("Request for time break point in the past. I can't let you do that.\n"); + return; + } + + if (timebp_queue_size == MAX_CONCURRENT_BPS) { + dbg_printf("Too many time break points\n"); + return; + } + + Bit64u diff = (absolute) ? time - bx_pc_system.time_ticks() : time; + + if (timebp_timer >= 0) { + if (timebp_queue_size == 0 || abs_time < timebp_queue[0]) { + /* first in queue */ + for (int i = timebp_queue_size; i >= 0; i--) + timebp_queue[i+1] = timebp_queue[i]; + timebp_queue[0] = abs_time; + timebp_queue_size++; + bx_pc_system.activate_timer_ticks(timebp_timer, diff, 1); + } else { + /* not first, insert at suitable place */ + for (int i = 1; i < timebp_queue_size; i++) { + if (timebp_queue[i] == abs_time) { + dbg_printf("Time breakpoint not inserted (duplicate)\n"); + return; + } else if (abs_time < timebp_queue[i]) { + for (int j = timebp_queue_size; j >= i; j--) + timebp_queue[j+1] = timebp_queue[j]; + timebp_queue[i] = abs_time; + goto inserted; + } + } + /* last */ + timebp_queue[timebp_queue_size] = abs_time; +inserted: + timebp_queue_size++; + } + } else { + timebp_queue_size = 1; + timebp_queue[0] = abs_time; + timebp_timer = bx_pc_system.register_timer_ticks(&bx_pc_system, bx_pc_system_c::timebp_handler, diff, 0, 1, "debug.timebp"); + } + + dbg_printf("Time breakpoint inserted. Delta = " FMT_LL "u\n", diff); +} + +Bit32u conv_4xBit8u_to_Bit32u(const Bit8u* buf) +{ + Bit32u ret = 0; + for (int i = 0; i < 4; i++) { + ret |= (buf[i] << (8 * i)); + } + return ret; +} + +Bit16u conv_2xBit8u_to_Bit16u(const Bit8u* buf) +{ + Bit16u ret = 0; + for (int i = 0; i < 2; i++) { + ret |= (buf[i] << (8 * i)); + } + return ret; +} + +void bx_dbg_record_command(char* path_quoted) +{ + // skip beginning double quote + if (path_quoted[0] == '"') + path_quoted++; + + // null out ending quote + int len = strlen(path_quoted); + if (path_quoted[len - 1] == '"') + path_quoted[len - 1] = '\0'; + + bx_dbg.record_io = fopen(path_quoted, "w"); + if (bx_dbg.record_io) + dbg_printf("IO record file '%s' opened\n", path_quoted); + else + dbg_printf("Error opening '%s' for writing\n", path_quoted); +} + +static FILE* playback_file = 0; + +struct playback_entry_t +{ + char command[100]; + Bit32u argument; + + void trigger(); +}; + +static playback_entry_t playback_entry; +static Bit64u last_playback_time = 0; +static int playback_timer_index = -1; + +void playback_function(void* this_ptr) +{ + ((playback_entry_t*)this_ptr)->trigger(); +} + +static void enter_playback_entry() +{ + static const int playback_buf_size = 100; + char playback_buf[playback_buf_size]; + if (!fgets(playback_buf, playback_buf_size, playback_file)) + return; + + Bit64u time; + if (sscanf(playback_buf, "%s " FMT_LL "d %x", playback_entry.command, &time, &playback_entry.argument) != 3) { + dbg_printf("Parse error in playback string '%s'\n", playback_buf); + return; + } + + Bit64u diff = time - last_playback_time; + last_playback_time = time; + + if (time < last_playback_time) { + BX_PANIC(("Negative diff in playback")); + } else if (diff == 0) { + playback_entry.trigger(); + } else { + if (playback_timer_index >= 0) + bx_pc_system.activate_timer_ticks(playback_timer_index, diff, 0); + else + playback_timer_index = bx_pc_system.register_timer_ticks(&playback_entry, playback_function, diff, 0, 1, "debug.playback"); + } +} + +void playback_entry_t::trigger() +{ + if (!strcmp("gen_scancode", command)) { + DEV_kbd_gen_scancode(argument); + } else { + dbg_printf("Unknown playback command '%s'\n", command); + return; + } + enter_playback_entry(); +} + +void bx_dbg_playback_command(char* path_quoted) +{ + // skip beginning double quote + if (path_quoted[0] == '"') + path_quoted++; + + // null out ending quote + int len = strlen(path_quoted); + if (path_quoted[len - 1] == '"') + path_quoted[len - 1] = '\0'; + + playback_file = fopen(path_quoted, "r"); + if (playback_file) { + dbg_printf("Playback from '%s'\n", path_quoted); + last_playback_time = 0; + dbg_printf("playback times relative from " FMT_LL "d\n", + bx_pc_system.time_ticks()); + enter_playback_entry(); + } else { + dbg_printf("Error opening '%s' for reading\n", path_quoted); + } +} + +// toggles mode switch breakpoint +void bx_dbg_modebp_command() +{ + BX_CPU(dbg_cpu)->mode_break = !BX_CPU(dbg_cpu)->mode_break; + dbg_printf("mode switch break %s\n", + BX_CPU(dbg_cpu)->mode_break ? "enabled" : "disabled"); +} + +bx_bool bx_dbg_read_linear(unsigned which_cpu, bx_address laddr, unsigned len, Bit8u *buf) +{ + unsigned remainsInPage; + bx_phy_address paddr; + unsigned read_len; + bx_bool paddr_valid; + +next_page: + remainsInPage = 0x1000 - PAGE_OFFSET(laddr); + read_len = (remainsInPage < len) ? remainsInPage : len; + + paddr_valid = BX_CPU(which_cpu)->dbg_xlate_linear2phy(laddr, &paddr); + if (paddr_valid) { + if (! BX_MEM(0)->dbg_fetch_mem(BX_CPU(which_cpu), paddr, read_len, buf)) { + dbg_printf("bx_dbg_read_linear: physical memory read error (phy=0x" FMT_PHY_ADDRX ", lin=0x" FMT_ADDRX ")\n", paddr, laddr); + return 0; + } + } + else { + dbg_printf("bx_dbg_read_linear: physical address not available for linear 0x" FMT_ADDRX "\n", laddr); + return 0; + } + + /* check for access across multiple pages */ + if (remainsInPage < len) + { + laddr += read_len; + len -= read_len; + buf += read_len; + goto next_page; + } + + return 1; +} + +// where +// stack trace: ebp -> old ebp +// return eip at ebp + 4 +void bx_dbg_where_command() +{ + if (!BX_CPU(dbg_cpu)->protected_mode()) { + dbg_printf("'where' only supported in protected mode\n"); + return; + } + if (BX_CPU(dbg_cpu)->get_segment_base(BX_SEG_REG_SS) != 0) { + dbg_printf("non-zero stack base\n"); + return; + } + Bit32u bp = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_EBP); + bx_address ip = BX_CPU(dbg_cpu)->get_instruction_pointer(); + dbg_printf("(%d) 0x%08x\n", dbg_cpu, ip); + for (int i = 1; i < 50; i++) { + // Up + bx_phy_address paddr; + Bit8u buf[4]; + + // bp = [bp]; + bx_bool paddr_valid = BX_CPU(dbg_cpu)->dbg_xlate_linear2phy(bp, &paddr); + if (paddr_valid) { + if (BX_MEM(0)->dbg_fetch_mem(BX_CPU(dbg_cpu), paddr, 4, buf)) { + bp = conv_4xBit8u_to_Bit32u(buf); + } else { + dbg_printf("(%d) Physical memory read error (BP)\n", i); + break; + } + } else { + dbg_printf("(%d) Could not translate linear address (BP)\n", i); + break; + } + + // ip = [bp + 4]; + paddr_valid = BX_CPU(dbg_cpu)->dbg_xlate_linear2phy(bp + 4, &paddr); + if (paddr_valid) { + if (BX_MEM(0)->dbg_fetch_mem(BX_CPU(dbg_cpu), paddr, 4, buf)) { + ip = conv_4xBit8u_to_Bit32u(buf); + } else { + dbg_printf("(%d) Physical memory read error (IP)\n", i); + break; + } + } else { + dbg_printf("(%d) Could not translate linear address (IP)\n", i); + break; + } + + // Print + dbg_printf("(%d) 0x%08x\n", i, ip); + } +} + +void bx_dbg_print_string_command(bx_address start_addr) +{ + dbg_printf("0x%08x: ", start_addr); + for (int i = 0; ; i++) { + Bit8u buf = 0; + if (! bx_dbg_read_linear(dbg_cpu, start_addr+i, 1, &buf)) break; + if (buf == 0) break; + if (isgraph(buf) || buf == 0x20) + dbg_printf("%c", buf); + else + dbg_printf("\\%d", buf); + } + dbg_printf("\n"); +} + +static void dbg_print_guard_found(unsigned cpu_mode, Bit32u cs, bx_address eip, bx_address laddr) +{ +#if BX_SUPPORT_X86_64 + if (cpu_mode == BX_MODE_LONG_64) { + dbg_printf("0x%04x:" FMT_ADDRX " (0x" FMT_ADDRX ")", cs, eip, laddr); + return; + } +#endif + + if (cpu_mode >= BX_MODE_IA32_PROTECTED) + dbg_printf("%04x:%08x (0x%08x)", cs, (unsigned) eip, (unsigned) laddr); + else // real or v8086 mode + dbg_printf("%04x:%04x (0x%08x)", cs, (unsigned) eip, (unsigned) laddr); +} + +void bx_dbg_xlate_address(bx_lin_address laddr) +{ + bx_phy_address paddr; + laddr &= BX_CONST64(0xfffffffffffff000); + + bx_bool paddr_valid = BX_CPU(dbg_cpu)->dbg_xlate_linear2phy(laddr, &paddr, 1); + if (paddr_valid) { + dbg_printf("linear page 0x" FMT_ADDRX " maps to physical page 0x" FMT_PHY_ADDRX "\n", laddr, paddr); + } + else { + dbg_printf("physical address not available for linear 0x" FMT_ADDRX "\n", laddr); + } +} + +unsigned dbg_show_mask = 0; + +#define BX_DBG_SHOW_CALLRET (Flag_call|Flag_ret) +#define BX_DBG_SHOW_SOFTINT (Flag_softint) +#define BX_DBG_SHOW_EXTINT (Flag_intsig) +#define BX_DBG_SHOW_IRET (Flag_iret) +#define BX_DBG_SHOW_INT (Flag_softint|Flag_iret|Flag_intsig) +#define BX_DBG_SHOW_MODE (Flag_mode) + +void bx_dbg_show_command(const char* arg) +{ + if(arg) { + if (!strcmp(arg, "mode")) { + if (dbg_show_mask & BX_DBG_SHOW_MODE) { + dbg_show_mask &= ~BX_DBG_SHOW_MODE; + dbg_printf("show mode switch: OFF\n"); + } else { + dbg_show_mask |= BX_DBG_SHOW_MODE; + dbg_printf("show mode switch: ON\n"); + } + } else if (!strcmp(arg, "int")) { + if (dbg_show_mask & BX_DBG_SHOW_INT) { + dbg_show_mask &= ~BX_DBG_SHOW_INT; + dbg_printf("show interrupts tracing (extint/softint/iret): OFF\n"); + } else { + dbg_show_mask |= BX_DBG_SHOW_INT; + dbg_printf("show interrupts tracing (extint/softint/iret): ON\n"); + } + } else if (!strcmp(arg, "extint")) { + if (dbg_show_mask & BX_DBG_SHOW_EXTINT) { + dbg_show_mask &= ~BX_DBG_SHOW_EXTINT; + dbg_printf("show external interrupts: OFF\n"); + } else { + dbg_show_mask |= BX_DBG_SHOW_EXTINT; + dbg_printf("show external interrupts: ON\n"); + } + } else if (!strcmp(arg, "softint")) { + if (dbg_show_mask & BX_DBG_SHOW_SOFTINT) { + dbg_show_mask &= ~BX_DBG_SHOW_SOFTINT; + dbg_printf("show software interrupts: OFF\n"); + } else { + dbg_show_mask |= BX_DBG_SHOW_SOFTINT; + dbg_printf("show software interrupts: ON\n"); + } + } else if (!strcmp(arg, "iret")) { + if (dbg_show_mask & BX_DBG_SHOW_IRET) { + dbg_show_mask &= ~BX_DBG_SHOW_IRET; + dbg_printf("show iret: OFF\n"); + } else { + dbg_show_mask |= BX_DBG_SHOW_IRET; + dbg_printf("show iret: ON\n"); + } + } else if(!strcmp(arg,"call")) { + if (dbg_show_mask & BX_DBG_SHOW_CALLRET) { + dbg_show_mask &= ~BX_DBG_SHOW_CALLRET; + dbg_printf("show calls/returns: OFF\n"); + } else { + dbg_show_mask |= BX_DBG_SHOW_CALLRET; + dbg_printf("show calls/returns: ON\n"); + } + } else if(!strcmp(arg,"off")) { + dbg_show_mask = 0x0; + dbg_printf("Disable all show flags\n"); + } else if(!strcmp(arg,"dbg-all")) { + bx_dbg.interrupts = 1; + bx_dbg.exceptions = 1; + bx_dbg.debugger = 1; + /* bx_dbg.record_io = 1; this is a pointer .. somewhere */ + dbg_printf("Turned ON all bx_dbg flags\n"); + return; + } else if(!strcmp(arg,"dbg-none")) { + bx_dbg.interrupts = 0; + bx_dbg.exceptions = 0; + bx_dbg.debugger = 0; + /* bx_dbg.record_io = 0; this is a pointer .. somewhere */ + dbg_printf("Turned OFF all bx_dbg flags\n"); + return; + } else if(!strcmp(arg,"vga")){ + DEV_vga_refresh(); + return; + } else { + dbg_printf("Unrecognized arg: %s (only 'mode', 'int', 'softint', 'extint', 'iret', 'call', 'off', 'dbg-all' and 'dbg-none' are valid)\n", arg); + return; + } + } + + if (dbg_show_mask) { + dbg_printf("show mask is:"); + if (dbg_show_mask & BX_DBG_SHOW_CALLRET) + dbg_printf(" call"); + if (dbg_show_mask & BX_DBG_SHOW_SOFTINT) + dbg_printf(" softint"); + if (dbg_show_mask & BX_DBG_SHOW_EXTINT) + dbg_printf(" extint"); + if (dbg_show_mask & BX_DBG_SHOW_IRET) + dbg_printf(" iret"); + if (dbg_show_mask & BX_DBG_SHOW_MODE) + dbg_printf(" mode"); + dbg_printf("\n"); + } + else { + dbg_printf("show mask is: 0\n"); + } +} + +void bx_dbg_show_param_command(const char *param) +{ + dbg_printf("show param name: <%s>\n", param); + bx_param_c *node = SIM->get_param(param, SIM->get_bochs_root()); + if (node) { + print_tree(node, 0); + } + else { + node = SIM->get_param(param, dbg_cpu_list); + if (node) + print_tree(node, 0); + else + dbg_printf("can't find param <%s> in global or default CPU tree\n", param); + } +} + +// return non zero to cause a stop +int bx_dbg_show_symbolic(void) +{ + static unsigned last_cpu_mode = 0; + static bx_address last_cr3 = 0; + + /* modes & address spaces */ + if (dbg_show_mask & BX_DBG_SHOW_MODE) { + if(BX_CPU(dbg_cpu)->get_cpu_mode() != last_cpu_mode) { + dbg_printf (FMT_TICK ": switched from '%s' to '%s'\n", + bx_pc_system.time_ticks(), + cpu_mode_string(last_cpu_mode), + cpu_mode_string(BX_CPU(dbg_cpu)->get_cpu_mode())); + } + + if(last_cr3 != BX_CPU(dbg_cpu)->cr3) + dbg_printf(FMT_TICK ": address space switched. CR3: 0x" FMT_PHY_ADDRX "\n", + bx_pc_system.time_ticks(), BX_CPU(dbg_cpu)->cr3); + } + + /* interrupts */ + if (dbg_show_mask & BX_DBG_SHOW_SOFTINT) { + if(BX_CPU(dbg_cpu)->show_flag & Flag_softint) { + dbg_printf(FMT_TICK ": softint ", bx_pc_system.time_ticks()); + dbg_print_guard_found(BX_CPU(dbg_cpu)->get_cpu_mode(), + BX_CPU(dbg_cpu)->guard_found.cs, BX_CPU(dbg_cpu)->guard_found.eip, + BX_CPU(dbg_cpu)->guard_found.laddr); + dbg_printf("\n"); + } + } + + if (dbg_show_mask & BX_DBG_SHOW_EXTINT) { + if((BX_CPU(dbg_cpu)->show_flag & Flag_intsig) && !(BX_CPU(dbg_cpu)->show_flag & Flag_softint)) { + dbg_printf(FMT_TICK ": exception (not softint) ", bx_pc_system.time_ticks()); + dbg_print_guard_found(BX_CPU(dbg_cpu)->get_cpu_mode(), + BX_CPU(dbg_cpu)->guard_found.cs, BX_CPU(dbg_cpu)->guard_found.eip, + BX_CPU(dbg_cpu)->guard_found.laddr); + dbg_printf("\n"); + } + } + + if (dbg_show_mask & BX_DBG_SHOW_IRET) { + if(BX_CPU(dbg_cpu)->show_flag & Flag_iret) { + dbg_printf(FMT_TICK ": iret ", bx_pc_system.time_ticks()); + dbg_print_guard_found(BX_CPU(dbg_cpu)->get_cpu_mode(), + BX_CPU(dbg_cpu)->guard_found.cs, BX_CPU(dbg_cpu)->guard_found.eip, + BX_CPU(dbg_cpu)->guard_found.laddr); + dbg_printf("\n"); + } + } + + /* calls */ + if (dbg_show_mask & BX_DBG_SHOW_CALLRET) + { + if(BX_CPU(dbg_cpu)->show_flag & Flag_call) { + bx_phy_address phy = 0; + bx_bool valid = BX_CPU(dbg_cpu)->dbg_xlate_linear2phy(BX_CPU(dbg_cpu)->guard_found.laddr, &phy); + dbg_printf(FMT_TICK ": call ", bx_pc_system.time_ticks()); + dbg_print_guard_found(BX_CPU(dbg_cpu)->get_cpu_mode(), + BX_CPU(dbg_cpu)->guard_found.cs, BX_CPU(dbg_cpu)->guard_found.eip, + BX_CPU(dbg_cpu)->guard_found.laddr); + if (!valid) dbg_printf(" phys not valid"); + else { + dbg_printf(" (phy: 0x" FMT_PHY_ADDRX ") %s", phy, + bx_dbg_symbolic_address(BX_CPU(dbg_cpu)->cr3 >> 12, + BX_CPU(dbg_cpu)->guard_found.eip, + BX_CPU(dbg_cpu)->guard_found.laddr - BX_CPU(dbg_cpu)->guard_found.eip)); + } + dbg_printf("\n"); + } + } + + last_cr3 = BX_CPU(dbg_cpu)->cr3; + last_cpu_mode = BX_CPU(dbg_cpu)->get_cpu_mode(); + BX_CPU(dbg_cpu)->show_flag = 0; + + return 0; +} + +void bx_dbg_print_stack_command(unsigned nwords) +{ + bx_address linear_sp; + unsigned len; + +#if BX_SUPPORT_X86_64 + if (BX_CPU(dbg_cpu)->get_cpu_mode() == BX_MODE_LONG_64) { + linear_sp = BX_CPU(dbg_cpu)->get_reg64(BX_64BIT_REG_RSP); + len = 8; + } + else +#endif + { + if (BX_CPU(dbg_cpu)->sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { + linear_sp = BX_CPU(dbg_cpu)->get_reg32(BX_32BIT_REG_ESP); + len = 4; + } + else { + linear_sp = BX_CPU(dbg_cpu)->get_reg16(BX_16BIT_REG_SP); + len = 2; + } + + linear_sp = BX_CPU(dbg_cpu)->get_laddr(BX_SEG_REG_SS, linear_sp); + } + + Bit8u buf[8]; + + dbg_printf("Stack address size %d\n", len); + + for (unsigned i = 0; i < nwords; i++) { + if (! bx_dbg_read_linear(dbg_cpu, linear_sp, len, buf)) break; +#if BX_SUPPORT_X86_64 + if (len == 8) { + dbg_printf(" | STACK 0x%08x%08x [0x%08x:0x%08x]\n", + GET32H(linear_sp), GET32L(linear_sp), + (unsigned) conv_4xBit8u_to_Bit32u(buf+4), + (unsigned) conv_4xBit8u_to_Bit32u(buf)); + } + else +#endif + { + if (len == 4) { + dbg_printf(" | STACK 0x%08x [0x%08x]\n", + (unsigned) linear_sp, (unsigned) conv_4xBit8u_to_Bit32u(buf)); + } + else { + dbg_printf(" | STACK 0x%04x [0x%04x]\n", + (unsigned) linear_sp, (unsigned) conv_2xBit8u_to_Bit16u(buf)); + } + } + + linear_sp += len; + } +} + +void bx_dbg_print_watchpoints(void) +{ unsigned i; + Bit8u buf[2]; + + // print watch point info + for (i = 0; i < num_read_watchpoints; i++) { + if (BX_MEM(0)->dbg_fetch_mem(BX_CPU(dbg_cpu), read_watchpoint[i].addr, 2, buf)) + dbg_printf("rd 0x"FMT_PHY_ADDRX" len=%d\t\t(%04x)\n", + read_watchpoint[i].addr, read_watchpoint[i].len, (int)buf[0] | ((int)buf[1] << 8)); + else + dbg_printf("rd 0x"FMT_PHY_ADDRX" len=%d\t\t(read error)\n", + read_watchpoint[i].addr, read_watchpoint[i].len); + } + for (i = 0; i < num_write_watchpoints; i++) { + if (BX_MEM(0)->dbg_fetch_mem(BX_CPU(dbg_cpu), write_watchpoint[i].addr, 2, buf)) + dbg_printf("wr 0x"FMT_PHY_ADDRX" len=%d\t\t(%04x)\n", + write_watchpoint[i].addr, write_watchpoint[i].len, (int)buf[0] | ((int)buf[1] << 8)); + else + dbg_printf("rd 0x"FMT_PHY_ADDRX" len=%d\t\t(read error)\n", + write_watchpoint[i].addr, write_watchpoint[i].len); + } +} + +void bx_dbg_watch(int type, bx_phy_address address, Bit32u len) +{ + if (type == BX_READ) { + if (num_read_watchpoints == BX_DBG_MAX_WATCHPONTS) { + dbg_printf("Too many read watchpoints (%d)\n", BX_DBG_MAX_WATCHPONTS); + return; + } + read_watchpoint[num_read_watchpoints].addr = address; + read_watchpoint[num_read_watchpoints].len = len; + num_read_watchpoints++; + dbg_printf("read watchpoint at 0x" FMT_PHY_ADDRX " len=%d inserted\n", address, len); + } + else if (type == BX_WRITE) { + if (num_write_watchpoints == BX_DBG_MAX_WATCHPONTS) { + dbg_printf("Too many write watchpoints (%d)\n", BX_DBG_MAX_WATCHPONTS); + return; + } + write_watchpoint[num_write_watchpoints].addr = address; + write_watchpoint[num_write_watchpoints].len = len; + num_write_watchpoints++; + dbg_printf("write watchpoint at 0x" FMT_PHY_ADDRX " len=%d inserted\n", address, len); + } + else { + dbg_printf("bx_dbg_watch: broken watchpoint type"); + } +} + +void bx_dbg_unwatch_all() +{ + num_read_watchpoints = num_write_watchpoints = 0; + dbg_printf("All watchpoints removed\n"); +} + +void bx_dbg_unwatch(bx_phy_address address) +{ unsigned i; + for (i=0; iguard_found.guard_found = 0; + BX_CPU(cpu)->guard_found.icount = 0; + BX_CPU(cpu)->guard_found.time_tick = bx_pc_system.time_ticks(); + } + + // update gui (disable continue command, enable stop command, etc.) + sim_running->set(1); + SIM->refresh_ci(); + + // use simulation mode while executing instructions. When the prompt + // is printed, we will return to config mode. + SIM->set_display_mode(DISP_MODE_SIM); + + bx_guard.interrupt_requested = 0; + int stop = 0; + int which = -1; + while (!stop && !bx_guard.interrupt_requested) { + // the quantum is an arbitrary number of cycles to run in each + // processor. In SMP mode, when this limit is reached, the + // cpu_loop exits so that another processor can be simulated + // for a few cycles. With a single processor, the quantum + // setting should have no effect, although a low setting does + // lead to poor performance because cpu_loop is returning and + // getting called again, over and over. + +#define BX_DBG_DEFAULT_ICOUNT_QUANTUM 5 + + Bit32u quantum = (BX_SMP_PROCESSORS>1) ? BX_DBG_DEFAULT_ICOUNT_QUANTUM : 0; + Bit32u max_executed = 0; + for (cpu=0; cpu < BX_SMP_PROCESSORS; cpu++) { + Bit64u cpu_icount = BX_CPU(cpu)->guard_found.icount; + BX_CPU(cpu)->cpu_loop(quantum); + Bit32u executed = BX_CPU(cpu)->guard_found.icount - cpu_icount; + if (executed > max_executed) max_executed = executed; + // set stop flag if a guard found other than icount or halted + unsigned found = BX_CPU(cpu)->guard_found.guard_found; + stop_reason_t reason = (stop_reason_t) BX_CPU(cpu)->stop_reason; + if (found || (reason != STOP_NO_REASON && reason != STOP_CPU_HALTED)) { + stop = 1; + which = cpu; + } + // even if stop==1, finish cycling through all processors. + // "which" remembers which cpu set the stop flag. If multiple + // cpus set stop, too bad. + } + +#if BX_SUPPORT_SMP + // increment time tick only after all processors have had their chance. + if (BX_SMP_PROCESSORS > 1) { + // potential deadlock if all processors are halted. Then + // max_executed will be 0, tick will be incremented by zero, and + // there will never be a timed event to wake them up. To avoid this, + // always tick by a minimum of 1. + if (max_executed < 1) max_executed=1; + + BX_TICKN(max_executed); + } +#endif + } + + sim_running->set(0); + SIM->refresh_ci(); + + // (mch) hack + DEV_vga_refresh(); + + BX_INSTR_DEBUG_PROMPT(); + bx_dbg_print_guard_results(); + + if (watchpoint_continue && (BX_CPU(which)->stop_reason == STOP_READ_WATCH_POINT || + BX_CPU(which)->stop_reason == STOP_WRITE_WATCH_POINT)) + goto one_more; +} + +void bx_dbg_stepN_command(int cpu, Bit32u count) +{ + if (cpu != -1 && cpu >= BX_SMP_PROCESSORS) { + dbg_printf("Error: stepN: unknown cpu=%d\n", cpu); + return; + } + + if (count == 0) { + dbg_printf("Error: stepN: count=0\n"); + return; + } + + // use simulation mode while executing instructions. When the prompt + // is printed, we will return to config mode. + SIM->set_display_mode(DISP_MODE_SIM); + + // reset guard counters for all CPUs + for (unsigned n=0; n < BX_SMP_PROCESSORS; n++) { + BX_CPU(n)->guard_found.icount = 0; + BX_CPU(n)->guard_found.time_tick = bx_pc_system.time_ticks(); + } + + if (cpu >= 0 || BX_SUPPORT_SMP==0) { + bx_guard.interrupt_requested = 0; + BX_CPU(cpu)->guard_found.guard_found = 0; + BX_CPU(cpu)->cpu_loop(count); + } +#if BX_SUPPORT_SMP + else { + int stop = 0; + // for now, step each CPU one instruction at a time + for (unsigned cycle=0; !stop && cycle < count; cycle++) { + for (unsigned ncpu=0; ncpu < BX_SMP_PROCESSORS; ncpu++) { + bx_guard.interrupt_requested = 0; + BX_CPU(ncpu)->guard_found.guard_found = 0; + BX_CPU(ncpu)->cpu_loop(1); + // set stop flag if a guard found other than icount or halted + unsigned found = BX_CPU(ncpu)->guard_found.guard_found; + stop_reason_t reason = (stop_reason_t) BX_CPU(ncpu)->stop_reason; + if (found || (reason != STOP_NO_REASON && reason != STOP_CPU_HALTED)) + stop = 1; + } + + // when (BX_SMP_PROCESSORS == 1) ticks are handled inside the cpu loop + if (BX_SMP_PROCESSORS > 1) BX_TICK1(); + } + } +#endif + + BX_INSTR_DEBUG_PROMPT(); + bx_dbg_print_guard_results(); +} + +void bx_dbg_disassemble_current(int which_cpu, int print_time) +{ + bx_phy_address phy; + + if (which_cpu < 0) { + // iterate over all of them. + for (int i=0; idbg_xlate_linear2phy(BX_CPU(which_cpu)->guard_found.laddr, &phy); + if (! phy_valid) { + dbg_printf("(%u).[" FMT_LL "d] ??? (physical address not available)\n", which_cpu, bx_pc_system.time_ticks()); + return; + } + + if (bx_dbg_read_linear(which_cpu, BX_CPU(which_cpu)->guard_found.laddr, 16, bx_disasm_ibuf)) + { + unsigned ilen = bx_disassemble.disasm(IS_CODE_32(BX_CPU(which_cpu)->guard_found.code_32_64), + IS_CODE_64(BX_CPU(which_cpu)->guard_found.code_32_64), + BX_CPU(which_cpu)->get_segment_base(BX_SEG_REG_CS), + BX_CPU(which_cpu)->guard_found.eip, bx_disasm_ibuf, bx_disasm_tbuf); + + // Note: it would be nice to display only the modified registers here, the easy + // way out I have thought of would be to keep a prev_eax, prev_ebx, etc copies + // in each cpu description (see cpu/cpu.h) and update/compare those "prev" values + // from here. (eks) + if(BX_CPU(which_cpu)->trace_reg) + bx_dbg_info_registers_command(BX_INFO_GENERAL_PURPOSE_REGS); + + if (print_time) + dbg_printf("(%u).[" FMT_LL "d] ", which_cpu, bx_pc_system.time_ticks()); + else + dbg_printf("(%u) ", which_cpu); + + if (BX_CPU(which_cpu)->protected_mode()) { + dbg_printf("[0x"FMT_PHY_ADDRX"] %04x:" FMT_ADDRX " (%s): ", + phy, BX_CPU(which_cpu)->guard_found.cs, + BX_CPU(which_cpu)->guard_found.eip, + bx_dbg_symbolic_address(BX_CPU(which_cpu)->cr3 >> 12, + BX_CPU(which_cpu)->guard_found.eip, + BX_CPU(which_cpu)->get_segment_base(BX_SEG_REG_CS))); + } + else { // Real & V86 mode + dbg_printf("[0x"FMT_PHY_ADDRX"] %04x:%04x (%s): ", + phy, BX_CPU(which_cpu)->guard_found.cs, + (unsigned) BX_CPU(which_cpu)->guard_found.eip, + bx_dbg_symbolic_address_16bit(BX_CPU(which_cpu)->guard_found.eip, + BX_CPU(which_cpu)->sregs[BX_SEG_REG_CS].selector.value)); + } + dbg_printf("%-25s ; ", bx_disasm_tbuf); + for (unsigned j=0; jguard_found.guard_found; + if (! found) { /* ... */ } +#if (BX_DBG_MAX_VIR_BPOINTS > 0) + else if (found & BX_DBG_GUARD_IADDR_VIR) { + i = BX_CPU(cpu)->guard_found.iaddr_index; + dbg_printf("(%u) Breakpoint %u, in "); + dbg_print_guard_found(BX_CPU(dbg_cpu)->get_cpu_mode(), + BX_CPU(cpu)->guard_found.cs, BX_CPU(cpu)->guard_found.eip, + BX_CPU(cpu)->guard_found.laddr); + dbg_printf("\n"); + } +#endif +#if (BX_DBG_MAX_LIN_BPOINTS > 0) + else if (found & BX_DBG_GUARD_IADDR_LIN) { + i = BX_CPU(cpu)->guard_found.iaddr_index; + if (bx_guard.iaddr.lin[i].bpoint_id != 0) + dbg_printf("(%u) Breakpoint %u, 0x" FMT_ADDRX " in ?? ()\n", + cpu, + bx_guard.iaddr.lin[i].bpoint_id, + BX_CPU(cpu)->guard_found.laddr); + } +#endif +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + else if (found & BX_DBG_GUARD_IADDR_PHY) { + i = BX_CPU(cpu)->guard_found.iaddr_index; + dbg_printf("(%u) Breakpoint %u, 0x" FMT_ADDRX " in ?? ()\n", + cpu, + bx_guard.iaddr.phy[i].bpoint_id, + BX_CPU(cpu)->guard_found.laddr); + } +#endif + switch(BX_CPU(cpu)->stop_reason) { + case STOP_NO_REASON: + case STOP_CPU_HALTED: + break; + case STOP_TIME_BREAK_POINT: + dbg_printf("(%u) Caught time breakpoint\n", cpu); + break; + case STOP_READ_WATCH_POINT: + dbg_printf("(%u) Caught read watch point at 0x" FMT_PHY_ADDRX "\n", cpu, BX_CPU(cpu)->watchpoint); + break; + case STOP_WRITE_WATCH_POINT: + dbg_printf("(%u) Caught write watch point at 0x" FMT_PHY_ADDRX "\n", cpu, BX_CPU(cpu)->watchpoint); + break; + case STOP_MAGIC_BREAK_POINT: + dbg_printf("(%u) Magic breakpoint\n", cpu); + break; + case STOP_MODE_BREAK_POINT: + dbg_printf("(%u) Caught mode switch breakpoint switching to '%s'\n", + cpu, cpu_mode_string(BX_CPU(cpu)->get_cpu_mode())); + break; + default: + dbg_printf("Error: (%u) print_guard_results: guard_found ? (stop reason %u)\n", + cpu, BX_CPU(cpu)->stop_reason); + } + + if (bx_debugger.auto_disassemble) { + if (cpu==0) { + // print this only once + dbg_printf("Next at t=" FMT_LL "d\n", bx_pc_system.time_ticks()); + } + bx_dbg_disassemble_current(cpu, 0); // one cpu, don't print time + } + } +#if 0 + // print the TSC value for every CPU + for (cpu=0; cputsc); + } +#endif +} + +void bx_dbg_breakpoint_changed(void) +{ +#if (BX_DBG_MAX_VIR_BPOINTS > 0) + if (bx_guard.iaddr.num_virtual) + bx_guard.guard_for |= BX_DBG_GUARD_IADDR_VIR; + else + bx_guard.guard_for &= ~BX_DBG_GUARD_IADDR_VIR; +#endif + +#if (BX_DBG_MAX_LIN_BPOINTS > 0) + if (bx_guard.iaddr.num_linear) + bx_guard.guard_for |= BX_DBG_GUARD_IADDR_LIN; + else + bx_guard.guard_for &= ~BX_DBG_GUARD_IADDR_LIN; +#endif + +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + if (bx_guard.iaddr.num_physical) + bx_guard.guard_for |= BX_DBG_GUARD_IADDR_PHY; + else + bx_guard.guard_for &= ~BX_DBG_GUARD_IADDR_PHY; +#endif +} + +void bx_dbg_en_dis_breakpoint_command(unsigned handle, bx_bool enable) +{ +#if (BX_DBG_MAX_VIR_BPOINTS > 0) + if (bx_dbg_en_dis_vbreak(handle, enable)) + goto done; +#endif + +#if (BX_DBG_MAX_LIN_BPOINTS > 0) + if (bx_dbg_en_dis_lbreak(handle, enable)) + goto done; +#endif + +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + if (bx_dbg_en_dis_pbreak(handle, enable)) + goto done; +#endif + + dbg_printf("Error: breakpoint %u not found.\n", handle); + return; + +done: + bx_dbg_breakpoint_changed(); +} + +bx_bool bx_dbg_en_dis_pbreak(unsigned handle, bx_bool enable) +{ +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + // see if breakpoint is a physical breakpoint + for (unsigned i=0; i 0) + // see if breakpoint is a linear breakpoint + for (unsigned i=0; i 0) + // see if breakpoint is a virtual breakpoint + for (unsigned i=0; i 0) + if (bx_dbg_del_vbreak(handle)) + goto done; +#endif + +#if (BX_DBG_MAX_LIN_BPOINTS > 0) + if (bx_dbg_del_lbreak(handle)) + goto done; +#endif + +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + if (bx_dbg_del_pbreak(handle)) + goto done; +#endif + + dbg_printf("Error: breakpoint %u not found.\n", handle); + return; + +done: + bx_dbg_breakpoint_changed(); +} + +bx_bool bx_dbg_del_pbreak(unsigned handle) +{ +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + // see if breakpoint is a physical breakpoint + for (unsigned i=0; i 0) + // see if breakpoint is a linear breakpoint + for (unsigned i=0; i 0) + // see if breakpoint is a virtual breakpoint + for (unsigned i=0; i 0) + if (bk != bkRegular) { + dbg_printf("Error: vbreak of this kind not implemented yet.\n"); + return -1; + } + + if (bx_guard.iaddr.num_virtual >= BX_DBG_MAX_VIR_BPOINTS) { + dbg_printf("Error: no more virtual breakpoint slots left.\n"); + dbg_printf("Error: see BX_DBG_MAX_VIR_BPOINTS.\n"); + return -1; + } + + bx_guard.iaddr.vir[bx_guard.iaddr.num_virtual].cs = cs; + bx_guard.iaddr.vir[bx_guard.iaddr.num_virtual].eip = eip; + bx_guard.iaddr.vir[bx_guard.iaddr.num_virtual].bpoint_id = bx_debugger.next_bpoint_id++; + int BpId = (int)bx_guard.iaddr.vir[bx_guard.iaddr.num_virtual].bpoint_id; + bx_guard.iaddr.vir[bx_guard.iaddr.num_virtual].enabled=1; + bx_guard.iaddr.num_virtual++; + bx_guard.guard_for |= BX_DBG_GUARD_IADDR_VIR; + return BpId; + +#else + dbg_printf("Error: virtual breakpoint support not compiled in.\n"); + dbg_printf("Error: make sure BX_DBG_MAX_VIR_BPOINTS > 0\n"); + return -1; +#endif +} + +int bx_dbg_lbreakpoint_command(BreakpointKind bk, bx_address laddress) +{ +#if (BX_DBG_MAX_LIN_BPOINTS > 0) + if (bk == bkAtIP) { + dbg_printf("Error: lbreak of this kind not implemented yet.\n"); + return -1; + } + + if (bx_guard.iaddr.num_linear >= BX_DBG_MAX_LIN_BPOINTS) { + dbg_printf("Error: no more linear breakpoint slots left.\n"); + dbg_printf("Error: see BX_DBG_MAX_LIN_BPOINTS.\n"); + return -1; + } + + bx_guard.iaddr.lin[bx_guard.iaddr.num_linear].addr = laddress; + int BpId = (bk == bkStepOver) ? 0 : bx_debugger.next_bpoint_id++; + bx_guard.iaddr.lin[bx_guard.iaddr.num_linear].bpoint_id = BpId; + bx_guard.iaddr.lin[bx_guard.iaddr.num_linear].enabled=1; + bx_guard.iaddr.num_linear++; + bx_guard.guard_for |= BX_DBG_GUARD_IADDR_LIN; + return BpId; + +#else + dbg_printf("Error: linear breakpoint support not compiled in.\n"); + dbg_printf("Error: make sure BX_DBG_MAX_LIN_BPOINTS > 0\n"); + return -1; +#endif +} + +int bx_dbg_pbreakpoint_command(BreakpointKind bk, bx_phy_address paddress) +{ +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + if (bk != bkRegular) { + dbg_printf("Error: pbreak of this kind not implemented yet.\n"); + return -1; + } + + if (bx_guard.iaddr.num_physical >= BX_DBG_MAX_PHY_BPOINTS) { + dbg_printf("Error: no more physical breakpoint slots left.\n"); + dbg_printf("Error: see BX_DBG_MAX_PHY_BPOINTS.\n"); + return -1; + } + + bx_guard.iaddr.phy[bx_guard.iaddr.num_physical].addr = paddress; + bx_guard.iaddr.phy[bx_guard.iaddr.num_physical].bpoint_id = bx_debugger.next_bpoint_id++; + int BpId = (int)bx_guard.iaddr.phy[bx_guard.iaddr.num_physical].bpoint_id; + bx_guard.iaddr.phy[bx_guard.iaddr.num_physical].enabled=1; + bx_guard.iaddr.num_physical++; + bx_guard.guard_for |= BX_DBG_GUARD_IADDR_PHY; + return BpId; +#else + dbg_printf("Error: physical breakpoint support not compiled in.\n"); + dbg_printf("Error: make sure BX_DBG_MAX_PHY_BPOINTS > 0\n"); + return -1; +#endif +} + +void bx_dbg_info_bpoints_command(void) +{ + unsigned i; +// Num Type Disp Enb Address What +// 1 breakpoint keep y 0x00010664 in main at temp.c:7 + + dbg_printf("Num Type Disp Enb Address\n"); +#if (BX_DBG_MAX_VIR_BPOINTS > 0) + for (i=0; i 0) + for (i=0; i 0) + for (i=0; idbg_take_dma(); + } + + bx_dbg_batch_dma.this_many = 1; // reset to normal + bx_dbg_post_dma_reports(); // print reports and flush + if (bx_guard.report.dma) + dbg_printf("done\n"); + } + else if (! strcmp(what, "irq")) { + BX_CPU(0)->dbg_take_irq(); + + if (bx_guard.report.irq) + dbg_printf("done\n"); + } + else { + dbg_printf("Error: Take '%s' not understood.\n", what); + } +} + +static void bx_print_char(Bit8u ch) +{ + if (ch < 10) + dbg_printf(" \\%d ", ch); + else if (isprint(ch)) + dbg_printf(" %c ", ch); + else + dbg_printf(" \\x%02X", ch); +} + +void dbg_printf_binary(const char *format, Bit32u data, int bits) +{ + int len = 0; + char num[33]; + + for (unsigned b = 1 << (bits - 1); b; b >>= 1) + num [len++] = (data & b) ? '1' : '0'; + num[len] = 0; + dbg_printf(format, num); +} + +void bx_dbg_examine_command(const char *command, const char *format, bx_bool format_passed, + bx_address addr, bx_bool addr_passed) +{ + unsigned repeat_count, i; + char ch, display_format, unit_size; + bx_bool iteration, memory_dump = false; + unsigned data_size; + Bit8u data8; + Bit16u data16; + Bit32u data32; + unsigned columns, per_line, offset; + bx_bool is_linear; + Bit8u databuf[8]; + + dbg_printf("[bochs]:\n"); + + // If command was the extended "xp" command, meaning eXamine Physical memory, + // then flag memory address as physical, rather than linear. + if (strcmp(command, "xp") == 0) { + is_linear = 0; + } + else { + is_linear = 1; + } + + if (addr_passed==0) + addr = bx_debugger.default_addr; + + if (format_passed==0) { + display_format = bx_debugger.default_display_format; + unit_size = bx_debugger.default_unit_size; + repeat_count = 1; + } + else { + if (format==NULL) { + dbg_printf("dbg_examine: format NULL\n"); + bx_dbg_exit(1); + } + + if (strlen(format) < 2) { + dbg_printf("dbg_examine: invalid format passed.\n"); + bx_dbg_exit(1); + } + + if (format[0] != '/') { + dbg_printf("dbg_examine: '/' is not first char of format.\n"); + bx_dbg_exit(1); + } + + format++; + repeat_count = 0; + ch = *format; + iteration = 0; + + while (ch>='0' && ch<='9') { + iteration = 1; + repeat_count = 10*repeat_count + (ch-'0'); + format++; + ch = *format; + } + + if (iteration==0) { + // if no count given, use default + repeat_count = 1; + } + else if (repeat_count==0) { + // count give, but zero is an error + dbg_printf("dbg_examine: repeat count given but is zero.\n"); + return; + } + + // set up the default display format and unit size parameters + display_format = bx_debugger.default_display_format; + unit_size = bx_debugger.default_unit_size; + + for (i = 0; format[i]; i++) { + switch (ch = format[i]) { + case 'x': // hex + case 'd': // signed decimal + case 'u': // unsigned decimal + case 'o': // octal + case 't': // binary + case 'c': // chars + case 's': // null terminated string + case 'i': // machine instruction + display_format = ch; + break; + + case 'b': // bytes + case 'h': // halfwords (two bytes) + case 'w': // words (4 bytes) + case 'g': // giant words (8 bytes) + unit_size = ch; + break; + + case 'm': // memory dump + memory_dump = true; + break; + + default: + dbg_printf("dbg_examine: invalid format passed. \'%c\'\n", ch); + bx_dbg_exit(1); + break; + } + } + } + + if ((display_format == 'i') || (display_format == 's')) { + dbg_printf("error: dbg_examine: 'i' and 's' formats not supported.\n"); + return; + } + + if (unit_size == 'g') { + dbg_printf("error: dbg_examine: 'g' (8-byte) unit size not supported.\n"); + return; + } + + if (format_passed) { + // store current options as default + bx_debugger.default_display_format = display_format; + bx_debugger.default_unit_size = unit_size; + } + + data_size = 0; + per_line = 0; + offset = 0; + + if (memory_dump) { + if (display_format == 'c') { + // Display character dump in lines of 64 characters + unit_size = 'b'; + data_size = 1; + per_line = 64; + } + else + switch (unit_size) { + case 'b': data_size = 1; per_line = 16; break; + case 'h': data_size = 2; per_line = 8; break; + case 'w': data_size = 4; per_line = 4; break; + //case 'g': data_size = 8; per_line = 2; break; + } + // binary format is quite large + if (display_format == 't') + per_line /= 4; + } + else { + switch (unit_size) { + case 'b': data_size = 1; per_line = 8; break; + case 'h': data_size = 2; per_line = 8; break; + case 'w': data_size = 4; per_line = 4; break; + //case 'g': data_size = 8; per_line = 2; break; + } + } + + columns = per_line + 1; // set current number columns past limit + + for (i=1; i<=repeat_count; i++) { + if (columns > per_line) { + // if not 1st run, need a newline from last line + if (i!=1) + dbg_printf("\n"); + if (memory_dump) + dbg_printf("0x" FMT_ADDRX ":", addr); + else + dbg_printf("0x" FMT_ADDRX " :", addr, offset); + columns = 1; + } + + /* Put a space in the middle of dump, for readability */ + if ((columns - 1) == per_line / 2 + && memory_dump && display_format != 'c') + dbg_printf(" "); + + if (is_linear) { + if (! bx_dbg_read_linear(dbg_cpu, addr, data_size, databuf)) return; + } + else { + // address is already physical address + BX_MEM(0)->dbg_fetch_mem(BX_CPU(dbg_cpu), (bx_phy_address) addr, data_size, databuf); + } + + //FIXME HanishKVC The char display for data to be properly integrated + // so that repeat_count, columns, etc. can be set or used properly. + // Also for data_size of 2 and 4 how to display the individual + // characters i.e in which order to be decided. + switch (data_size) { + case 1: + data8 = databuf[0]; + if (memory_dump) + switch (display_format) { + case 'd': dbg_printf("%03d ", data8); break; + case 'u': dbg_printf("%03u ", data8); break; + case 'o': dbg_printf("%03o ", data8); break; + case 't': dbg_printf_binary("%s ", data8, 8); break; + case 'c': dbg_printf("%c", isprint(data8) ? data8 : '.'); break; + default : dbg_printf("%02X ", data8); break; + } + else + switch (display_format) { + case 'x': dbg_printf("\t0x%02x", (unsigned) data8); break; + case 'd': dbg_printf("\t%d", (int) (Bit8s) data8); break; + case 'u': dbg_printf("\t%u", (unsigned) data8); break; + case 'o': dbg_printf("\t%o", (unsigned) data8); break; + case 't': dbg_printf_binary("\t%s", data8, 8); break; + case 'c': bx_print_char(data8); break; + } + break; + + case 2: + ReadHostWordFromLittleEndian(databuf, data16); + + if (memory_dump) + switch (display_format) { + case 'd': dbg_printf("%05d ", data16); break; + case 'u': dbg_printf("%05u ", data16); break; + case 'o': dbg_printf("%06o ", data16); break; + case 't': dbg_printf_binary("%s ", data16, 16); break; + default : dbg_printf("%04X ", data16); break; + } + else + switch (display_format) { + case 'x': dbg_printf("\t0x%04x", (unsigned) data16); break; + case 'd': dbg_printf("\t%d", (int) (Bit16s) data16); break; + case 'u': dbg_printf("\t%u", (unsigned) data16); break; + case 'o': dbg_printf("\t%o", (unsigned) data16); break; + case 't': dbg_printf_binary("\t%s", data16, 16); break; + case 'c': + bx_print_char(data16>>8); + bx_print_char(data16 & 0xff); + break; + } + break; + + case 4: + ReadHostDWordFromLittleEndian(databuf, data32); + + if (memory_dump) + switch (display_format) { + case 'd': dbg_printf("%10d ", data32); break; + case 'u': dbg_printf("%10u ", data32); break; + case 'o': dbg_printf("%12o ", data32); break; + case 't': dbg_printf_binary("%s ", data32, 32); break; + default : dbg_printf("%08X ", data32); break; + } + else + switch (display_format) { + case 'x': dbg_printf("\t0x%08x", (unsigned) data32); break; + case 'd': dbg_printf("\t%d", (int) (Bit32s) data32); break; + case 'u': dbg_printf("\t%u", (unsigned) data32); break; + case 'o': dbg_printf("\t%o", (unsigned) data32); break; + case 't': dbg_printf_binary("\t%s", data32, 32); break; + case 'c': + bx_print_char(0xff & (data32>>24)); + bx_print_char(0xff & (data32>>16)); + bx_print_char(0xff & (data32>> 8)); + bx_print_char(0xff & (data32>> 0)); + break; + } + break; + } + + addr += data_size; + bx_debugger.default_addr = addr; + columns++; + offset += data_size; + } + dbg_printf("\n"); +} + +Bit32u bx_dbg_lin_indirect(bx_address addr) +{ + Bit8u databuf[4]; + Bit32u result; + + if (! bx_dbg_read_linear(dbg_cpu, addr, 4, databuf)) { + /* bx_dbg_read_linear already printed an error message if it failed */ + return 0; + } + + ReadHostDWordFromLittleEndian(databuf, result); + return result; +} + +Bit32u bx_dbg_phy_indirect(bx_phy_address paddr) +{ + Bit8u databuf[4]; + Bit32u result; + + if (! BX_MEM(0)->dbg_fetch_mem(BX_CPU(dbg_cpu), paddr, 4, databuf)) { + /* dbg_fetch_mem already printed an error message if it failed */ + return 0; + } + + ReadHostDWordFromLittleEndian(databuf, result); + return result; +} + +void bx_dbg_setpmem_command(bx_phy_address paddr, unsigned len, Bit32u val) +{ + Bit8u buf[4]; + + switch (len) { + case 1: + buf[0] = (Bit8u) val; + break; + case 2: + buf[0] = val & 0xff; val >>= 8; + buf[1] = val & 0xff; + break; + case 4: + buf[0] = val & 0xff; val >>= 8; + buf[1] = val & 0xff; val >>= 8; + buf[2] = val & 0xff; val >>= 8; + buf[3] = val & 0xff; + break; + default: + dbg_printf("Error: setpmem: bad length value = %u\n", len); + return; + } + + if (! BX_MEM(0)->dbg_set_mem(paddr, len, buf)) { + dbg_printf("Error: setpmem: could not set memory, out of physical bounds?\n"); + } +} + +void bx_dbg_set_symbol_command(const char *symbol, Bit32u val) +{ + bx_bool is_OK = false; + symbol++; // get past '$' + + if (!strcmp(symbol, "eip")) { + is_OK = BX_CPU(dbg_cpu)->dbg_set_reg(BX_DBG_REG_EIP, val); + } + else if (!strcmp(symbol, "eflags")) { + is_OK = BX_CPU(dbg_cpu)->dbg_set_reg(BX_DBG_REG_EFLAGS, val); + } + else if (!strcmp(symbol, "cpu")) { + if (val >= BX_SMP_PROCESSORS) { + dbg_printf("invalid cpu id number %d\n", val); + return; + } + char cpu_param_name[10]; + sprintf(cpu_param_name, "cpu%d", val); + dbg_cpu_list = (bx_list_c*) SIM->get_param(cpu_param_name, SIM->get_bochs_root()); + dbg_cpu = val; + return; + } + else if (!strcmp(symbol, "synchronous_dma")) { + bx_guard.async.dma = !val; + return; + } + else if (!strcmp(symbol, "synchronous_irq")) { + bx_guard.async.irq = !val; + return; + } + else if (!strcmp(symbol, "event_reports")) { + bx_guard.report.irq = val; + bx_guard.report.a20 = val; + bx_guard.report.io = val; + bx_guard.report.dma = val; + return; + } + else if (!strcmp(symbol, "auto_disassemble")) { + bx_dbg_set_auto_disassemble(val != 0); + return; + } + else { + dbg_printf("Error: set: unrecognized symbol.\n"); + return; + } + + if (!is_OK) { + dbg_printf("Error: could not set register '%s'.\n", symbol); + } +} + +void bx_dbg_query_command(const char *what) +{ + unsigned pending; + + if (! strcmp(what, "pending")) { + pending = BX_CPU(0)->dbg_query_pending(); + + if (pending & BX_DBG_PENDING_DMA) + dbg_printf("pending DMA\n"); + + if (pending & BX_DBG_PENDING_IRQ) + dbg_printf("pending IRQ\n"); + + if (!pending) + dbg_printf("pending none\n"); + + dbg_printf("done\n"); + } + else { + dbg_printf("Error: Query '%s' not understood.\n", what); + } +} + +void bx_dbg_restore_command(const char *param_name, const char *restore_path) +{ + const char *path = (restore_path == NULL) ? "." : restore_path; + dbg_printf("restoring param (%s) state from file (%s/%s)\n", + param_name, path, param_name); + if (! SIM->restore_bochs_param(SIM->get_bochs_root(), path, param_name)) { + dbg_printf("Error: error occured during restore\n"); + } + else { + bx_sr_after_restore_state(); + } +} + +void bx_dbg_disassemble_current(const char *format) +{ + Bit64u addr = bx_dbg_get_laddr(bx_dbg_get_selector_value(BX_DBG_SREG_CS), + BX_CPU(dbg_cpu)->get_instruction_pointer()); + bx_dbg_disassemble_command(format, addr, addr); +} + +void bx_dbg_disassemble_command(const char *format, Bit64u from, Bit64u to) +{ + int numlines = INT_MAX; + + if (from > to) { + Bit64u temp = from; + from = to; + to = temp; + } + + if (format) { + // format always begins with '/' (checked in lexer) + // so we won't bother checking it here second time. + numlines = atoi(format + 1); + if (to == from) + to = BX_MAX_BIT64U; // Disassemble just X lines + } + + unsigned dis_size = bx_debugger.disassemble_size; + if (dis_size == 0) { + dis_size = 16; // until otherwise proven + if (BX_CPU(dbg_cpu)->sregs[BX_SEG_REG_CS].cache.u.segment.d_b) + dis_size = 32; + if (BX_CPU(dbg_cpu)->get_cpu_mode() == BX_MODE_LONG_64) + dis_size = 64; + } + + do { + numlines--; + + if (! bx_dbg_read_linear(dbg_cpu, from, 16, bx_disasm_ibuf)) break; + + unsigned ilen = bx_disassemble.disasm(dis_size==32, dis_size==64, + (bx_address)(-1), (bx_address)(-1), bx_disasm_ibuf, bx_disasm_tbuf); + + const char *Sym=bx_dbg_disasm_symbolic_address((Bit32u)from, 0); + + dbg_printf("%08x: ", (unsigned) from); + dbg_printf("(%20s): ", Sym?Sym:""); + dbg_printf("%-25s ; ", bx_disasm_tbuf); + + for (unsigned j=0; j 0); +} + +void bx_dbg_instrument_command(const char *comm) +{ +#if BX_INSTRUMENTATION + dbg_printf("Command '%s' passed to instrumentation module\n", comm); + BX_INSTR_DEBUG_CMD(comm); +#else + UNUSED(comm); + dbg_printf("Error: instrumentation not enabled.\n"); +#endif +} + +void bx_dbg_doit_command(unsigned n) +{ + // generic command to add temporary hacks to + // for debugging purposes + bx_dbg.interrupts = n; + bx_dbg.exceptions = n; +} + +void bx_dbg_crc_command(bx_phy_address addr1, bx_phy_address addr2) +{ + Bit32u crc1; + + if (addr1 >= addr2) { + dbg_printf("Error: crc32: invalid range\n"); + return; + } + + if (!BX_MEM(0)->dbg_crc32(addr1, addr2, &crc1)) { + dbg_printf("Error: could not crc32 memory\n"); + return; + } + dbg_printf("0x%lx\n", crc1); +} + +void bx_dbg_print_descriptor(Bit32u lo, Bit32u hi) +{ + Bit32u base = ((lo >> 16) & 0xffff) + | ((hi << 16) & 0xff0000) + | (hi & 0xff000000); + Bit32u limit = (hi & 0x000f0000) | (lo & 0xffff); + Bit32u segment = (lo >> 16) & 0xffff; + Bit32u offset = (lo & 0xffff) | (hi & 0xffff0000); + unsigned type = (hi >> 8) & 0xf; + unsigned dpl = (hi >> 13) & 0x3; + unsigned s = (hi >> 12) & 0x1; + unsigned d_b = (hi >> 22) & 0x1; + unsigned g = (hi >> 23) & 0x1; + + // 32-bit trap gate, target=0010:c0108ec4, DPL=0, present=1 + // code segment, base=0000:00cfffff, length=0xffff + if (s) { + // either a code or a data segment. bit 11 (type file MSB) then says + // 0=data segment, 1=code seg + if (type&8) { + dbg_printf("Code segment, base=0x%08x, limit=0x%08x, %s%s%s, %d-bit\n", + base, g ? (limit * 4096 + 4095) : limit, + (type&2)? "Execute/Read" : "Execute-Only", + (type&4)? ", Conforming" : "", + (type&1)? ", Accessed" : "", + d_b ? 32 : 16); + } else { + dbg_printf("Data segment, base=0x%08x, limit=0x%08x, %s%s%s\n", + base, g ? (limit * 4096 + 4095) : limit, + (type&2)? "Read/Write" : "Read-Only", + (type&4)? ", Expand-down" : "", + (type&1)? ", Accessed" : ""); + } + } else { + // types from IA32-devel-guide-3, page 3-15. + static const char *undef = "???"; + static const char *type_names[16] = { + undef, + "16-Bit TSS (available)", + "LDT", + "16-Bit TSS (Busy)", + "16-Bit Call Gate", + "Task Gate", + "16-Bit Interrupt Gate", + "16-Bit Trap Gate", + undef, + "32-Bit TSS (Available)", + undef, + "32-Bit TSS (Busy)", + "32-Bit Call Gate", + undef, + "32-Bit Interrupt Gate", + "32-Bit Trap Gate" + }; + dbg_printf("%s ", type_names[type]); + // only print more if type is valid + if (type_names[type] == undef) { + dbg_printf("descriptor hi=0x%08x, lo=0x%08x", hi, lo); + } else { + // for call gates, print segment:offset and parameter count p.4-15 + // for task gate, only present,dpl,TSS segment selector exist. p.5-13 + // for interrupt gate, segment:offset,p,dpl + // for trap gate, segment:offset,p,dpl + // for TSS, base address and segment limit + switch (type) { + case BX_SYS_SEGMENT_AVAIL_286_TSS: + case BX_SYS_SEGMENT_BUSY_286_TSS: + case BX_SYS_SEGMENT_AVAIL_386_TSS: + case BX_SYS_SEGMENT_BUSY_386_TSS: + dbg_printf("at 0x%08x, length 0x%05x", base, limit); + break; + case BX_SYS_SEGMENT_LDT: + // it's an LDT. not much to print. + break; + default: + // task, int, trap, or call gate. + dbg_printf("target=0x%04x:0x%08x, DPL=%d", segment, offset, dpl); + break; + } + } + dbg_printf("\n"); + } +} + +#if BX_SUPPORT_X86_64 +void bx_dbg_print_descriptor64(Bit32u lo1, Bit32u hi1, Bit32u lo2, Bit32u hi2) +{ + Bit32u segment = (lo1 >> 16) & 0xffff; + Bit64u offset = (lo1 & 0xffff) | (hi1 & 0xffff0000) | ((Bit64u)(lo2) << 32); + unsigned type = (hi1 >> 8) & 0xf; + unsigned dpl = (hi1 >> 13) & 0x3; + unsigned s = (hi1 >> 12) & 0x1; + + if (s) { + dbg_printf("bx_dbg_print_descriptor64: only system entries displayed in 64bit mode\n"); + } + else { + static const char *undef = "???"; + static const char *type_names[16] = { + undef, + undef, + "LDT", + undef, + undef, + undef, + undef, + undef, + undef, + "64-Bit TSS (Available)", + undef, + "64-Bit TSS (Busy)", + "64-Bit Call Gate", + undef, + "64-Bit Interrupt Gate", + "64-Bit Trap Gate" + }; + dbg_printf("%s ", type_names[type]); + // only print more if type is valid + if (type_names[type] == undef) { + dbg_printf("\ndescriptor dword2 hi=0x%08x, lo=0x%08x", hi2, lo2); + dbg_printf("\n dword1 hi=0x%08x, lo=0x%08x", hi1, lo1); + } else { + // for call gates, print segment:offset and parameter count p.4-15 + // for task gate, only present,dpl,TSS segment selector exist. p.5-13 + // for interrupt gate, segment:offset,p,dpl + // for trap gate, segment:offset,p,dpl + // for TSS, base address and segment limit + switch (type) { + case BX_SYS_SEGMENT_AVAIL_286_TSS: + case BX_SYS_SEGMENT_BUSY_286_TSS: + case BX_SYS_SEGMENT_AVAIL_386_TSS: + case BX_SYS_SEGMENT_BUSY_386_TSS: + // don't print nothing about 64-bit TSS + break; + case BX_SYS_SEGMENT_LDT: + // it's an LDT. not much to print. + break; + default: + // task, int, trap, or call gate. + dbg_printf("target=0x%04x:"FMT_ADDRX", DPL=%d", segment, offset, dpl); + break; + } + } + dbg_printf("\n"); + } +} +#endif + +void bx_dbg_info_idt_command(unsigned from, unsigned to) +{ + bx_dbg_global_sreg_t idtr; + BX_CPU(dbg_cpu)->dbg_get_idtr(&idtr); + bx_bool all = 0; + + if (to == (unsigned) EMPTY_ARG) { + to = from; + if(from == (unsigned) EMPTY_ARG) { from = 0; to = 255; all = 1; } + } + if (from > 255 || to > 255) { + dbg_printf("IDT entry should be [0-255], 'info idt' command malformed\n"); + return; + } + if (from > to) { + unsigned temp = from; + from = to; + to = temp; + } + +#if BX_SUPPORT_X86_64 + if (BX_CPU(dbg_cpu)->long_mode()) { + dbg_printf("Interrupt Descriptor Table (base=0x" FMT_ADDRX ", limit=%d):\n", idtr.base, idtr.limit); + for (unsigned n = from; n<=to; n++) { + Bit8u entry[16]; + if (16*n + 15 > idtr.limit) break; + if (bx_dbg_read_linear(dbg_cpu, idtr.base + 16*n, 16, entry)) { + dbg_printf("IDT[0x%02x]=", n); + + Bit32u lo1 = (entry[3] << 24) | (entry[2] << 16) | (entry[1] << 8) | (entry[0]); + Bit32u hi1 = (entry[7] << 24) | (entry[6] << 16) | (entry[5] << 8) | (entry[4]); + Bit32u lo2 = (entry[11] << 24) | (entry[10] << 16) | (entry[9] << 8) | (entry[8]); + Bit32u hi2 = (entry[15] << 24) | (entry[14] << 16) | (entry[13] << 8) | (entry[12]); + + bx_dbg_print_descriptor64(lo1, hi1, lo2, hi2); + } + else { + dbg_printf("error: IDTR+16*%d points to invalid linear address 0x" FMT_ADDRX "\n", n, idtr.base); + } + } + } + else +#endif + { + dbg_printf("Interrupt Descriptor Table (base=0x" FMT_ADDRX ", limit=%d):\n", idtr.base, idtr.limit); + for (unsigned n = from; n<=to; n++) { + Bit8u entry[8]; + if (8*n + 7 > idtr.limit) break; + if (bx_dbg_read_linear(dbg_cpu, idtr.base + 8*n, 8, entry)) { + dbg_printf("IDT[0x%02x]=", n); + + Bit32u lo = (entry[3] << 24) | (entry[2] << 16) | (entry[1] << 8) | (entry[0]); + Bit32u hi = (entry[7] << 24) | (entry[6] << 16) | (entry[5] << 8) | (entry[4]); + + bx_dbg_print_descriptor(lo, hi); + } + else { + dbg_printf("error: IDTR+8*%d points to invalid linear address 0x" FMT_ADDRX "\n", n, idtr.base); + } + } + } + + if (all) + dbg_printf("You can list individual entries with 'info idt [NUM]' or groups with 'info idt [NUM] [NUM]'\n"); +} + +void bx_dbg_info_gdt_command(unsigned from, unsigned to) +{ + bx_dbg_global_sreg_t gdtr; + BX_CPU(dbg_cpu)->dbg_get_gdtr(&gdtr); + bx_bool all = 0; + + if (to == (unsigned) EMPTY_ARG) { + to = from; + if(from == (unsigned) EMPTY_ARG) { from = 0; to = 0xffff; all = 1; } + } + if (from > 0xffff || to > 0xffff) { + dbg_printf("GDT entry should be [0-65535], 'info gdt' command malformed\n"); + return; + } + if (from > to) { + unsigned temp = from; + from = to; + to = temp; + } + + dbg_printf("Global Descriptor Table (base=0x" FMT_ADDRX ", limit=%d):\n", gdtr.base, gdtr.limit); + for (unsigned n = from; n<=to; n++) { + Bit8u entry[8]; + if (8*n + 7 > gdtr.limit) break; + if (bx_dbg_read_linear(dbg_cpu, gdtr.base + 8*n, 8, entry)) { + dbg_printf("GDT[0x%02x]=", n); + + Bit32u lo = (entry[3] << 24) | (entry[2] << 16) | (entry[1] << 8) | (entry[0]); + Bit32u hi = (entry[7] << 24) | (entry[6] << 16) | (entry[5] << 8) | (entry[4]); + + bx_dbg_print_descriptor(lo, hi); + } + else { + dbg_printf("error: GDTR+8*%d points to invalid linear address 0x" FMT_ADDRX "\n", + n, gdtr.base); + } + } + if (all) + dbg_printf("You can list individual entries with 'info gdt [NUM]' or groups with 'info gdt [NUM] [NUM]'\n"); +} + +void bx_dbg_info_ldt_command(unsigned from, unsigned to) +{ + bx_address ldtr_base = SIM->get_param_num("LDTR.base", dbg_cpu_list)->get64(); + Bit32u ldtr_limit = SIM->get_param_num("LDTR.limit_scaled", dbg_cpu_list)->get(); + + bx_bool all = 0; + + if (to == (unsigned) EMPTY_ARG) { + to = from; + if(from == (unsigned) EMPTY_ARG) { from = 0; to = 0xffff; all = 1; } + } + if (from > 0xffff || to > 0xffff) { + dbg_printf("LDT entry should be [0-65535], 'info ldt' command malformed\n"); + return; + } + if (from > to) { + unsigned temp = from; + from = to; + to = temp; + } + + dbg_printf("Local Descriptor Table (base=0x" FMT_ADDRX ", limit=%d):\n", ldtr_base, ldtr_limit); + for (unsigned n = from; n<=to; n++) { + Bit8u entry[8]; + if (8*n + 7 > ldtr_limit) break; + if (bx_dbg_read_linear(dbg_cpu, ldtr_base + 8*n, 8, entry)) { + dbg_printf("LDT[0x%02x]=", n); + + Bit32u lo = (entry[3] << 24) | (entry[2] << 16) | (entry[1] << 8) | (entry[0]); + Bit32u hi = (entry[7] << 24) | (entry[6] << 16) | (entry[5] << 8) | (entry[4]); + + bx_dbg_print_descriptor(lo, hi); + } + else { + dbg_printf("error: LDTR+8*%d points to invalid linear address 0x" FMT_ADDRX "\n", + n, ldtr_base); + } + } + if (all) + dbg_printf("You can list individual entries with 'info ldt [NUM]' or groups with 'info ldt [NUM] [NUM]'\n"); +} + +/*form RB list*/ +static const char* bx_dbg_ivt_desc(int intnum) +{ + const char* ret; + switch (intnum) { + case 0x00: ret = "DIVIDE ERROR" ; break; + case 0x01: ret = "SINGLE STEP" ; break; + case 0x02: ret = "NON-MASKABLE INTERRUPT" ; break; + case 0x03: ret = "BREAKPOINT" ; break; + case 0x04: ret = "INT0 DETECTED OVERFLOW" ; break; + case 0x05: ret = "BOUND RANGE EXCEED" ; break; + case 0x06: ret = "INVALID OPCODE" ; break; + case 0x07: ret = "PROCESSOR EXTENSION NOT AVAILABLE" ; break; + case 0x08: ret = "IRQ0 - SYSTEM TIMER" ; break; + case 0x09: ret = "IRQ1 - KEYBOARD DATA READY" ; break; + case 0x0a: ret = "IRQ2 - LPT2" ; break; + case 0x0b: ret = "IRQ3 - COM2" ; break; + case 0x0c: ret = "IRQ4 - COM1" ; break; + case 0x0d: ret = "IRQ5 - FIXED DISK" ; break; + case 0x0e: ret = "IRQ6 - DISKETTE CONTROLLER" ; break; + case 0x0f: ret = "IRQ7 - PARALLEL PRINTER" ; break; + case 0x10: ret = "VIDEO" ; break; + case 0x11: ret = "GET EQUIPMENT LIST" ; break; + case 0x12: ret = "GET MEMORY SIZE" ; break; + case 0x13: ret = "DISK" ; break; + case 0x14: ret = "SERIAL" ; break; + case 0x15: ret = "SYSTEM" ; break; + case 0x16: ret = "KEYBOARD" ; break; + case 0x17: ret = "PRINTER" ; break; + case 0x18: ret = "CASETTE BASIC" ; break; + case 0x19: ret = "BOOTSTRAP LOADER" ; break; + case 0x1a: ret = "TIME" ; break; + case 0x1b: ret = "KEYBOARD - CONTROL-BREAK HANDLER" ; break; + case 0x1c: ret = "TIME - SYSTEM TIMER TICK" ; break; + case 0x1d: ret = "SYSTEM DATA - VIDEO PARAMETER TABLES"; break; + case 0x1e: ret = "SYSTEM DATA - DISKETTE PARAMETERS" ; break; + case 0x1f: ret = "SYSTEM DATA - 8x8 GRAPHICS FONT" ; break; + case 0x70: ret = "IRQ8 - CMOS REAL-TIME CLOCK" ; break; + case 0x71: ret = "IRQ9 - REDIRECTED TO INT 0A BY BIOS" ; break; + case 0x72: ret = "IRQ10 - RESERVED" ; break; + case 0x73: ret = "IRQ11 - RESERVED" ; break; + case 0x74: ret = "IRQ12 - POINTING DEVICE" ; break; + case 0x75: ret = "IRQ13 - MATH COPROCESSOR EXCEPTION" ; break; + case 0x76: ret = "IRQ14 - HARD DISK CONTROLLER OPERATION COMPLETE"; break; + case 0x77: ret = "IRQ15 - SECONDARY IDE CONTROLLER OPERATION COMPLETE"; break; + default : ret = "" ; break; + } + return ret; +} + +void bx_dbg_info_ivt_command(unsigned from, unsigned to) +{ + unsigned char buff[4]; + unsigned seg, off; + bx_bool all = 0; + bx_dbg_global_sreg_t idtr; + + BX_CPU(dbg_cpu)->dbg_get_idtr(&idtr); + + if (! BX_CPU(dbg_cpu)->protected_mode()) + { + if (to == (unsigned) EMPTY_ARG) { + to = from; + if(from == (unsigned) EMPTY_ARG) { from = 0; to = 255; all = 1; } + } + if (from > 255 || to > 255) { + dbg_printf("IVT entry should be [0-255], 'info ivt' command malformed\n"); + return; + } + if (from > to) { + unsigned temp = from; + from = to; + to = temp; + } + + for (unsigned i = from; i <= to; i++) + { + bx_dbg_read_linear(dbg_cpu, idtr.base + i*4, 4, buff); + seg = ((Bit32u) buff[3] << 8) | buff[2]; + off = ((Bit32u) buff[1] << 8) | buff[0]; + bx_dbg_read_linear(dbg_cpu, (seg << 4) + off, 1, buff); + dbg_printf("INT# %02x > %04X:%04X (0x%08x) %s%s\n", i, seg, off, + (unsigned) ((seg << 4) + off), bx_dbg_ivt_desc(i), + (buff[0] == 0xcf) ? " ; dummy iret" : ""); + } + if (all) dbg_printf("You can list individual entries with 'info ivt [NUM]' or groups with 'info ivt [NUM] [NUM]'\n"); + } + else + dbg_printf("cpu in protected mode, use info idt\n"); +} + +static void bx_dbg_print_tss(Bit8u *tss, int len) +{ + if (len<104) { + dbg_printf("Invalid tss length (limit must be greater then 103)\n"); + return; + } + + dbg_printf("ss:esp(0): 0x%04x:0x%08x\n", + *(Bit16u*)(tss+8), *(Bit32u*)(tss+4)); + dbg_printf("ss:esp(1): 0x%04x:0x%08x\n", + *(Bit16u*)(tss+0x10), *(Bit32u*)(tss+0xc)); + dbg_printf("ss:esp(2): 0x%04x:0x%08x\n", + *(Bit16u*)(tss+0x18), *(Bit32u*)(tss+0x14)); + dbg_printf("cr3: 0x%08x\n", *(Bit32u*)(tss+0x1c)); + dbg_printf("eip: 0x%08x\n", *(Bit32u*)(tss+0x20)); + dbg_printf("eflags: 0x%08x\n", *(Bit32u*)(tss+0x24)); + + dbg_printf("cs: 0x%04x ds: 0x%04x ss: 0x%04x\n", + *(Bit16u*)(tss+76), *(Bit16u*)(tss+84), *(Bit16u*)(tss+80)); + dbg_printf("es: 0x%04x fs: 0x%04x gs: 0x%04x\n", + *(Bit16u*)(tss+72), *(Bit16u*)(tss+88), *(Bit16u*)(tss+92)); + + dbg_printf("eax: 0x%08x ebx: 0x%08x ecx: 0x%08x edx: 0x%08x\n", + *(Bit32u*)(tss+0x28), *(Bit32u*)(tss+0x34), *(Bit32u*)(tss+0x2c), *(Bit32u*)(tss+0x30)); + dbg_printf("esi: 0x%08x edi: 0x%08x ebp: 0x%08x esp: 0x%08x\n", + *(Bit32u*)(tss+0x40), *(Bit32u*)(tss+0x44), *(Bit32u*)(tss+0x3c), *(Bit32u*)(tss+0x38)); + + dbg_printf("ldt: 0x%04x\n", *(Bit16u*)(tss+0x60)); + dbg_printf("i/o map: 0x%04x\n", *(Bit16u*)(tss+0x66)); +} + +void bx_dbg_info_tss_command(void) +{ + bx_dbg_sreg_t tr; + BX_CPU(dbg_cpu)->dbg_get_tr(&tr); + + bx_address base = (tr.des_l>>16) | + ((tr.des_h<<16)&0x00ff0000) | (tr.des_h & 0xff000000); +#if BX_SUPPORT_X86_64 + base |= (Bit64u)(tr.dword3) << 32; +#endif + Bit32u len = (tr.des_l & 0xffff) + 1; + + dbg_printf("tr:s=0x%x, base=0x" FMT_ADDRX ", valid=%u\n", + (unsigned) tr.sel, base, (unsigned) tr.valid); + + bx_phy_address paddr = 0; + if (BX_CPU(dbg_cpu)->dbg_xlate_linear2phy(base, &paddr)) { + bx_dbg_print_tss(BX_MEM(0)->get_vector(paddr), len); + } + else { + dbg_printf("bx_dbg_info_tss_command: failed to get physical address for TSS.BASE !"); + } +} + +/* + * this function implements the info ne2k commands in the debugger + * info ne2k - shows all registers + * info ne2k page N - shows all registers in a page + * info ne2k page N reg M - shows just one register + */ +void bx_dbg_info_ne2k(int page, int reg) +{ +#if BX_SUPPORT_NE2K + DEV_ne2k_print_info(stderr, page, reg, 0); +#else + dbg_printf("NE2000 support is not compiled in\n"); +#endif +} + +/* + * this implements the info pic command in the debugger. + * info pic - shows pic registers + */ +void bx_dbg_info_pic() +{ + DEV_pic_debug_dump(); +} + +/* + * this implements the info vga command in the debugger. + * info vga - shows vga registers + */ +void bx_dbg_info_vga() +{ + DEV_vga_debug_dump(); +} + +/* + * this implements the info pci command in the debugger. + * info pci - shows i440fx state + */ +void bx_dbg_info_pci() +{ +#if BX_SUPPORT_PCI + if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) { + DEV_pci_debug_dump(); + } + else { + dbg_printf("PCI support is disabled in .bochsrc\n"); + } +#else + dbg_printf("PCI support is not compiled in\n"); +#endif +} + +// +// Reports from various events +// + +void bx_dbg_iac_report(unsigned vector, unsigned irq) +{ + if (bx_guard.report.irq) { + dbg_printf("event at t=" FMT_LL "d IRQ irq=%u vec=%x\n", + bx_pc_system.time_ticks(), irq, vector); + } +} + +void bx_dbg_a20_report(unsigned val) +{ + if (bx_guard.report.a20) { + dbg_printf("event at t=" FMT_LL "d A20 val=%u\n", + bx_pc_system.time_ticks(), val); + } +} + +void bx_dbg_io_report(Bit32u port, unsigned size, unsigned op, Bit32u val) +{ + if (bx_guard.report.io) { + dbg_printf("event at t=" FMT_LL "d IO addr=0x%x size=%u op=%s val=0x%x\n", + bx_pc_system.time_ticks(), + port, + size, + (op==BX_READ) ? "read" : "write", + (unsigned) val); + } +} + +void bx_dbg_dma_report(bx_phy_address addr, unsigned len, unsigned what, Bit32u val) +{ + if (bx_dbg_batch_dma.this_many == 0) { + dbg_printf("%s: DMA batch this_many=0.\n", argv0); + bx_dbg_exit(1); + } + + // if Q is full, post events (and flush) + if (bx_dbg_batch_dma.Qsize >= bx_dbg_batch_dma.this_many) { + dbg_printf("%s: DMA batch Q was not flushed.\n", argv0); + bx_dbg_exit(1); + } + + // if Q already has MAX elements in it + if (bx_dbg_batch_dma.Qsize >= BX_BATCH_DMA_BUFSIZE) { + dbg_printf("%s: DMA batch buffer overrun.\n", argv0); + bx_dbg_exit(1); + } + + bx_dbg_batch_dma.Qsize++; + bx_dbg_batch_dma.Q[bx_dbg_batch_dma.Qsize-1].addr = addr; + bx_dbg_batch_dma.Q[bx_dbg_batch_dma.Qsize-1].len = len; + bx_dbg_batch_dma.Q[bx_dbg_batch_dma.Qsize-1].what = what; + bx_dbg_batch_dma.Q[bx_dbg_batch_dma.Qsize-1].val = val; + bx_dbg_batch_dma.Q[bx_dbg_batch_dma.Qsize-1].time = bx_pc_system.time_ticks(); + + // if Q is full, post events (and flush) + if (bx_dbg_batch_dma.Qsize >= bx_dbg_batch_dma.this_many) + bx_dbg_post_dma_reports(); +} + +void bx_dbg_post_dma_reports(void) +{ + unsigned i; + unsigned addr, len, what, val; + unsigned last_addr, last_len, last_what; + unsigned print_header; + unsigned first_iteration; + + if (bx_guard.report.dma) { + if (bx_dbg_batch_dma.Qsize == 0) return; // nothing batched to print + + // compress output so all contiguous DMA ops of the same type and size + // are printed on the same line + last_addr = bx_dbg_batch_dma.Q[0].addr; + last_len = bx_dbg_batch_dma.Q[0].len; + last_what = bx_dbg_batch_dma.Q[0].what; + first_iteration = 1; + + for (i=0; icr0.get_PG()) { + printf("paging off\n"); + return; + } + + printf("cr3: 0x"FMT_PHY_ADDRX"\n", BX_CPU(dbg_cpu)->cr3); + + lin = 0; + phy = 0; + + start_lin = 1; + start_phy = 2; + while(1) { + valid = BX_CPU(dbg_cpu)->dbg_xlate_linear2phy(lin, &phy); + if(valid) { + if((lin - start_lin) != (phy - start_phy)) { + if(start_lin != 1) + dbg_printf("0x%08x-0x%08x -> 0x"FMT_PHY_ADDRX"-0x"FMT_PHY_ADDRX"\n", + start_lin, lin - 1, start_phy, start_phy + (lin-1-start_lin)); + start_lin = lin; + start_phy = phy; + } + } else { + if(start_lin != 1) + dbg_printf("0x%08x-0x%08x -> 0x"FMT_PHY_ADDRX"-0x"FMT_PHY_ADDRX"\n", + start_lin, lin - 1, start_phy, start_phy + (lin-1-start_lin)); + start_lin = 1; + start_phy = 2; + } + + if(lin == 0xfffff000) break; + lin += 0x1000; + } + if(start_lin != 1) + dbg_printf("0x%08x-0x%08x -> 0x"FMT_PHY_ADDRX"-0x"FMT_PHY_ADDRX"\n", + start_lin, 0xffffffff, start_phy, start_phy + (0xffffffff-start_lin)); +} + +void bx_dbg_print_help(void) +{ + dbg_printf("h|help - show list of debugger commands\n"); + dbg_printf("h|help command - show short command description\n"); + dbg_printf("-*- Debugger control -*-\n"); + dbg_printf(" help, q|quit|exit, set, instrument, show, trace, trace-reg,\n"); + dbg_printf(" trace-mem, u|disasm, record, playback, ldsym, slist\n"); + dbg_printf("-*- Execution control -*-\n"); + dbg_printf(" c|cont|continue, s|step, p|n|next, modebp\n"); + dbg_printf("-*- Breakpoint management -*-\n"); + dbg_printf(" vb|vbreak, lb|lbreak, pb|pbreak|b|break, sb, sba, blist,\n"); + dbg_printf(" bpe, bpd, d|del|delete, watch, unwatch\n"); + dbg_printf("-*- CPU and memory contents -*-\n"); + dbg_printf(" x, xp, setpmem, crc, info,\n"); + dbg_printf(" r|reg|regs|registers, fp|fpu, mmx, sse, sreg, dreg, creg,\n"); + dbg_printf(" page, set, ptime, print-stack, ?|calc\n"); + dbg_printf("-*- Working with bochs param tree -*-\n"); + dbg_printf(" show \"param\", restore\n"); +} + +void bx_dbg_calc_command(Bit64u value) +{ + dbg_printf("0x" FMT_LL "x " FMT_LL "d\n", value, value); +} + +Bit8u bx_dbg_get_reg8l_value(unsigned reg) +{ + if (reg < BX_GENERAL_REGISTERS) + return BX_CPU(dbg_cpu)->get_reg8l(reg); + + dbg_printf("Unknown 8BL register [%d] !!!\n", reg); + return 0; +} + +Bit8u bx_dbg_get_reg8h_value(unsigned reg) +{ + if (reg < BX_GENERAL_REGISTERS) + return BX_CPU(dbg_cpu)->get_reg8h(reg); + + dbg_printf("Unknown 8BH register [%d] !!!\n", reg); + return 0; +} + +Bit16u bx_dbg_get_reg16_value(unsigned reg) +{ + if (reg < BX_GENERAL_REGISTERS) + return BX_CPU(dbg_cpu)->get_reg16(reg); + + dbg_printf("Unknown 16B register [%d] !!!\n", reg); + return 0; +} + +Bit32u bx_dbg_get_reg32_value(unsigned reg) +{ + if (reg < BX_GENERAL_REGISTERS) + return BX_CPU(dbg_cpu)->get_reg32(reg); + + dbg_printf("Unknown 32B register [%d] !!!\n", reg); + return 0; +} + +Bit64u bx_dbg_get_reg64_value(unsigned reg) +{ +#if BX_SUPPORT_X86_64 + if (reg < BX_GENERAL_REGISTERS) + return BX_CPU(dbg_cpu)->get_reg64(reg); +#endif + + dbg_printf("Unknown 64B register [%d] !!!\n", reg); + return 0; +} + +void bx_dbg_set_reg8l_value(unsigned reg, Bit8u value) +{ + if (reg < BX_GENERAL_REGISTERS) + BX_CPU(dbg_cpu)->set_reg8l(reg, value); + else + dbg_printf("Unknown 8BL register [%d] !!!\n", reg); +} + +void bx_dbg_set_reg8h_value(unsigned reg, Bit8u value) +{ + if (reg < BX_GENERAL_REGISTERS) + BX_CPU(dbg_cpu)->set_reg8h(reg, value); + else + dbg_printf("Unknown 8BH register [%d] !!!\n", reg); +} + +void bx_dbg_set_reg16_value(unsigned reg, Bit16u value) +{ + if (reg < BX_GENERAL_REGISTERS) + BX_CPU(dbg_cpu)->set_reg16(reg, value); + else + dbg_printf("Unknown 16B register [%d] !!!\n", reg); +} + +void bx_dbg_set_reg32_value(unsigned reg, Bit32u value) +{ + if (reg < BX_GENERAL_REGISTERS) + BX_CPU(dbg_cpu)->set_reg32(reg, value); + else + dbg_printf("Unknown 32B register [%d] !!!\n", reg); +} + +void bx_dbg_set_reg64_value(unsigned reg, Bit64u value) +{ +#if BX_SUPPORT_X86_64 + if (reg < BX_GENERAL_REGISTERS) + BX_CPU(dbg_cpu)->set_reg64(reg, value); + else +#endif + dbg_printf("Unknown 64B register [%d] !!!\n", reg); +} + +Bit16u bx_dbg_get_selector_value(unsigned int seg_no) +{ + bx_dbg_sreg_t sreg; + + if (seg_no > 5) { + dbg_printf("Error: seg_no out of bounds\n"); + return 0; + } + BX_CPU(dbg_cpu)->dbg_get_sreg(&sreg, seg_no); + if (!sreg.valid) { + dbg_printf("Error: segment valid bit cleared\n"); + return 0; + } + return sreg.sel; +} + +Bit16u bx_dbg_get_ip(void) +{ + return BX_CPU(dbg_cpu)->get_ip(); +} + +Bit32u bx_dbg_get_eip(void) +{ + return BX_CPU(dbg_cpu)->get_eip(); +} + +bx_address bx_dbg_get_instruction_pointer(void) +{ + return BX_CPU(dbg_cpu)->get_instruction_pointer(); +} + +bx_bool bx_dbg_read_pmode_descriptor(Bit16u sel, bx_descriptor_t *descriptor) +{ + bx_selector_t selector; + Bit32u dword1, dword2; + bx_address desc_base; + + /* if selector is NULL, error */ + if ((sel & 0xfffc) == 0) { + dbg_printf("bx_dbg_read_pmode_descriptor: Dereferencing a NULL selector!\n"); + return 0; + } + + /* parse fields in selector */ + parse_selector(sel, &selector); + + if (selector.ti) { + // LDT + if (((Bit32u)selector.index*8 + 7) > BX_CPU(dbg_cpu)->ldtr.cache.u.segment.limit_scaled) { + dbg_printf("bx_dbg_read_pmode_descriptor: selector (0x%04x) > LDT size limit\n", selector.index*8); + return 0; + } + desc_base = BX_CPU(dbg_cpu)->ldtr.cache.u.segment.base; + } + else { + // GDT + if (((Bit32u)selector.index*8 + 7) > BX_CPU(dbg_cpu)->gdtr.limit) { + dbg_printf("bx_dbg_read_pmode_descriptor: selector (0x%04x) > GDT size limit\n", selector.index*8); + return 0; + } + desc_base = BX_CPU(dbg_cpu)->gdtr.base; + } + + if (! bx_dbg_read_linear(dbg_cpu, desc_base + selector.index * 8, 4, (Bit8u*) &dword1)) { + dbg_printf("bx_dbg_read_pmode_descriptor: cannot read selector 0x%04x (index=0x%04x)\n", sel, selector.index); + return 0; + } + if (! bx_dbg_read_linear(dbg_cpu, desc_base + selector.index * 8 + 4, 4, (Bit8u*) &dword2)) { + dbg_printf("bx_dbg_read_pmode_descriptor: cannot read selector 0x%04x (index=0x%04x)\n", sel, selector.index); + return 0; + } + + memset (descriptor, 0, sizeof (descriptor)); + parse_descriptor(dword1, dword2, descriptor); + + if (!descriptor->segment) { + dbg_printf("bx_dbg_read_pmode_descriptor: selector 0x%04x points to a system descriptor and is not supported!\n", sel); + return 0; + } + + /* #NP(selector) if descriptor is not present */ + if (descriptor->p==0) { + dbg_printf("bx_dbg_read_pmode_descriptor: descriptor 0x%04x not present!\n", sel); + return 0; + } + + return 1; +} + +void bx_dbg_load_segreg(unsigned seg_no, unsigned value) +{ + bx_segment_reg_t sreg; + + if (seg_no > 6) { + dbg_printf("bx_dbg_load_segreg: unknown segment register !"); + return; + } + + if (value > 0xffff) { + dbg_printf("bx_dbg_load_segreg: segment selector out of limits !"); + return; + } + + unsigned cpu_mode = BX_CPU(dbg_cpu)->get_cpu_mode(); + if (cpu_mode == BX_MODE_LONG_64) { + dbg_printf("bx_dbg_load_segreg: not supported in long64 mode !"); + return; + } + + if (! BX_CPU(dbg_cpu)->protected_mode()) { + parse_selector(value, &sreg.selector); + + sreg.cache.valid = SegValidCache; + sreg.cache.p = 1; + sreg.cache.dpl = (cpu_mode == BX_MODE_IA32_V8086); + sreg.cache.segment = 1; + sreg.cache.type = BX_DATA_READ_WRITE_ACCESSED; + + sreg.cache.u.segment.base = sreg.selector.value << 4; + sreg.cache.u.segment.limit_scaled = 0xffff; + sreg.cache.u.segment.g = 0; + sreg.cache.u.segment.d_b = 0; + sreg.cache.u.segment.avl = 0; + sreg.selector.rpl = (cpu_mode == BX_MODE_IA32_V8086); + + BX_CPU(dbg_cpu)->dbg_set_sreg(seg_no, &sreg); + } + else { + parse_selector(value, &sreg.selector); + if (bx_dbg_read_pmode_descriptor(value, &sreg.cache)) { + BX_CPU(dbg_cpu)->dbg_set_sreg(seg_no, &sreg); + } + } +} + +bx_address bx_dbg_get_laddr(Bit16u sel, bx_address ofs) +{ + bx_address laddr; + + if (BX_CPU(dbg_cpu)->protected_mode()) { + bx_descriptor_t descriptor; + Bit32u lowaddr, highaddr; + + if (! bx_dbg_read_pmode_descriptor(sel, &descriptor)) + return 0; + + // expand-down + if (IS_DATA_SEGMENT(descriptor.type) && IS_DATA_SEGMENT_EXPAND_DOWN(descriptor.type)) { + lowaddr = descriptor.u.segment.limit_scaled; + highaddr = descriptor.u.segment.g ? 0xffffffff : 0xffff; + } + else { + lowaddr = 0; + highaddr = descriptor.u.segment.limit_scaled; + } + + if (ofs < lowaddr || ofs > highaddr) { + dbg_printf("WARNING: Offset %08X is out of selector %04x limit (%08x...%08x)!\n", + ofs, sel, lowaddr, highaddr); + } + + laddr = descriptor.u.segment.base + ofs; + } + else { + laddr = sel * 16 + ofs; + } + + return laddr; +} + +void bx_dbg_step_over_command() +{ + bx_address laddr = BX_CPU(dbg_cpu)->guard_found.laddr; + + if (! bx_dbg_read_linear(dbg_cpu, laddr, 16, bx_disasm_ibuf)) + { + return; + } + + x86_insn insn = bx_disassemble.decode(IS_CODE_32(BX_CPU(dbg_cpu)->guard_found.code_32_64), + IS_CODE_64(BX_CPU(dbg_cpu)->guard_found.code_32_64), + BX_CPU(dbg_cpu)->get_segment_base(BX_SEG_REG_CS), + BX_CPU(dbg_cpu)->guard_found.eip, bx_disasm_ibuf, bx_disasm_tbuf); + + unsigned b1 = insn.b1; + + switch(b1) { + // Jcc short + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: + case 0x79: + case 0x7A: + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + + // Jcc near + case 0x180: + case 0x181: + case 0x182: + case 0x183: + case 0x184: + case 0x185: + case 0x186: + case 0x187: + case 0x188: + case 0x189: + case 0x18A: + case 0x18B: + case 0x18C: + case 0x18D: + case 0x18E: + case 0x18F: + + // jcxz + case 0xE3: + + // retn n + case 0xC2: + // retn + case 0xC3: + // retf n + case 0xCA: + // retf + case 0xCB: + // iret + case 0xCF: + + // jmp near + case 0xE9: + // jmp far + case 0xEA: + // jmp short + case 0xEB: + bx_dbg_stepN_command(dbg_cpu, 1); + return; + // jmp absolute indirect + case 0xFF: + switch (insn.nnn) { + // near + case 4: + // far + case 5: + bx_dbg_stepN_command(dbg_cpu, 1); + return; + } + } + + // calls, ints, loops and so on + int BpId = bx_dbg_lbreakpoint_command(bkStepOver, laddr + insn.ilen); + if (BpId == -1) { + dbg_printf("bx_dbg_step_over_command:: Failed to set lbreakpoint !\n"); + return; + } + + bx_dbg_continue_command(); + + if (bx_dbg_del_lbreak(BpId)) + bx_dbg_breakpoint_changed(); +} + +#endif /* if BX_DEBUGGER */ diff --git a/bochs/bx_debug/debug.h b/bochs/bx_debug/debug.h new file mode 100644 index 00000000..7a5770c8 --- /dev/null +++ b/bochs/bx_debug/debug.h @@ -0,0 +1,507 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2001-2009 The Bochs Project +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +// if including from C parser, need basic types etc +#include "config.h" +#include "osdep.h" + +#define BX_DBG_NO_HANDLE 1000 + +Bit32u crc32(const Bit8u *buf, int len); + +#if BX_DEBUGGER + +// some strict C declarations needed by the parser/lexer +#ifdef __cplusplus +extern "C" { +#endif + +extern Bit32u dbg_cpu; + +void dbg_printf (const char *fmt, ...); + +typedef enum { + BX_DBG_SREG_ES, + BX_DBG_SREG_CS, + BX_DBG_SREG_SS, + BX_DBG_SREG_DS, + BX_DBG_SREG_FS, + BX_DBG_SREG_GS +} SRegs; + +#if BX_SUPPORT_X86_64 +# define BX_DBG_GEN_REGISTERS 16 +#else +# define BX_DBG_GEN_REGISTERS 8 +#endif + +typedef enum { + BX_DBG_REG8H_AH, + BX_DBG_REG8H_CH, + BX_DBG_REG8H_DH, + BX_DBG_REG8H_BH, +} Regs8H; + +#if BX_SUPPORT_X86_64 + +typedef enum { + BX_DBG_REG8L_AL, + BX_DBG_REG8L_CL, + BX_DBG_REG8L_DL, + BX_DBG_REG8L_BL, + BX_DBG_REG8L_SPL, + BX_DBG_REG8L_BPL, + BX_DBG_REG8L_SIL, + BX_DBG_REG8L_DIL, + BX_DBG_REG8L_R8, + BX_DBG_REG8L_R9, + BX_DBG_REG8L_R10, + BX_DBG_REG8L_R11, + BX_DBG_REG8L_R12, + BX_DBG_REG8L_R13, + BX_DBG_REG8L_R14, + BX_DBG_REG8L_R15 +} Regs8L; + +typedef enum { + BX_DBG_REG16_AX, + BX_DBG_REG16_CX, + BX_DBG_REG16_DX, + BX_DBG_REG16_BX, + BX_DBG_REG16_SP, + BX_DBG_REG16_BP, + BX_DBG_REG16_SI, + BX_DBG_REG16_DI, + BX_DBG_REG16_R8, + BX_DBG_REG16_R9, + BX_DBG_REG16_R10, + BX_DBG_REG16_R11, + BX_DBG_REG16_R12, + BX_DBG_REG16_R13, + BX_DBG_REG16_R14, + BX_DBG_REG16_R15 +} Regs16; + +typedef enum { + BX_DBG_REG32_EAX, + BX_DBG_REG32_ECX, + BX_DBG_REG32_EDX, + BX_DBG_REG32_EBX, + BX_DBG_REG32_ESP, + BX_DBG_REG32_EBP, + BX_DBG_REG32_ESI, + BX_DBG_REG32_EDI, + BX_DBG_REG32_R8, + BX_DBG_REG32_R9, + BX_DBG_REG32_R10, + BX_DBG_REG32_R11, + BX_DBG_REG32_R12, + BX_DBG_REG32_R13, + BX_DBG_REG32_R14, + BX_DBG_REG32_R15 +} Regs32; + +typedef enum { + BX_DBG_REG64_RAX, + BX_DBG_REG64_RCX, + BX_DBG_REG64_RDX, + BX_DBG_REG64_RBX, + BX_DBG_REG64_RSP, + BX_DBG_REG64_RBP, + BX_DBG_REG64_RSI, + BX_DBG_REG64_RDI, + BX_DBG_REG64_R8, + BX_DBG_REG64_R9, + BX_DBG_REG64_R10, + BX_DBG_REG64_R11, + BX_DBG_REG64_R12, + BX_DBG_REG64_R13, + BX_DBG_REG64_R14, + BX_DBG_REG64_R15 +} Regs64; + +#else + +typedef enum { + BX_DBG_REG8L_AL, + BX_DBG_REG8L_CL, + BX_DBG_REG8L_DL, + BX_DBG_REG8L_BL +} Regs8L; + +typedef enum { + BX_DBG_REG16_AX, + BX_DBG_REG16_CX, + BX_DBG_REG16_DX, + BX_DBG_REG16_BX, + BX_DBG_REG16_SP, + BX_DBG_REG16_BP, + BX_DBG_REG16_SI, + BX_DBG_REG16_DI +} Regs16; + +typedef enum { + BX_DBG_REG32_EAX, + BX_DBG_REG32_ECX, + BX_DBG_REG32_EDX, + BX_DBG_REG32_EBX, + BX_DBG_REG32_ESP, + BX_DBG_REG32_EBP, + BX_DBG_REG32_ESI, + BX_DBG_REG32_EDI +} Regs32; + +#endif + +typedef enum +{ + bkRegular, + bkAtIP, + bkStepOver +} BreakpointKind; + +typedef enum _show_flags { + Flag_call = 0x1, + Flag_ret = 0x2, + Flag_softint = 0x4, + Flag_iret = 0x8, + Flag_intsig = 0x10, + Flag_mode = 0x20 +} show_flags_t; + +// Flex defs +extern int bxlex(void); +extern char *bxtext; // Using the pointer option rather than array +extern int bxwrap(void); +void bx_add_lex_input(char *buf); + +// Yacc defs +extern int bxparse(void); +extern void bxerror(char *s); + +#define EMPTY_ARG (-1) + +bx_bool bx_dbg_read_linear(unsigned which_cpu, bx_address laddr, unsigned len, Bit8u *buf); +Bit16u bx_dbg_get_selector_value(unsigned int seg_no); +Bit16u bx_dbg_get_ip (void); +Bit32u bx_dbg_get_eip(void); +bx_address bx_dbg_get_instruction_pointer(void); +Bit8u bx_dbg_get_reg8l_value(unsigned reg); +Bit8u bx_dbg_get_reg8h_value(unsigned reg); +Bit16u bx_dbg_get_reg16_value(unsigned reg); +Bit32u bx_dbg_get_reg32_value(unsigned reg); +Bit64u bx_dbg_get_reg64_value(unsigned reg); +void bx_dbg_set_reg8l_value(unsigned reg, Bit8u value); +void bx_dbg_set_reg8h_value(unsigned reg, Bit8u value); +void bx_dbg_set_reg16_value(unsigned reg, Bit16u value); +void bx_dbg_set_reg32_value(unsigned reg, Bit32u value); +void bx_dbg_set_reg64_value(unsigned reg, Bit64u value); +void bx_dbg_load_segreg(unsigned reg, unsigned value); +bx_address bx_dbg_get_laddr(Bit16u sel, bx_address ofs); +void bx_dbg_step_over_command(void); +void bx_dbg_trace_command(bx_bool enable); +void bx_dbg_trace_reg_command(bx_bool enable); +void bx_dbg_trace_mem_command(bx_bool enable); +void bx_dbg_ptime_command(void); +void bx_dbg_timebp_command(bx_bool absolute, Bit64u time); +#define MAX_CONCURRENT_BPS 5 +extern int timebp_timer; +extern Bit64u timebp_queue[MAX_CONCURRENT_BPS]; +extern int timebp_queue_size; +void bx_dbg_record_command(char*); +void bx_dbg_playback_command(char*); +void bx_dbg_modebp_command(void); +void bx_dbg_where_command(void); +void bx_dbg_print_string_command(bx_address addr); +void bx_dbg_xlate_address(bx_lin_address address); +void bx_dbg_show_command(const char*); +void bx_dbg_print_stack_command(unsigned nwords); +void bx_dbg_print_watchpoints(void); +void bx_dbg_watchpoint_continue(bx_bool watch_continue); +void bx_dbg_watch(int type, bx_phy_address address, Bit32u len); +void bx_dbg_unwatch_all(void); +void bx_dbg_unwatch(bx_phy_address handle); +void bx_dbg_continue_command(void); +void bx_dbg_stepN_command(int cpu, Bit32u count); +void bx_dbg_set_auto_disassemble(bx_bool enable); +void bx_dbg_disassemble_switch_mode(void); +void bx_dbg_disassemble_hex_mode_switch(int mode); +void bx_dbg_set_disassemble_size(unsigned size); +void bx_dbg_del_breakpoint_command(unsigned handle); +void bx_dbg_en_dis_breakpoint_command(unsigned handle, bx_bool enable); +bx_bool bx_dbg_en_dis_pbreak(unsigned handle, bx_bool enable); +bx_bool bx_dbg_en_dis_lbreak(unsigned handle, bx_bool enable); +bx_bool bx_dbg_en_dis_vbreak(unsigned handle, bx_bool enable); +bx_bool bx_dbg_del_pbreak(unsigned handle); +bx_bool bx_dbg_del_lbreak(unsigned handle); +bx_bool bx_dbg_del_vbreak(unsigned handle); +int bx_dbg_vbreakpoint_command(BreakpointKind bk, Bit32u cs, bx_address eip); +int bx_dbg_lbreakpoint_command(BreakpointKind bk, bx_address laddress); +int bx_dbg_pbreakpoint_command(BreakpointKind bk, bx_phy_address paddress); +void bx_dbg_info_bpoints_command(void); +void bx_dbg_quit_command(void); +#define BX_INFO_GENERAL_PURPOSE_REGS 1 /* bitmasks - choices for bx_dbg_info_registers_command */ +#define BX_INFO_FPU_REGS 2 +#define BX_INFO_MMX_REGS 4 +#define BX_INFO_SSE_REGS 8 +void bx_dbg_info_registers_command(int); +void bx_dbg_info_ivt_command(unsigned from, unsigned to); +void bx_dbg_info_idt_command(unsigned from, unsigned to); +void bx_dbg_info_gdt_command(unsigned from, unsigned to); +void bx_dbg_info_ldt_command(unsigned from, unsigned to); +void bx_dbg_info_tss_command(void); +void bx_dbg_info_debug_regs_command(void); +void bx_dbg_info_control_regs_command(void); +void bx_dbg_info_segment_regs_command(void); +void bx_dbg_info_flags(void); +void bx_dbg_info_linux_command(void); +void bx_dbg_examine_command(const char *command, const char *format, bx_bool format_passed, + bx_address addr, bx_bool addr_passed); +Bit32u bx_dbg_lin_indirect(bx_address addr); +Bit32u bx_dbg_phy_indirect(bx_phy_address addr); +void bx_dbg_setpmem_command(bx_phy_address addr, unsigned len, Bit32u val); +void bx_dbg_query_command(const char *); +void bx_dbg_take_command(const char *, unsigned n); +void bx_dbg_disassemble_current(const char *); +void bx_dbg_disassemble_command(const char *, Bit64u from, Bit64u to); +void bx_dbg_instrument_command(const char *); +void bx_dbg_doit_command(unsigned); +void bx_dbg_crc_command(bx_phy_address addr1, bx_phy_address addr2); +void bx_dbg_linux_syscall(unsigned which_cpu); +void bx_dbg_info_ne2k(int page, int reg); +void bx_dbg_info_pic(void); +void bx_dbg_info_vga(void); +void bx_dbg_info_pci(void); +void bx_dbg_print_help(void); +void bx_dbg_calc_command(Bit64u value); +void bx_dbg_dump_table(void); + +// callbacks from CPU +void bx_dbg_exception(unsigned cpu, Bit8u vector, Bit16u error_code); +void bx_dbg_interrupt(unsigned cpu, Bit8u vector, Bit16u error_code); +void bx_dbg_halt(unsigned cpu); + +// memory trace callbacks from CPU, len=1,2,4 or 8 +void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsigned len, unsigned pl, unsigned rw, Bit8u *data); +void bx_dbg_phy_memory_access(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw, Bit8u *data); + +// check memory access for watchpoints +void bx_dbg_check_memory_watchpoints(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw); + +// commands that work with Bochs param tree +void bx_dbg_restore_command(const char *param_name, const char *path); +void bx_dbg_show_param_command(const char *param); + +int bx_dbg_show_symbolic(void); +void bx_dbg_set_symbol_command(const char *symbol, Bit32u val); +const char* bx_dbg_symbolic_address(Bit32u context, Bit32u eip, Bit32u base); +const char* bx_dbg_symbolic_address_16bit(Bit32u eip, Bit32u cs); +int bx_dbg_symbol_command(const char* filename, bx_bool global, Bit32u offset); +void bx_dbg_info_symbols_command(const char *Symbol); +int bx_dbg_lbreakpoint_symbol_command(const char *Symbol); +Bit32u bx_dbg_get_symbol_value(const char *Symbol); +const char* bx_dbg_disasm_symbolic_address(Bit32u eip, Bit32u base); + +#ifdef __cplusplus +} +#endif + +// the rest for C++ +#ifdef __cplusplus + +typedef enum { + STOP_NO_REASON = 0, + STOP_TIME_BREAK_POINT, + STOP_READ_WATCH_POINT, + STOP_WRITE_WATCH_POINT, + STOP_MAGIC_BREAK_POINT, + STOP_MODE_BREAK_POINT, + STOP_CPU_HALTED +} stop_reason_t; + +typedef enum { + BREAK_POINT_MAGIC, BREAK_POINT_READ, BREAK_POINT_WRITE, BREAK_POINT_TIME +} break_point_t; + +#define BX_DBG_REG_EIP 10 +#define BX_DBG_REG_EFLAGS 11 +#define BX_DBG_REG_CS 20 +#define BX_DBG_REG_SS 21 +#define BX_DBG_REG_DS 22 +#define BX_DBG_REG_ES 23 +#define BX_DBG_REG_FS 24 +#define BX_DBG_REG_GS 25 +#define BX_DBG_REG_CR0 30 +#define BX_DBG_REG_CR2 32 +#define BX_DBG_REG_CR3 33 +#define BX_DBG_REG_CR4 34 + +#define BX_DBG_PENDING_DMA 1 +#define BX_DBG_PENDING_IRQ 2 + +void bx_debug_break(void); + +void bx_dbg_exit(int code); +#if BX_DBG_EXTENSIONS + int bx_dbg_extensions(char *command); +#else +#define bx_dbg_extensions(command) 0 +#endif + +// +// code for guards... +// + +#define BX_DBG_GUARD_IADDR_VIR 0x0001 +#define BX_DBG_GUARD_IADDR_LIN 0x0002 +#define BX_DBG_GUARD_IADDR_PHY 0x0004 +#define BX_DBG_GUARD_IADDR_ALL (BX_DBG_GUARD_IADDR_VIR | \ + BX_DBG_GUARD_IADDR_LIN | \ + BX_DBG_GUARD_IADDR_PHY) + +#define BX_DBG_GUARD_CTRL_C 0x0100 + +typedef struct { + unsigned guard_for; + + // instruction address breakpoints + struct { +#if (BX_DBG_MAX_VIR_BPOINTS > 0) + unsigned num_virtual; + struct { + Bit32u cs; // only use 16 bits + bx_address eip; + unsigned bpoint_id; + bx_bool enabled; + } vir[BX_DBG_MAX_VIR_BPOINTS]; +#endif + +#if (BX_DBG_MAX_LIN_BPOINTS > 0) + unsigned num_linear; + struct { + bx_address addr; + unsigned bpoint_id; + bx_bool enabled; + } lin[BX_DBG_MAX_LIN_BPOINTS]; +#endif + +#if (BX_DBG_MAX_PHY_BPOINTS > 0) + unsigned num_physical; + struct { + bx_phy_address addr; + unsigned bpoint_id; + bx_bool enabled; + } phy[BX_DBG_MAX_PHY_BPOINTS]; +#endif + } iaddr; + + // user typed Ctrl-C, requesting simulator stop at next convient spot + volatile bx_bool interrupt_requested; + + // booleans to control whether simulator should report events + // to debug controller + struct { + bx_bool irq; + bx_bool a20; + bx_bool io; + bx_bool dma; + } report; + + struct { + bx_bool irq; // should process IRQs asynchronously + bx_bool dma; // should process DMAs asynchronously + } async; + +#define BX_DBG_ASYNC_PENDING_A20 0x01 +#define BX_DBG_ASYNC_PENDING_RESET 0x02 +#define BX_DBG_ASYNC_PENDING_NMI 0x04 + + // Asynchronous changes which are pending. These are Q'd by + // the debugger, as the master simulator is notified of a pending + // async change. At the simulator's next point, where it checks for + // such events, it notifies the debugger with acknowlegement. This + // field contains a logically or'd list of all events which should + // be checked, and ack'd. + struct { + unsigned which; // logical OR of above constants + bx_bool a20; + bx_bool reset; + bx_bool nmi; + } async_changes_pending; +} bx_guard_t; + +// working information for each simulator to update when a guard +// is reached (found) +typedef struct bx_guard_found_t { + unsigned guard_found; + unsigned iaddr_index; + Bit64u icount; // number of completed instructions from last breakpoint hit + Bit32u cs; // cs:eip and linear addr of instruction at guard point + bx_address eip; + bx_address laddr; + // 00 - 16 bit, 01 - 32 bit, 10 - 64-bit, 11 - illegal + unsigned code_32_64; // CS seg size at guard point + bx_bool ctrl_c; // simulator stopped due to Ctrl-C request + Bit64u time_tick; // time tick when guard reached +} bx_guard_found_t; + +struct bx_watchpoint { + bx_phy_address addr; + Bit32u len; +}; + +extern unsigned num_write_watchpoints; +extern unsigned num_read_watchpoints; +extern bx_watchpoint write_watchpoint[BX_DBG_MAX_WATCHPONTS]; +extern bx_watchpoint read_watchpoint[BX_DBG_MAX_WATCHPONTS]; +extern bx_guard_t bx_guard; + +#define IS_CODE_32(code_32_64) ((code_32_64 & 1) != 0) +#define IS_CODE_64(code_32_64) ((code_32_64 & 2) != 0) + +void bx_dbg_init_infile(void); +int bx_dbg_set_rcfile(const char *rcfile); +int bx_dbg_main(void); +void bx_dbg_user_input_loop(void); +void bx_dbg_interpret_line(char *cmd); + +typedef struct { + Bit16u sel; + Bit32u des_l, des_h, valid; +#if BX_SUPPORT_X86_64 + Bit32u dword3; +#endif +} bx_dbg_sreg_t; + +typedef struct { + bx_address base; + Bit16u limit; +} bx_dbg_global_sreg_t; + +void bx_dbg_dma_report(bx_phy_address addr, unsigned len, unsigned what, Bit32u val); +void bx_dbg_iac_report(unsigned vector, unsigned irq); +void bx_dbg_a20_report(unsigned val); +void bx_dbg_io_report(Bit32u port, unsigned size, unsigned op, Bit32u val); +void bx_dbg_disassemble_current(int which_cpu, int print_time); + +#endif // #ifdef __cplusplus + +#endif // #if BX_DEBUGGER diff --git a/bochs/bx_debug/lexer.c b/bochs/bx_debug/lexer.c new file mode 100644 index 00000000..a4934c19 --- /dev/null +++ b/bochs/bx_debug/lexer.c @@ -0,0 +1,3482 @@ + +#line 3 "" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer bx_create_buffer +#define yy_delete_buffer bx_delete_buffer +#define yy_flex_debug bx_flex_debug +#define yy_init_buffer bx_init_buffer +#define yy_flush_buffer bx_flush_buffer +#define yy_load_buffer_state bx_load_buffer_state +#define yy_switch_to_buffer bx_switch_to_buffer +#define yyin bxin +#define yyleng bxleng +#define yylex bxlex +#define yylineno bxlineno +#define yyout bxout +#define yyrestart bxrestart +#define yytext bxtext +#define yywrap bxwrap +#define yyalloc bxalloc +#define yyrealloc bxrealloc +#define yyfree bxfree + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE bxrestart(bxin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int bxleng; + +extern FILE *bxin, *bxout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up bxtext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up bxtext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via bxrestart()), so that the user can continue scanning by + * just pointing bxin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when bxtext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int bxleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow bxwrap()'s to do buffer switches + * instead of setting up a fresh bxin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void bxrestart (FILE *input_file ); +void bx_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE bx_create_buffer (FILE *file,int size ); +void bx_delete_buffer (YY_BUFFER_STATE b ); +void bx_flush_buffer (YY_BUFFER_STATE b ); +void bxpush_buffer_state (YY_BUFFER_STATE new_buffer ); +void bxpop_buffer_state (void ); + +static void bxensure_buffer_stack (void ); +static void bx_load_buffer_state (void ); +static void bx_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER bx_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE bx_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE bx_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE bx_scan_bytes (yyconst char *bytes,int len ); + +void *bxalloc (yy_size_t ); +void *bxrealloc (void *,yy_size_t ); +void bxfree (void * ); + +#define yy_new_buffer bx_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + bxensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + bx_create_buffer(bxin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + bxensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + bx_create_buffer(bxin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *bxin = (FILE *) 0, *bxout = (FILE *) 0; + +typedef int yy_state_type; + +extern int bxlineno; + +int bxlineno = 1; + +extern char *bxtext; +#define yytext_ptr bxtext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up bxtext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + bxleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 203 +#define YY_END_OF_BUFFER 204 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[444] = + { 0, + 0, 0, 0, 0, 0, 0, 204, 201, 1, 199, + 186, 201, 200, 201, 183, 201, 188, 189, 179, 177, + 178, 180, 194, 194, 198, 201, 201, 172, 187, 197, + 185, 195, 18, 6, 43, 195, 195, 195, 171, 195, + 195, 195, 195, 12, 195, 13, 48, 26, 10, 195, + 59, 195, 80, 49, 184, 202, 1, 202, 198, 202, + 1, 0, 191, 0, 200, 196, 0, 190, 0, 195, + 193, 194, 0, 182, 181, 197, 195, 109, 93, 113, + 110, 94, 119, 195, 114, 195, 111, 95, 195, 195, + 21, 164, 115, 195, 112, 118, 96, 195, 195, 23, + + 167, 116, 195, 195, 195, 195, 195, 195, 165, 195, + 195, 29, 168, 195, 195, 169, 195, 195, 195, 161, + 195, 195, 16, 195, 195, 195, 195, 195, 195, 3, + 195, 18, 195, 195, 195, 195, 195, 195, 195, 197, + 153, 154, 195, 195, 195, 195, 195, 195, 195, 71, + 195, 195, 117, 195, 120, 195, 166, 195, 195, 195, + 195, 195, 195, 195, 15, 195, 195, 195, 195, 195, + 50, 174, 175, 176, 196, 192, 92, 195, 45, 44, + 100, 195, 195, 195, 33, 5, 195, 42, 98, 195, + 56, 195, 195, 129, 135, 130, 131, 134, 132, 195, + + 162, 133, 136, 195, 195, 29, 36, 195, 195, 61, + 34, 195, 195, 57, 35, 195, 195, 37, 195, 32, + 195, 197, 195, 4, 195, 195, 91, 195, 58, 195, + 195, 195, 195, 195, 155, 156, 157, 158, 159, 160, + 101, 137, 121, 102, 138, 122, 145, 152, 146, 147, + 150, 148, 195, 195, 27, 195, 163, 149, 151, 72, + 2, 195, 97, 195, 195, 99, 195, 30, 195, 195, + 195, 195, 39, 195, 195, 38, 195, 195, 90, 195, + 195, 195, 31, 195, 195, 173, 7, 22, 195, 195, + 64, 24, 195, 47, 195, 195, 171, 20, 195, 195, + + 195, 195, 195, 197, 88, 11, 89, 195, 195, 195, + 195, 195, 195, 46, 103, 139, 123, 104, 140, 124, + 105, 141, 125, 106, 142, 126, 107, 143, 127, 108, + 144, 128, 79, 195, 195, 27, 195, 195, 81, 69, + 195, 25, 9, 63, 195, 195, 55, 195, 195, 195, + 195, 195, 195, 14, 17, 195, 195, 195, 195, 170, + 195, 195, 195, 82, 40, 195, 197, 195, 195, 195, + 195, 70, 53, 195, 195, 195, 195, 84, 195, 195, + 65, 195, 195, 77, 86, 80, 195, 41, 60, 85, + 195, 16, 75, 19, 195, 195, 195, 73, 195, 195, + + 195, 195, 195, 195, 195, 15, 195, 195, 54, 195, + 195, 195, 51, 52, 195, 83, 195, 195, 78, 8, + 195, 74, 195, 195, 195, 195, 195, 195, 195, 195, + 28, 195, 67, 66, 62, 195, 195, 195, 76, 195, + 68, 87, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 6, 7, 1, 8, 9, 10, + 11, 12, 13, 1, 14, 1, 15, 16, 17, 18, + 19, 20, 21, 22, 22, 23, 24, 1, 25, 26, + 1, 27, 28, 29, 30, 30, 30, 30, 30, 30, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 1, 32, 1, 33, 31, 1, 34, 35, 36, 37, + + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 1, 60, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[61] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 1, 1, 1, 1, 1, 5, + 6, 1, 1, 7, 8, 8, 8, 7, 7, 9, + 9, 9, 10, 10, 10, 9, 10, 9, 10, 10, + 10, 9, 9, 9, 10, 9, 11, 10, 10, 1 + } ; + +static yyconst flex_int16_t yy_base[458] = + { 0, + 0, 0, 59, 61, 63, 65, 218, 2459, 210, 2459, + 2459, 64, 0, 0, 2459, 61, 2459, 2459, 2459, 2459, + 0, 2459, 48, 0, 2459, 185, 179, 2459, 2459, 0, + 2459, 92, 136, 83, 156, 180, 40, 127, 185, 198, + 199, 217, 214, 92, 234, 256, 261, 302, 325, 301, + 114, 349, 346, 229, 2459, 2459, 201, 389, 2459, 0, + 198, 68, 2459, 0, 0, 0, 66, 2459, 0, 0, + 79, 0, 0, 2459, 2459, 0, 387, 406, 407, 420, + 421, 434, 443, 448, 457, 462, 471, 476, 296, 487, + 507, 324, 500, 512, 519, 526, 539, 540, 553, 562, + + 567, 576, 581, 590, 595, 608, 613, 622, 627, 640, + 649, 654, 668, 669, 682, 683, 696, 697, 710, 715, + 724, 735, 738, 749, 756, 763, 772, 781, 790, 795, + 808, 809, 822, 825, 841, 848, 863, 864, 879, 311, + 64, 90, 882, 891, 896, 909, 923, 920, 937, 43, + 381, 248, 947, 955, 259, 962, 975, 982, 983, 992, + 652, 868, 997, 1005, 1012, 1019, 1020, 1040, 1041, 1048, + 1051, 0, 0, 0, 0, 0, 1061, 1062, 1070, 1071, + 1081, 1084, 1091, 1092, 1101, 1106, 1114, 1121, 1128, 1129, + 1136, 1143, 1150, 1151, 1158, 1165, 1172, 1173, 1180, 1187, + + 1194, 1195, 1202, 1209, 1216, 1217, 1224, 1231, 1238, 1239, + 1246, 1259, 1260, 1268, 1269, 1288, 1283, 1291, 1296, 1311, + 1318, 126, 1319, 1326, 1339, 1346, 1347, 1356, 1361, 1366, + 1369, 1383, 1386, 1391, 136, 153, 154, 364, 494, 564, + 0, 0, 0, 0, 0, 0, 1394, 1405, 1413, 1414, + 1422, 1427, 1435, 1442, 1449, 1452, 1459, 1462, 1472, 1473, + 1481, 1482, 1492, 1501, 1506, 1509, 1514, 1523, 1528, 1533, + 1536, 1556, 1547, 1564, 1561, 1569, 1578, 1586, 1583, 1591, + 1600, 1605, 1608, 1613, 1627, 1628, 1636, 1641, 1649, 1656, + 1663, 1664, 1671, 1678, 1685, 1686, 1693, 1700, 1707, 1708, + + 1715, 1728, 1735, 183, 0, 1738, 1743, 1748, 1757, 1767, + 1758, 1778, 1781, 1786, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1789, 1800, 1808, 1809, 1819, 1822, 1829, 1830, + 1839, 1844, 1849, 1854, 1859, 1864, 1869, 1879, 1874, 1884, + 1889, 1899, 1904, 1909, 1912, 1919, 1929, 1934, 1939, 1942, + 1953, 1956, 1963, 1966, 1977, 1985, 180, 1980, 1999, 2002, + 2009, 2016, 2019, 2026, 2033, 2036, 2041, 2055, 2056, 2064, + 2085, 2077, 2078, 2092, 2099, 2100, 2107, 2114, 2122, 2129, + 2136, 2137, 2144, 2151, 2158, 2159, 143, 2166, 2179, 2186, + + 2187, 2194, 2201, 36, 2208, 2211, 2216, 2221, 2230, 2231, + 133, 2238, 2245, 2252, 137, 2259, 144, 142, 2260, 2267, + 2274, 2282, 70, 2289, 127, 128, 122, 2296, 112, 103, + 2299, 107, 0, 0, 2304, 94, 79, 81, 0, 78, + 0, 0, 2459, 2356, 2367, 2378, 2385, 2396, 2405, 2413, + 103, 2421, 2430, 90, 2438, 2446, 2447 + } ; + +static yyconst flex_int16_t yy_def[458] = + { 0, + 443, 1, 444, 444, 444, 444, 443, 443, 443, 443, + 443, 445, 446, 447, 443, 448, 443, 443, 443, 443, + 449, 443, 450, 451, 443, 443, 443, 443, 443, 452, + 443, 453, 453, 33, 33, 33, 33, 33, 33, 33, + 33, 40, 40, 40, 40, 33, 33, 36, 33, 33, + 40, 40, 33, 33, 443, 443, 443, 443, 443, 454, + 443, 445, 443, 445, 446, 455, 448, 443, 448, 449, + 450, 451, 456, 443, 443, 452, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 40, 40, + 40, 40, 40, 33, 33, 33, 33, 33, 33, 33, + + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 40, 33, 40, 33, 33, 33, + 33, 33, 33, 40, 40, 40, 40, 40, 40, 452, + 452, 452, 33, 33, 33, 33, 33, 33, 33, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 58, 457, 454, 455, 456, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 452, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + + 147, 147, 147, 452, 452, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 452, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 449, 147, 147, 147, + + 147, 147, 147, 449, 147, 147, 147, 147, 147, 147, + 449, 147, 147, 147, 449, 147, 449, 449, 147, 147, + 147, 147, 449, 147, 449, 449, 449, 147, 449, 449, + 147, 449, 449, 449, 147, 449, 449, 449, 449, 449, + 449, 449, 0, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443 + } ; + +static yyconst flex_int16_t yy_nxt[2520] = + { 0, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 26, 27, 28, 29, 30, + 30, 8, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 41, 41, 55, + 57, 10, 57, 10, 57, 10, 57, 10, 63, 68, + 72, 72, 63, 58, 68, 58, 260, 60, 77, 60, + 77, 417, 77, 59, 111, 59, 418, 59, 112, 59, + 77, 113, 69, 174, 77, 64, 77, 69, 241, 64, + + 242, 72, 72, 429, 73, 70, 72, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 86, 442, 441, 243, + 430, 76, 76, 87, 244, 440, 245, 88, 77, 128, + 89, 90, 78, 91, 92, 443, 79, 439, 77, 93, + 77, 304, 77, 438, 437, 246, 77, 436, 80, 70, + 77, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 164, 434, 77, 114, 77, 76, 76, 77, 77, 305, + 315, 115, 316, 433, 432, 77, 81, 77, 116, 427, + 82, 426, 425, 77, 83, 423, 84, 318, 321, 319, + 322, 317, 85, 94, 411, 305, 95, 96, 367, 61, + + 97, 98, 61, 99, 77, 75, 100, 101, 320, 323, + 74, 61, 102, 103, 104, 105, 106, 443, 107, 443, + 77, 108, 117, 443, 77, 77, 443, 443, 77, 77, + 77, 109, 443, 77, 118, 77, 110, 443, 77, 77, + 443, 77, 77, 77, 119, 443, 120, 77, 121, 77, + 77, 123, 122, 124, 77, 77, 443, 443, 125, 126, + 77, 127, 77, 77, 77, 77, 443, 77, 77, 77, + 77, 77, 129, 77, 170, 443, 443, 171, 443, 77, + 130, 77, 77, 77, 77, 77, 443, 77, 77, 131, + 132, 133, 77, 134, 77, 262, 77, 135, 77, 77, + + 136, 77, 443, 266, 77, 77, 137, 443, 138, 77, + 77, 77, 77, 443, 139, 443, 443, 77, 140, 443, + 443, 443, 443, 443, 141, 142, 235, 236, 237, 238, + 239, 240, 77, 443, 161, 143, 144, 145, 146, 147, + 77, 77, 184, 148, 77, 77, 77, 443, 443, 77, + 77, 162, 163, 149, 443, 443, 443, 77, 77, 150, + 77, 443, 151, 443, 443, 152, 153, 443, 443, 154, + 77, 443, 77, 155, 77, 156, 157, 158, 77, 167, + 159, 77, 160, 165, 443, 77, 168, 443, 166, 443, + 77, 443, 443, 443, 77, 77, 169, 77, 324, 77, + + 325, 443, 77, 77, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 443, 77, 443, 77, 443, 443, 326, + 77, 443, 443, 173, 173, 173, 443, 77, 173, 173, + 173, 77, 77, 261, 173, 77, 173, 77, 443, 443, + 173, 173, 173, 77, 173, 173, 77, 77, 443, 443, + 77, 177, 443, 443, 77, 77, 77, 77, 443, 443, + 77, 77, 77, 77, 77, 77, 443, 443, 77, 77, + 77, 77, 443, 443, 77, 178, 77, 77, 77, 179, + 180, 443, 77, 77, 77, 182, 443, 181, 77, 443, + 77, 77, 77, 77, 443, 443, 77, 77, 77, 77, + + 443, 77, 77, 443, 77, 77, 183, 77, 443, 443, + 77, 77, 77, 77, 443, 77, 77, 443, 77, 77, + 77, 77, 443, 77, 77, 443, 77, 77, 327, 443, + 328, 443, 77, 77, 443, 77, 77, 77, 443, 443, + 185, 77, 186, 77, 187, 443, 77, 443, 77, 329, + 77, 443, 77, 77, 77, 77, 188, 77, 443, 77, + 77, 77, 77, 77, 443, 443, 77, 77, 77, 77, + 189, 443, 443, 191, 77, 77, 77, 190, 443, 77, + 77, 443, 77, 77, 77, 443, 443, 77, 77, 77, + 77, 443, 443, 77, 192, 77, 77, 77, 330, 193, + + 331, 77, 77, 77, 443, 443, 77, 77, 443, 77, + 77, 77, 77, 443, 443, 77, 77, 77, 77, 332, + 77, 77, 443, 77, 77, 77, 77, 443, 443, 77, + 77, 77, 77, 443, 77, 77, 443, 194, 195, 77, + 77, 443, 443, 77, 443, 77, 196, 443, 77, 198, + 443, 197, 77, 77, 443, 443, 77, 200, 77, 443, + 443, 77, 77, 77, 199, 443, 77, 77, 202, 77, + 201, 77, 77, 443, 443, 203, 443, 77, 77, 443, + 77, 204, 205, 77, 77, 77, 273, 77, 77, 77, + 77, 77, 443, 77, 77, 274, 77, 77, 77, 77, + + 443, 443, 77, 77, 77, 77, 443, 206, 77, 77, + 77, 443, 77, 77, 443, 443, 77, 77, 77, 77, + 443, 207, 77, 77, 77, 77, 77, 77, 443, 208, + 77, 77, 77, 77, 443, 443, 77, 77, 77, 77, + 209, 77, 443, 443, 77, 77, 77, 77, 212, 211, + 77, 443, 210, 77, 77, 77, 443, 443, 77, 77, + 77, 213, 443, 77, 77, 77, 77, 443, 77, 443, + 443, 77, 77, 214, 77, 77, 443, 443, 77, 77, + 77, 443, 77, 77, 443, 77, 77, 215, 216, 77, + 443, 77, 77, 77, 77, 443, 443, 77, 222, 77, + + 217, 218, 219, 77, 77, 77, 77, 77, 221, 443, + 77, 77, 443, 77, 443, 443, 443, 443, 77, 220, + 77, 77, 77, 443, 443, 77, 77, 443, 224, 77, + 77, 77, 443, 443, 77, 77, 443, 223, 77, 77, + 77, 443, 443, 77, 443, 77, 77, 225, 77, 77, + 443, 77, 77, 77, 443, 443, 77, 77, 77, 226, + 443, 77, 77, 227, 77, 77, 77, 443, 443, 443, + 77, 228, 77, 77, 443, 77, 229, 77, 77, 77, + 443, 230, 443, 443, 77, 443, 443, 77, 443, 77, + 443, 77, 443, 443, 77, 77, 77, 443, 77, 77, + + 77, 275, 77, 77, 231, 232, 443, 77, 443, 77, + 77, 77, 77, 77, 77, 77, 233, 77, 77, 77, + 234, 443, 77, 443, 443, 77, 77, 77, 443, 77, + 77, 77, 77, 77, 443, 77, 77, 443, 247, 248, + 77, 77, 443, 443, 77, 443, 77, 249, 443, 77, + 251, 443, 250, 77, 443, 443, 253, 77, 254, 77, + 77, 443, 255, 77, 77, 252, 443, 77, 257, 443, + 77, 77, 443, 77, 256, 443, 77, 77, 258, 77, + 77, 77, 77, 443, 443, 259, 77, 77, 77, 443, + 77, 263, 443, 77, 77, 77, 265, 77, 77, 267, + + 443, 77, 443, 443, 443, 264, 77, 443, 77, 443, + 77, 443, 268, 77, 77, 77, 77, 77, 77, 269, + 443, 77, 77, 443, 271, 77, 77, 77, 443, 270, + 77, 77, 77, 77, 77, 443, 77, 272, 77, 443, + 77, 443, 443, 77, 77, 77, 443, 77, 276, 443, + 443, 77, 279, 77, 77, 77, 77, 443, 77, 77, + 277, 443, 278, 77, 443, 443, 443, 443, 443, 443, + 77, 77, 280, 77, 77, 77, 77, 281, 443, 77, + 77, 77, 282, 77, 77, 443, 77, 77, 443, 443, + 77, 77, 77, 283, 77, 77, 77, 77, 443, 77, + + 77, 77, 77, 77, 77, 77, 77, 443, 443, 77, + 77, 443, 77, 284, 77, 443, 77, 285, 443, 77, + 77, 77, 77, 77, 77, 77, 286, 77, 443, 443, + 77, 77, 77, 443, 77, 77, 77, 443, 443, 77, + 77, 77, 77, 77, 287, 77, 443, 77, 443, 77, + 443, 443, 77, 288, 77, 443, 77, 77, 289, 443, + 77, 77, 290, 77, 77, 77, 443, 77, 77, 77, + 443, 77, 77, 443, 443, 77, 77, 443, 77, 77, + 77, 443, 77, 77, 77, 77, 77, 77, 443, 292, + 77, 77, 443, 77, 77, 291, 443, 77, 77, 443, + + 77, 77, 77, 443, 77, 77, 77, 77, 77, 77, + 443, 77, 77, 77, 443, 77, 77, 443, 443, 77, + 293, 443, 77, 77, 77, 443, 77, 77, 77, 77, + 77, 77, 443, 77, 77, 77, 443, 77, 77, 443, + 443, 77, 77, 443, 77, 77, 77, 443, 77, 77, + 77, 77, 77, 77, 443, 295, 77, 77, 443, 77, + 77, 294, 443, 77, 77, 296, 77, 77, 77, 443, + 77, 77, 77, 77, 77, 77, 443, 77, 77, 77, + 443, 77, 77, 443, 443, 77, 297, 443, 443, 77, + 77, 443, 77, 77, 77, 77, 443, 77, 77, 77, + + 443, 77, 77, 77, 77, 443, 298, 77, 77, 443, + 77, 77, 299, 443, 443, 443, 77, 443, 77, 77, + 77, 77, 77, 77, 77, 300, 77, 77, 443, 77, + 77, 77, 443, 443, 77, 77, 443, 443, 443, 77, + 301, 443, 77, 443, 77, 443, 77, 77, 443, 302, + 77, 77, 77, 77, 77, 303, 443, 77, 77, 77, + 443, 77, 77, 443, 443, 77, 443, 443, 443, 77, + 77, 306, 77, 443, 77, 443, 307, 77, 77, 77, + 77, 77, 77, 308, 443, 77, 77, 443, 443, 77, + 77, 77, 309, 443, 77, 77, 77, 77, 77, 77, + + 77, 77, 77, 443, 77, 77, 443, 77, 77, 443, + 443, 443, 77, 443, 443, 311, 77, 77, 77, 77, + 77, 77, 77, 310, 77, 77, 77, 77, 312, 77, + 77, 443, 443, 77, 77, 443, 313, 77, 77, 443, + 77, 443, 77, 314, 77, 77, 77, 77, 77, 77, + 443, 443, 77, 77, 443, 77, 77, 77, 443, 443, + 77, 77, 77, 443, 77, 77, 77, 443, 77, 443, + 77, 333, 443, 77, 77, 77, 443, 77, 77, 443, + 443, 77, 77, 443, 77, 77, 77, 77, 77, 334, + 335, 77, 77, 77, 77, 77, 443, 77, 77, 443, + + 336, 77, 443, 77, 337, 77, 77, 77, 77, 443, + 77, 77, 77, 77, 77, 77, 77, 77, 443, 443, + 77, 77, 443, 77, 77, 77, 443, 77, 443, 338, + 443, 77, 77, 77, 77, 443, 77, 339, 340, 77, + 77, 77, 77, 77, 77, 77, 443, 77, 77, 77, + 443, 443, 77, 342, 443, 443, 77, 341, 77, 443, + 77, 77, 77, 77, 443, 77, 77, 77, 77, 77, + 443, 77, 77, 443, 77, 77, 343, 443, 443, 77, + 77, 344, 77, 443, 77, 443, 77, 77, 345, 77, + 346, 77, 443, 443, 77, 77, 348, 77, 77, 77, + + 77, 347, 77, 77, 77, 443, 443, 77, 77, 443, + 443, 349, 77, 77, 443, 77, 77, 77, 77, 77, + 77, 77, 77, 350, 77, 77, 351, 443, 443, 77, + 77, 443, 443, 77, 77, 77, 443, 77, 77, 77, + 77, 77, 77, 77, 77, 443, 77, 77, 77, 443, + 352, 77, 77, 443, 443, 443, 77, 353, 443, 77, + 77, 77, 77, 77, 77, 354, 77, 77, 443, 77, + 355, 77, 443, 443, 77, 77, 77, 356, 77, 77, + 77, 443, 77, 443, 77, 443, 443, 77, 77, 77, + 443, 77, 77, 443, 443, 77, 77, 77, 77, 77, + + 77, 357, 77, 77, 77, 443, 77, 358, 443, 443, + 359, 77, 443, 77, 77, 77, 443, 77, 77, 361, + 77, 77, 77, 443, 77, 77, 77, 443, 77, 77, + 443, 443, 77, 77, 443, 77, 360, 77, 443, 77, + 77, 363, 77, 77, 77, 443, 77, 77, 77, 443, + 77, 77, 443, 443, 77, 443, 443, 362, 77, 77, + 364, 77, 443, 77, 443, 443, 77, 77, 77, 366, + 77, 77, 443, 77, 77, 443, 77, 77, 77, 77, + 443, 368, 77, 77, 365, 443, 77, 77, 443, 77, + 77, 77, 77, 77, 77, 443, 77, 77, 369, 77, + + 77, 370, 77, 443, 443, 443, 77, 443, 77, 77, + 371, 77, 443, 77, 77, 372, 77, 77, 77, 77, + 77, 77, 77, 443, 77, 77, 443, 443, 77, 77, + 443, 443, 77, 77, 443, 77, 443, 77, 373, 77, + 77, 77, 77, 77, 77, 443, 443, 77, 77, 443, + 374, 77, 77, 443, 77, 77, 443, 77, 77, 375, + 77, 77, 77, 77, 77, 77, 376, 377, 77, 77, + 77, 443, 77, 77, 77, 443, 443, 77, 77, 77, + 77, 77, 77, 77, 77, 443, 443, 77, 77, 77, + 77, 378, 77, 77, 379, 77, 443, 77, 77, 77, + + 77, 443, 77, 77, 77, 77, 443, 77, 77, 77, + 77, 380, 77, 77, 77, 77, 381, 383, 77, 77, + 77, 443, 77, 77, 77, 77, 382, 443, 77, 384, + 77, 443, 77, 443, 77, 77, 385, 77, 77, 77, + 77, 386, 77, 77, 77, 77, 443, 77, 77, 443, + 77, 77, 77, 443, 77, 77, 443, 443, 77, 443, + 77, 443, 77, 77, 77, 387, 388, 77, 77, 77, + 77, 443, 77, 77, 77, 77, 443, 77, 77, 389, + 77, 77, 443, 443, 443, 77, 77, 443, 77, 77, + 360, 77, 77, 77, 443, 77, 77, 390, 77, 77, + + 443, 77, 77, 443, 77, 77, 392, 77, 443, 391, + 77, 443, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 443, 397, 394, 77, 443, 443, 443, 77, 443, + 443, 77, 77, 393, 77, 396, 77, 77, 77, 443, + 443, 77, 77, 443, 77, 395, 443, 443, 77, 77, + 77, 77, 77, 77, 77, 77, 443, 443, 77, 77, + 77, 77, 398, 443, 443, 77, 77, 77, 77, 77, + 77, 77, 77, 443, 77, 77, 77, 77, 401, 443, + 77, 443, 443, 443, 77, 399, 400, 77, 77, 77, + 77, 77, 77, 443, 77, 77, 402, 77, 404, 77, + + 443, 443, 443, 77, 443, 443, 77, 77, 403, 443, + 77, 77, 405, 77, 443, 77, 77, 77, 77, 443, + 77, 406, 443, 443, 77, 77, 443, 77, 77, 77, + 443, 77, 77, 77, 77, 77, 77, 443, 77, 77, + 77, 443, 77, 77, 443, 443, 77, 77, 443, 77, + 77, 77, 443, 77, 443, 77, 443, 77, 77, 443, + 407, 77, 77, 443, 77, 77, 443, 443, 77, 77, + 77, 77, 77, 77, 443, 77, 77, 77, 443, 77, + 77, 408, 443, 77, 77, 443, 77, 77, 77, 443, + 77, 77, 77, 77, 410, 77, 443, 409, 77, 77, + + 443, 77, 77, 443, 443, 77, 443, 415, 443, 77, + 77, 443, 77, 443, 77, 443, 412, 77, 77, 77, + 77, 77, 77, 413, 443, 77, 77, 77, 443, 77, + 77, 443, 414, 77, 77, 443, 77, 77, 77, 443, + 77, 77, 443, 77, 77, 77, 77, 77, 419, 77, + 77, 77, 416, 420, 77, 77, 77, 443, 421, 77, + 77, 443, 77, 77, 77, 77, 77, 77, 443, 77, + 77, 77, 77, 77, 422, 443, 443, 77, 77, 443, + 77, 77, 77, 443, 77, 77, 443, 77, 424, 77, + 443, 77, 77, 77, 77, 77, 77, 443, 77, 77, + + 77, 443, 77, 77, 443, 443, 77, 77, 443, 77, + 77, 77, 443, 77, 443, 77, 443, 77, 77, 443, + 428, 77, 77, 443, 77, 77, 443, 443, 77, 77, + 443, 77, 77, 77, 77, 77, 443, 77, 77, 77, + 431, 443, 443, 77, 443, 443, 443, 77, 435, 443, + 77, 443, 443, 443, 443, 77, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 62, 443, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 65, 443, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, + 66, 66, 66, 66, 66, 66, 67, 443, 67, 67, + + 67, 67, 67, 67, 67, 67, 67, 70, 443, 443, + 443, 70, 70, 70, 70, 70, 71, 443, 443, 443, + 443, 443, 443, 71, 76, 76, 76, 76, 76, 76, + 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 175, 175, 175, 175, 175, 175, 175, 175, 176, + 176, 443, 176, 176, 173, 173, 443, 173, 7, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443 + } ; + +static yyconst flex_int16_t yy_chk[2520] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 3, 4, 4, 5, 5, 6, 6, 12, 16, + 23, 23, 62, 3, 67, 4, 150, 5, 150, 6, + 37, 404, 150, 3, 37, 4, 404, 5, 37, 6, + 37, 37, 16, 454, 150, 12, 37, 67, 141, 62, + + 141, 71, 71, 423, 23, 32, 451, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 34, 440, 438, 141, + 423, 32, 32, 34, 142, 437, 142, 34, 44, 44, + 34, 34, 32, 34, 34, 71, 32, 436, 44, 34, + 44, 222, 44, 432, 430, 142, 44, 429, 32, 33, + 51, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 51, 427, 51, 38, 51, 33, 33, 38, 51, 222, + 235, 38, 235, 426, 425, 38, 33, 38, 38, 418, + 33, 417, 415, 38, 33, 411, 33, 236, 237, 236, + 237, 235, 33, 35, 397, 367, 35, 35, 304, 61, + + 35, 35, 57, 35, 35, 27, 35, 35, 236, 237, + 26, 9, 35, 36, 36, 36, 36, 7, 36, 0, + 36, 36, 39, 0, 36, 39, 0, 0, 36, 39, + 36, 36, 0, 39, 40, 39, 36, 0, 40, 41, + 0, 39, 40, 41, 40, 0, 40, 41, 40, 41, + 43, 42, 40, 42, 40, 41, 0, 0, 42, 43, + 43, 43, 43, 42, 43, 42, 0, 42, 43, 54, + 45, 42, 45, 54, 54, 0, 0, 54, 0, 54, + 45, 152, 45, 152, 45, 54, 0, 152, 45, 46, + 46, 46, 155, 46, 155, 152, 46, 46, 155, 152, + + 46, 47, 0, 155, 46, 47, 46, 0, 46, 47, + 155, 47, 46, 0, 47, 0, 0, 47, 48, 0, + 0, 0, 0, 0, 48, 48, 140, 140, 140, 140, + 140, 140, 89, 0, 50, 48, 48, 48, 48, 48, + 48, 50, 89, 48, 89, 50, 89, 0, 0, 50, + 89, 50, 50, 48, 0, 0, 0, 50, 48, 49, + 92, 0, 49, 0, 0, 49, 49, 0, 0, 49, + 92, 0, 92, 49, 92, 49, 49, 49, 92, 53, + 49, 49, 49, 52, 0, 52, 53, 0, 52, 0, + 53, 0, 0, 0, 53, 52, 53, 52, 238, 52, + + 238, 0, 53, 52, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 0, 151, 0, 151, 0, 0, 238, + 151, 0, 0, 58, 58, 58, 0, 77, 58, 58, + 58, 77, 151, 151, 58, 77, 58, 77, 0, 0, + 58, 58, 58, 77, 58, 58, 78, 79, 0, 0, + 78, 79, 0, 0, 78, 79, 78, 79, 0, 0, + 80, 81, 78, 79, 80, 81, 0, 0, 80, 81, + 80, 81, 0, 0, 82, 82, 80, 81, 82, 83, + 83, 0, 82, 83, 82, 84, 0, 83, 84, 0, + 82, 83, 84, 83, 0, 0, 84, 85, 84, 83, + + 0, 85, 86, 0, 84, 85, 86, 85, 0, 0, + 86, 87, 86, 85, 0, 87, 88, 0, 86, 87, + 88, 87, 0, 90, 88, 0, 88, 87, 239, 0, + 239, 0, 88, 90, 0, 90, 93, 90, 0, 0, + 90, 90, 91, 91, 91, 0, 93, 0, 93, 239, + 93, 0, 94, 91, 93, 91, 94, 91, 0, 95, + 94, 91, 94, 95, 0, 0, 96, 95, 94, 95, + 96, 0, 0, 98, 96, 95, 96, 96, 0, 97, + 98, 0, 96, 97, 98, 0, 0, 97, 98, 97, + 98, 0, 0, 99, 99, 97, 98, 99, 240, 100, + + 240, 99, 100, 99, 0, 0, 100, 101, 0, 99, + 100, 101, 100, 0, 0, 101, 102, 101, 100, 240, + 102, 103, 0, 101, 102, 103, 102, 0, 0, 103, + 104, 103, 102, 0, 104, 105, 0, 103, 104, 105, + 104, 0, 0, 105, 0, 105, 104, 0, 106, 106, + 0, 105, 106, 107, 0, 0, 106, 107, 106, 0, + 0, 107, 108, 107, 106, 0, 108, 109, 109, 107, + 108, 109, 108, 0, 0, 109, 0, 109, 108, 0, + 110, 110, 111, 109, 110, 161, 161, 161, 110, 111, + 110, 161, 0, 111, 112, 161, 110, 111, 112, 111, + + 0, 0, 112, 161, 112, 111, 0, 112, 113, 114, + 112, 0, 113, 114, 0, 0, 113, 114, 113, 114, + 0, 114, 115, 116, 113, 114, 115, 116, 0, 115, + 115, 116, 115, 116, 0, 0, 117, 118, 115, 116, + 117, 118, 0, 0, 117, 118, 117, 118, 119, 118, + 119, 0, 117, 118, 119, 120, 0, 0, 119, 120, + 119, 119, 0, 120, 121, 120, 119, 0, 121, 0, + 0, 120, 121, 121, 121, 122, 0, 0, 123, 122, + 121, 0, 123, 122, 0, 122, 123, 122, 123, 124, + 0, 122, 125, 124, 123, 0, 0, 124, 128, 124, + + 124, 124, 125, 126, 125, 124, 125, 126, 127, 0, + 125, 126, 0, 126, 0, 0, 0, 0, 127, 126, + 127, 128, 127, 0, 0, 128, 127, 0, 129, 128, + 129, 128, 0, 0, 129, 130, 0, 128, 129, 130, + 129, 0, 0, 130, 0, 130, 129, 131, 131, 132, + 0, 130, 131, 132, 0, 0, 131, 132, 131, 132, + 0, 134, 133, 133, 131, 132, 133, 0, 0, 0, + 133, 134, 133, 134, 0, 134, 135, 135, 133, 134, + 0, 136, 0, 0, 136, 0, 0, 135, 0, 135, + 0, 135, 0, 0, 136, 135, 136, 0, 136, 137, + + 138, 162, 136, 162, 137, 138, 0, 162, 0, 137, + 138, 137, 138, 137, 138, 139, 139, 137, 138, 162, + 139, 0, 143, 0, 0, 139, 143, 139, 0, 139, + 143, 144, 143, 139, 0, 144, 145, 0, 143, 144, + 145, 144, 0, 0, 145, 0, 145, 144, 0, 146, + 146, 0, 145, 146, 0, 0, 147, 146, 147, 146, + 148, 0, 147, 147, 148, 146, 0, 147, 148, 0, + 148, 147, 0, 147, 147, 0, 148, 149, 149, 147, + 153, 149, 153, 0, 0, 149, 153, 149, 154, 0, + 154, 153, 0, 149, 154, 156, 154, 156, 153, 156, + + 0, 156, 0, 0, 0, 153, 154, 0, 157, 0, + 157, 0, 157, 156, 157, 158, 159, 158, 159, 158, + 0, 158, 159, 0, 159, 160, 157, 160, 0, 158, + 163, 160, 163, 158, 159, 0, 163, 160, 164, 0, + 164, 0, 0, 160, 164, 165, 0, 165, 163, 0, + 0, 165, 166, 167, 166, 167, 164, 0, 166, 167, + 164, 0, 165, 165, 0, 0, 0, 0, 0, 0, + 166, 167, 167, 168, 169, 168, 169, 168, 0, 168, + 169, 170, 169, 170, 171, 0, 171, 170, 0, 0, + 171, 168, 169, 170, 177, 178, 177, 178, 0, 170, + + 177, 178, 171, 179, 180, 179, 180, 0, 0, 179, + 180, 0, 177, 178, 181, 0, 181, 182, 0, 182, + 181, 179, 180, 182, 183, 184, 183, 184, 0, 0, + 183, 184, 181, 0, 185, 182, 185, 0, 0, 186, + 185, 186, 183, 184, 184, 186, 0, 187, 0, 187, + 0, 0, 185, 187, 188, 0, 188, 186, 188, 0, + 188, 189, 190, 189, 190, 187, 0, 189, 190, 191, + 0, 191, 188, 0, 0, 191, 192, 0, 192, 189, + 190, 0, 192, 193, 194, 193, 194, 191, 0, 193, + 194, 195, 0, 195, 192, 192, 0, 195, 196, 0, + + 196, 193, 194, 0, 196, 197, 198, 197, 198, 195, + 0, 197, 198, 199, 0, 199, 196, 0, 0, 199, + 200, 0, 200, 197, 198, 0, 200, 201, 202, 201, + 202, 199, 0, 201, 202, 203, 0, 203, 200, 0, + 0, 203, 204, 0, 204, 201, 202, 0, 204, 205, + 206, 205, 206, 203, 0, 205, 206, 207, 0, 207, + 204, 204, 0, 207, 208, 208, 208, 205, 206, 0, + 208, 209, 210, 209, 210, 207, 0, 209, 210, 211, + 0, 211, 208, 0, 0, 211, 209, 0, 0, 209, + 210, 0, 212, 213, 212, 213, 0, 211, 212, 213, + + 0, 214, 215, 214, 215, 0, 212, 214, 215, 0, + 212, 213, 213, 0, 0, 0, 217, 0, 217, 214, + 215, 216, 217, 216, 218, 216, 218, 216, 0, 219, + 218, 219, 0, 0, 217, 219, 0, 0, 0, 216, + 217, 0, 218, 0, 220, 0, 220, 219, 0, 219, + 220, 221, 223, 221, 223, 221, 0, 221, 223, 224, + 0, 224, 220, 0, 0, 224, 0, 0, 0, 221, + 223, 223, 225, 0, 225, 0, 225, 224, 225, 226, + 227, 226, 227, 226, 0, 226, 227, 0, 0, 228, + 225, 228, 228, 0, 229, 228, 229, 226, 227, 230, + + 229, 230, 231, 0, 231, 230, 0, 228, 231, 0, + 0, 0, 229, 0, 0, 231, 232, 230, 232, 233, + 231, 233, 232, 230, 234, 233, 234, 247, 232, 247, + 234, 0, 0, 247, 232, 0, 233, 233, 248, 0, + 248, 0, 234, 234, 248, 247, 249, 250, 249, 250, + 0, 0, 249, 250, 0, 251, 248, 251, 0, 0, + 252, 251, 252, 0, 249, 250, 252, 0, 253, 0, + 253, 253, 0, 251, 253, 254, 0, 254, 252, 0, + 0, 254, 255, 0, 255, 256, 253, 256, 255, 254, + 255, 256, 257, 254, 257, 258, 0, 258, 257, 0, + + 255, 258, 0, 256, 256, 259, 260, 259, 260, 0, + 257, 259, 260, 258, 261, 262, 261, 262, 0, 0, + 261, 262, 0, 259, 260, 263, 0, 263, 0, 261, + 0, 263, 261, 262, 264, 0, 264, 262, 264, 265, + 264, 265, 266, 263, 266, 265, 0, 267, 266, 267, + 0, 0, 264, 267, 0, 0, 268, 265, 268, 0, + 266, 269, 268, 269, 0, 267, 270, 269, 270, 271, + 0, 271, 270, 0, 268, 271, 269, 0, 0, 269, + 273, 270, 273, 0, 270, 0, 273, 271, 271, 272, + 272, 272, 0, 0, 275, 272, 275, 274, 273, 274, + + 275, 274, 276, 274, 276, 0, 0, 272, 276, 0, + 0, 277, 275, 277, 0, 274, 279, 277, 279, 278, + 276, 278, 279, 278, 280, 278, 280, 0, 0, 277, + 280, 0, 0, 281, 279, 281, 0, 278, 282, 281, + 282, 283, 280, 283, 282, 0, 284, 283, 284, 0, + 281, 281, 284, 0, 0, 0, 282, 282, 0, 283, + 285, 286, 285, 286, 284, 284, 285, 286, 0, 287, + 285, 287, 0, 0, 288, 287, 288, 287, 285, 286, + 288, 0, 289, 0, 289, 0, 0, 287, 289, 290, + 0, 290, 288, 0, 0, 290, 291, 292, 291, 292, + + 289, 289, 291, 292, 293, 0, 293, 290, 0, 0, + 293, 294, 0, 294, 291, 292, 0, 294, 295, 296, + 295, 296, 293, 0, 295, 296, 297, 0, 297, 294, + 0, 0, 297, 298, 0, 298, 295, 296, 0, 298, + 299, 300, 299, 300, 297, 0, 299, 300, 301, 0, + 301, 298, 0, 0, 301, 0, 0, 299, 299, 300, + 301, 302, 0, 302, 0, 0, 301, 302, 303, 303, + 303, 306, 0, 306, 303, 0, 307, 306, 307, 302, + 0, 308, 307, 308, 302, 0, 303, 308, 0, 306, + 309, 311, 309, 311, 307, 0, 309, 311, 309, 308, + + 310, 310, 310, 0, 0, 0, 310, 0, 309, 311, + 311, 312, 0, 312, 313, 312, 313, 312, 310, 314, + 313, 314, 333, 0, 333, 314, 0, 0, 333, 312, + 0, 0, 313, 334, 0, 334, 0, 314, 313, 334, + 333, 335, 336, 335, 336, 0, 0, 335, 336, 0, + 334, 334, 337, 0, 337, 338, 0, 338, 337, 335, + 336, 338, 339, 340, 339, 340, 337, 338, 339, 340, + 337, 0, 341, 338, 341, 0, 0, 342, 341, 342, + 339, 340, 343, 342, 343, 0, 0, 344, 343, 344, + 341, 341, 345, 344, 345, 342, 0, 346, 345, 346, + + 343, 0, 347, 346, 347, 344, 0, 349, 347, 349, + 345, 346, 348, 349, 348, 346, 348, 350, 348, 350, + 347, 0, 351, 350, 351, 349, 349, 0, 351, 351, + 348, 0, 352, 0, 352, 350, 352, 353, 352, 353, + 351, 353, 354, 353, 354, 355, 0, 355, 354, 0, + 352, 355, 356, 0, 356, 353, 0, 0, 356, 0, + 354, 0, 357, 355, 357, 356, 357, 358, 357, 358, + 356, 0, 359, 358, 359, 360, 0, 360, 359, 358, + 357, 360, 0, 0, 0, 358, 361, 0, 361, 362, + 359, 362, 361, 360, 0, 362, 363, 361, 363, 364, + + 0, 364, 363, 0, 361, 364, 363, 362, 0, 362, + 365, 0, 365, 368, 363, 368, 365, 364, 366, 368, + 366, 0, 371, 368, 366, 0, 0, 0, 365, 0, + 0, 368, 369, 366, 369, 370, 366, 370, 369, 0, + 0, 370, 371, 0, 371, 369, 0, 0, 371, 372, + 369, 372, 373, 370, 373, 372, 0, 0, 373, 374, + 371, 374, 374, 0, 0, 374, 375, 372, 375, 376, + 373, 376, 375, 0, 377, 376, 377, 374, 377, 0, + 377, 0, 0, 0, 375, 375, 376, 376, 378, 379, + 378, 379, 377, 0, 378, 379, 379, 380, 381, 380, + + 0, 0, 0, 380, 0, 0, 378, 379, 380, 0, + 382, 383, 382, 383, 0, 380, 382, 383, 381, 0, + 381, 383, 0, 0, 381, 384, 0, 384, 382, 383, + 0, 384, 385, 386, 385, 386, 381, 0, 385, 386, + 387, 0, 387, 384, 0, 0, 387, 388, 0, 388, + 385, 386, 0, 388, 0, 389, 0, 389, 387, 0, + 387, 389, 390, 0, 390, 388, 0, 0, 390, 391, + 392, 391, 392, 389, 0, 391, 392, 393, 0, 393, + 390, 391, 0, 393, 394, 0, 394, 391, 392, 0, + 394, 395, 396, 395, 396, 393, 0, 395, 396, 398, + + 0, 398, 394, 0, 0, 398, 0, 402, 0, 395, + 396, 0, 399, 0, 399, 0, 399, 398, 399, 400, + 401, 400, 401, 400, 0, 400, 401, 402, 0, 402, + 399, 0, 401, 402, 403, 0, 403, 400, 401, 0, + 403, 405, 0, 405, 406, 402, 406, 405, 405, 407, + 406, 407, 403, 407, 408, 407, 408, 0, 408, 405, + 408, 0, 406, 409, 410, 409, 410, 407, 0, 409, + 410, 412, 408, 412, 410, 0, 0, 412, 413, 0, + 413, 409, 410, 0, 413, 414, 0, 414, 412, 412, + 0, 414, 416, 419, 416, 419, 413, 0, 416, 419, + + 420, 0, 420, 414, 0, 0, 420, 421, 0, 421, + 416, 419, 0, 421, 0, 422, 0, 422, 420, 0, + 421, 422, 424, 0, 424, 421, 0, 0, 424, 428, + 0, 428, 431, 422, 431, 428, 0, 435, 431, 435, + 424, 0, 0, 435, 0, 0, 0, 428, 428, 0, + 431, 0, 0, 0, 0, 435, 444, 444, 444, 444, + 444, 444, 444, 444, 444, 444, 444, 445, 0, 445, + 445, 445, 445, 445, 445, 445, 445, 445, 446, 0, + 446, 446, 446, 446, 446, 446, 446, 446, 446, 447, + 447, 447, 447, 447, 447, 447, 448, 0, 448, 448, + + 448, 448, 448, 448, 448, 448, 448, 449, 0, 0, + 0, 449, 449, 449, 449, 449, 450, 0, 0, 0, + 0, 0, 0, 450, 452, 452, 452, 452, 452, 452, + 452, 452, 453, 453, 453, 453, 453, 453, 453, 453, + 453, 455, 455, 455, 455, 455, 455, 455, 455, 456, + 456, 0, 456, 456, 457, 457, 0, 457, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int bx_flex_debug; +int bx_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *bxtext; +#line 1 "lexer.l" +#line 2 "lexer.l" +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// + +#include +#include + +#ifdef WIN32 + #include + #define YY_NO_UNISTD_H +#endif + +#include "debug.h" +#if BX_DEBUGGER + +#include "parser.h" + +int bx_yyinput(char *buf, int max_size); +#undef YY_INPUT +#define YY_INPUT(buf, ret, max_size) (ret = bx_yyinput(buf, max_size)) + +static char *lex_input_ptr = NULL; +static unsigned lex_input_size = 0; + +#if BX_SUPPORT_X86_64 + #define LONG_MODE_8BL_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_8BL_REG); } + #define LONG_MODE_16B_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_16B_REG); } + #define LONG_MODE_32B_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_32B_REG); } + #define LONG_MODE_64B_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_64B_REG); } +#else + #define LONG_MODE_8BL_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } + #define LONG_MODE_16B_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } + #define LONG_MODE_32B_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } + #define LONG_MODE_64B_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } +#endif + + + +#line 1218 "" + +#define INITIAL 0 +#define EXAMINE 1 +#define DISASM 2 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int bxlex_destroy (void ); + +int bxget_debug (void ); + +void bxset_debug (int debug_flag ); + +YY_EXTRA_TYPE bxget_extra (void ); + +void bxset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *bxget_in (void ); + +void bxset_in (FILE * in_str ); + +FILE *bxget_out (void ); + +void bxset_out (FILE * out_str ); + +int bxget_leng (void ); + +char *bxget_text (void ); + +int bxget_lineno (void ); + +void bxset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int bxwrap (void ); +#else +extern int bxwrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( bxtext, bxleng, 1, bxout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( bxin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( bxin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, bxin))==0 && ferror(bxin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(bxin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int bxlex (void); + +#define YY_DECL int bxlex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after bxtext and bxleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 51 "lexer.l" + +#line 1404 "" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! bxin ) + bxin = stdin; + + if ( ! bxout ) + bxout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + bxensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + bx_create_buffer(bxin,YY_BUF_SIZE ); + } + + bx_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of bxtext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 2459 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 52 "lexer.l" +; // eat up whitespace + YY_BREAK +case 2: +YY_RULE_SETUP +#line 53 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SET); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 54 "lexer.l" +{ bxlval.bval = 1; return(BX_TOKEN_ON); } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 55 "lexer.l" +{ bxlval.bval = 0; return(BX_TOKEN_OFF); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 56 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_CRC); } + YY_BREAK +case 6: +#line 58 "lexer.l" +case 7: +#line 59 "lexer.l" +case 8: +YY_RULE_SETUP +#line 59 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_CONTINUE); } + YY_BREAK +case 9: +#line 61 "lexer.l" +case 10: +YY_RULE_SETUP +#line 61 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_STEPN); } + YY_BREAK +case 11: +#line 63 "lexer.l" +case 12: +#line 64 "lexer.l" +case 13: +YY_RULE_SETUP +#line 64 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_STEP_OVER); } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 65 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_LIST_BREAK); } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 66 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_VBREAKPOINT); } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 67 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_LBREAKPOINT); } + YY_BREAK +case 17: +#line 69 "lexer.l" +case 18: +#line 70 "lexer.l" +case 19: +YY_RULE_SETUP +#line 70 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PBREAKPOINT); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 71 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_INFO); } + YY_BREAK +case 21: +#line 73 "lexer.l" +case 22: +YY_RULE_SETUP +#line 73 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_CONTROL_REGS); } + YY_BREAK +case 23: +#line 75 "lexer.l" +case 24: +YY_RULE_SETUP +#line 75 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_DEBUG_REGS); } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 76 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SEGMENT_REGS); } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 77 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_R); } + YY_BREAK +case 27: +#line 79 "lexer.l" +case 28: +YY_RULE_SETUP +#line 79 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_REGS); } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 80 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_FPU); } + YY_BREAK +case 30: +#line 82 "lexer.l" +case 31: +YY_RULE_SETUP +#line 82 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SSE); } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 83 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_MMX); } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 84 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_CPU); } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 85 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_IDT); } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 86 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_IVT); } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 87 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_GDT); } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 88 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_LDT); } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 89 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TSS); } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 90 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TAB); } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 91 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_LINUX); } + YY_BREAK +case 41: +#line 93 "lexer.l" +case 42: +#line 94 "lexer.l" +case 43: +YY_RULE_SETUP +#line 94 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_DEL_BREAKPOINT); } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 95 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_ENABLE_BREAKPOINT); } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 96 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_DISABLE_BREAKPOINT); } + YY_BREAK +case 46: +#line 98 "lexer.l" +case 47: +#line 99 "lexer.l" +case 48: +YY_RULE_SETUP +#line 99 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_QUIT); } + YY_BREAK +case 49: +#line 101 "lexer.l" +case 50: +YY_RULE_SETUP +#line 101 "lexer.l" +{ BEGIN(EXAMINE); bxlval.sval = strdup(bxtext); return(BX_TOKEN_EXAMINE); } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 102 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_RESTORE); } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 103 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SETPMEM); } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 104 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_QUERY); } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 105 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PENDING); } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 106 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TAKE); } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 107 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_DMA); } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 108 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_IRQ); } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 109 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PIC); } + YY_BREAK +case 59: +#line 111 "lexer.l" +case 60: +YY_RULE_SETUP +#line 111 "lexer.l" +{ BEGIN(DISASM); bxlval.sval = strdup(bxtext); return(BX_TOKEN_DISASM); } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 112 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_HEX); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 113 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_INSTRUMENT); } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 114 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_STOP); } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 115 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_DOIT); } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 116 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TRACE); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 117 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TRACEREG); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 118 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TRACEMEM); } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 119 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SWITCH_MODE); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 120 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SIZE); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 121 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PTIME); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 122 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TIMEBP); } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 123 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_TIMEBP_ABSOLUTE); } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 124 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_RECORD); } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 125 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PLAYBACK); } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 126 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_MODEBP); } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 127 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PRINT_STACK); } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 128 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_WATCH); } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 129 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_UNWATCH); } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 130 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_READ); } + YY_BREAK +case 80: +YY_RULE_SETUP +#line 131 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_WRITE); } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 132 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SHOW); } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 133 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_LOAD_SYMBOLS); } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 134 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SYMBOLS); } + YY_BREAK +case 84: +YY_RULE_SETUP +#line 135 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_LIST_SYMBOLS); } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 136 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_GLOBAL); } + YY_BREAK +case 86: +YY_RULE_SETUP +#line 137 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_WHERE); } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 138 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PRINT_STRING); } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 139 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_NE2000); } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 140 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PAGE); } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 141 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_VGA); } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 142 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_PCI); } + YY_BREAK +case 92: +YY_RULE_SETUP +#line 143 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_ALL); } + YY_BREAK +case 93: +YY_RULE_SETUP +#line 144 "lexer.l" +{ bxlval.uval = BX_DBG_REG8L_AL; return(BX_TOKEN_8BL_REG);} + YY_BREAK +case 94: +YY_RULE_SETUP +#line 145 "lexer.l" +{ bxlval.uval = BX_DBG_REG8L_BL; return(BX_TOKEN_8BL_REG);} + YY_BREAK +case 95: +YY_RULE_SETUP +#line 146 "lexer.l" +{ bxlval.uval = BX_DBG_REG8L_CL; return(BX_TOKEN_8BL_REG);} + YY_BREAK +case 96: +YY_RULE_SETUP +#line 147 "lexer.l" +{ bxlval.uval = BX_DBG_REG8L_DL; return(BX_TOKEN_8BL_REG);} + YY_BREAK +case 97: +YY_RULE_SETUP +#line 148 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_SIL); } + YY_BREAK +case 98: +YY_RULE_SETUP +#line 149 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_DIL); } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 150 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_SPL); } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 151 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_BPL); } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 152 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R8); } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 153 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R9); } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 154 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R10); } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 155 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R11); } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 156 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R12); } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 157 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R13); } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 158 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R14); } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 159 "lexer.l" +{ LONG_MODE_8BL_REG(BX_DBG_REG8L_R15); } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 160 "lexer.l" +{ bxlval.uval = BX_DBG_REG8H_AH; return(BX_TOKEN_8BH_REG);} + YY_BREAK +case 110: +YY_RULE_SETUP +#line 161 "lexer.l" +{ bxlval.uval = BX_DBG_REG8H_BH; return(BX_TOKEN_8BH_REG);} + YY_BREAK +case 111: +YY_RULE_SETUP +#line 162 "lexer.l" +{ bxlval.uval = BX_DBG_REG8H_CH; return(BX_TOKEN_8BH_REG);} + YY_BREAK +case 112: +YY_RULE_SETUP +#line 163 "lexer.l" +{ bxlval.uval = BX_DBG_REG8H_DH; return(BX_TOKEN_8BH_REG);} + YY_BREAK +case 113: +YY_RULE_SETUP +#line 164 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_AX; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 114: +YY_RULE_SETUP +#line 165 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_BX; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 115: +YY_RULE_SETUP +#line 166 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_CX; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 116: +YY_RULE_SETUP +#line 167 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_DX; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 117: +YY_RULE_SETUP +#line 168 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_SI; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 118: +YY_RULE_SETUP +#line 169 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_DI; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 119: +YY_RULE_SETUP +#line 170 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_BP; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 120: +YY_RULE_SETUP +#line 171 "lexer.l" +{ bxlval.uval = BX_DBG_REG16_SP; return(BX_TOKEN_16B_REG);} + YY_BREAK +case 121: +YY_RULE_SETUP +#line 172 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R8); } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 173 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R9); } + YY_BREAK +case 123: +YY_RULE_SETUP +#line 174 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R10); } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 175 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R11); } + YY_BREAK +case 125: +YY_RULE_SETUP +#line 176 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R12); } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 177 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R13); } + YY_BREAK +case 127: +YY_RULE_SETUP +#line 178 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R14); } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 179 "lexer.l" +{ LONG_MODE_16B_REG(BX_DBG_REG16_R15); } + YY_BREAK +case 129: +YY_RULE_SETUP +#line 180 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_EAX; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 130: +YY_RULE_SETUP +#line 181 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_EBX; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 131: +YY_RULE_SETUP +#line 182 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_ECX; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 132: +YY_RULE_SETUP +#line 183 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_EDX; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 133: +YY_RULE_SETUP +#line 184 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_ESI; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 134: +YY_RULE_SETUP +#line 185 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_EDI; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 135: +YY_RULE_SETUP +#line 186 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_EBP; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 136: +YY_RULE_SETUP +#line 187 "lexer.l" +{ bxlval.uval = BX_DBG_REG32_ESP; return(BX_TOKEN_32B_REG);} + YY_BREAK +case 137: +YY_RULE_SETUP +#line 188 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R8); } + YY_BREAK +case 138: +YY_RULE_SETUP +#line 189 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R9); } + YY_BREAK +case 139: +YY_RULE_SETUP +#line 190 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R10); } + YY_BREAK +case 140: +YY_RULE_SETUP +#line 191 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R11); } + YY_BREAK +case 141: +YY_RULE_SETUP +#line 192 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R12); } + YY_BREAK +case 142: +YY_RULE_SETUP +#line 193 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R13); } + YY_BREAK +case 143: +YY_RULE_SETUP +#line 194 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R14); } + YY_BREAK +case 144: +YY_RULE_SETUP +#line 195 "lexer.l" +{ LONG_MODE_32B_REG(BX_DBG_REG32_R15); } + YY_BREAK +case 145: +YY_RULE_SETUP +#line 196 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RAX); } + YY_BREAK +case 146: +YY_RULE_SETUP +#line 197 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RBX); } + YY_BREAK +case 147: +YY_RULE_SETUP +#line 198 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RCX); } + YY_BREAK +case 148: +YY_RULE_SETUP +#line 199 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RDX); } + YY_BREAK +case 149: +YY_RULE_SETUP +#line 200 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RSI); } + YY_BREAK +case 150: +YY_RULE_SETUP +#line 201 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RDI); } + YY_BREAK +case 151: +YY_RULE_SETUP +#line 202 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RSP); } + YY_BREAK +case 152: +YY_RULE_SETUP +#line 203 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_RBP); } + YY_BREAK +case 153: +YY_RULE_SETUP +#line 204 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R8); } + YY_BREAK +case 154: +YY_RULE_SETUP +#line 205 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R9); } + YY_BREAK +case 155: +YY_RULE_SETUP +#line 206 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R10); } + YY_BREAK +case 156: +YY_RULE_SETUP +#line 207 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R11); } + YY_BREAK +case 157: +YY_RULE_SETUP +#line 208 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R12); } + YY_BREAK +case 158: +YY_RULE_SETUP +#line 209 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R13); } + YY_BREAK +case 159: +YY_RULE_SETUP +#line 210 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R14); } + YY_BREAK +case 160: +YY_RULE_SETUP +#line 211 "lexer.l" +{ LONG_MODE_64B_REG(BX_DBG_REG64_R15); } + YY_BREAK +case 161: +YY_RULE_SETUP +#line 212 "lexer.l" +{ return(BX_TOKEN_REG_IP); } + YY_BREAK +case 162: +YY_RULE_SETUP +#line 213 "lexer.l" +{ return(BX_TOKEN_REG_EIP);} + YY_BREAK +case 163: +YY_RULE_SETUP +#line 214 "lexer.l" +{ return(BX_TOKEN_REG_RIP);} + YY_BREAK +case 164: +YY_RULE_SETUP +#line 215 "lexer.l" +{ bxlval.uval = BX_DBG_SREG_CS; return(BX_TOKEN_CS); } + YY_BREAK +case 165: +YY_RULE_SETUP +#line 216 "lexer.l" +{ bxlval.uval = BX_DBG_SREG_ES; return(BX_TOKEN_ES); } + YY_BREAK +case 166: +YY_RULE_SETUP +#line 217 "lexer.l" +{ bxlval.uval = BX_DBG_SREG_SS; return(BX_TOKEN_SS); } + YY_BREAK +case 167: +YY_RULE_SETUP +#line 218 "lexer.l" +{ bxlval.uval = BX_DBG_SREG_DS; return(BX_TOKEN_DS); } + YY_BREAK +case 168: +YY_RULE_SETUP +#line 219 "lexer.l" +{ bxlval.uval = BX_DBG_SREG_FS; return(BX_TOKEN_FS); } + YY_BREAK +case 169: +YY_RULE_SETUP +#line 220 "lexer.l" +{ bxlval.uval = BX_DBG_SREG_GS; return(BX_TOKEN_GS); } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 221 "lexer.l" +{ bxlval.uval = 0; return (BX_TOKEN_FLAGS); } + YY_BREAK +case 171: +YY_RULE_SETUP +#line 222 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_HELP); } + YY_BREAK +case 172: +#line 224 "lexer.l" +case 173: +YY_RULE_SETUP +#line 224 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_CALC); } + YY_BREAK +case 174: +YY_RULE_SETUP +#line 225 "lexer.l" +{ BEGIN(INITIAL); bxlval.sval = strdup(bxtext); return(BX_TOKEN_XFORMAT); } + YY_BREAK +case 175: +YY_RULE_SETUP +#line 226 "lexer.l" +{ BEGIN(INITIAL); bxlval.sval = strdup(bxtext); return(BX_TOKEN_XFORMAT); } + YY_BREAK +case 176: +YY_RULE_SETUP +#line 227 "lexer.l" +{ BEGIN(INITIAL); bxlval.sval = strdup(bxtext); return(BX_TOKEN_DISFORMAT); } + YY_BREAK +case 177: +YY_RULE_SETUP +#line 228 "lexer.l" +{ return ('+'); } + YY_BREAK +case 178: +YY_RULE_SETUP +#line 229 "lexer.l" +{ return ('-'); } + YY_BREAK +case 179: +YY_RULE_SETUP +#line 230 "lexer.l" +{ return ('*'); } + YY_BREAK +case 180: +YY_RULE_SETUP +#line 231 "lexer.l" +{ return ('/'); } + YY_BREAK +case 181: +YY_RULE_SETUP +#line 232 "lexer.l" +{ return (BX_TOKEN_RSHIFT); } + YY_BREAK +case 182: +YY_RULE_SETUP +#line 233 "lexer.l" +{ return (BX_TOKEN_LSHIFT); } + YY_BREAK +case 183: +YY_RULE_SETUP +#line 234 "lexer.l" +{ return ('&'); } + YY_BREAK +case 184: +YY_RULE_SETUP +#line 235 "lexer.l" +{ return ('|'); } + YY_BREAK +case 185: +YY_RULE_SETUP +#line 236 "lexer.l" +{ return ('^'); } + YY_BREAK +case 186: +YY_RULE_SETUP +#line 237 "lexer.l" +{ return ('!'); } + YY_BREAK +case 187: +YY_RULE_SETUP +#line 238 "lexer.l" +{ return ('@'); } + YY_BREAK +case 188: +YY_RULE_SETUP +#line 239 "lexer.l" +{ return ('('); } + YY_BREAK +case 189: +YY_RULE_SETUP +#line 240 "lexer.l" +{ return (')'); } + YY_BREAK +case 190: +#line 242 "lexer.l" +case 191: +YY_RULE_SETUP +#line 242 "lexer.l" +{ bxlval.sval = strdup(bxtext+1); bxlval.sval[strlen(bxlval.sval)-1] = 0; return(BX_TOKEN_STRING); } + YY_BREAK +case 192: +YY_RULE_SETUP +#line 243 "lexer.l" +{ bxlval.uval = strtoull(bxtext, NULL, 16); return(BX_TOKEN_NUMERIC); } + YY_BREAK +case 193: +YY_RULE_SETUP +#line 244 "lexer.l" +{ bxlval.uval = strtoull(bxtext, NULL, 8); return(BX_TOKEN_NUMERIC); } + YY_BREAK +case 194: +YY_RULE_SETUP +#line 245 "lexer.l" +{ bxlval.uval = strtoull(bxtext, NULL, 10); return(BX_TOKEN_NUMERIC); } + YY_BREAK +case 195: +YY_RULE_SETUP +#line 246 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_COMMAND); } + YY_BREAK +case 196: +YY_RULE_SETUP +#line 247 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_SYMBOLNAME); } + YY_BREAK +case 197: +YY_RULE_SETUP +#line 248 "lexer.l" +{ bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } + YY_BREAK +case 198: +YY_RULE_SETUP +#line 249 "lexer.l" +{ return ('\n'); } + YY_BREAK +case 199: +/* rule 199 can match eol */ +YY_RULE_SETUP +#line 250 "lexer.l" +{ return ('\n'); } + YY_BREAK +case 200: +YY_RULE_SETUP +#line 251 "lexer.l" +; // eat up comments '//' + YY_BREAK +case 201: +YY_RULE_SETUP +#line 252 "lexer.l" +{ return(bxtext[0]); } + YY_BREAK +case 202: +YY_RULE_SETUP +#line 253 "lexer.l" +{ BEGIN(INITIAL); unput(*bxtext); } + YY_BREAK +case 203: +YY_RULE_SETUP +#line 254 "lexer.l" +ECHO; + YY_BREAK +#line 2446 "" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(EXAMINE): +case YY_STATE_EOF(DISASM): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed bxin at a new source and called + * bxlex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = bxin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( bxwrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * bxtext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of bxlex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + bxrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + bxrestart(bxin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) bxrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 443); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up bxtext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + bxrestart(bxin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( bxwrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve bxtext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void bxrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + bxensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + bx_create_buffer(bxin,YY_BUF_SIZE ); + } + + bx_init_buffer(YY_CURRENT_BUFFER,input_file ); + bx_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void bx_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * bxpop_buffer_state(); + * bxpush_buffer_state(new_buffer); + */ + bxensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + bx_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (bxwrap()) processing, but the only time this flag + * is looked at is after bxwrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void bx_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + bxin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE bx_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) bxalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in bx_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) bxalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in bx_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + bx_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with bx_create_buffer() + * + */ + void bx_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + bxfree((void *) b->yy_ch_buf ); + + bxfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a bxrestart() or at EOF. + */ + static void bx_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + bx_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then bx_init_buffer was _probably_ + * called from bxrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void bx_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + bx_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void bxpush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + bxensure_buffer_stack(); + + /* This block is copied from bx_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from bx_switch_to_buffer. */ + bx_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void bxpop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + bx_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + bx_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void bxensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)bxalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in bxensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)bxrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in bxensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE bx_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) bxalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in bx_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + bx_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to bxlex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * bx_scan_bytes() instead. + */ +YY_BUFFER_STATE bx_scan_string (yyconst char * yystr ) +{ + + return bx_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to bxlex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE bx_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) bxalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in bx_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = bx_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in bx_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up bxtext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + bxtext[bxleng] = (yy_hold_char); \ + (yy_c_buf_p) = bxtext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + bxleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int bxget_lineno (void) +{ + + return bxlineno; +} + +/** Get the input stream. + * + */ +FILE *bxget_in (void) +{ + return bxin; +} + +/** Get the output stream. + * + */ +FILE *bxget_out (void) +{ + return bxout; +} + +/** Get the length of the current token. + * + */ +int bxget_leng (void) +{ + return bxleng; +} + +/** Get the current token. + * + */ + +char *bxget_text (void) +{ + return bxtext; +} + +/** Set the current line number. + * @param line_number + * + */ +void bxset_lineno (int line_number ) +{ + + bxlineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see bx_switch_to_buffer + */ +void bxset_in (FILE * in_str ) +{ + bxin = in_str ; +} + +void bxset_out (FILE * out_str ) +{ + bxout = out_str ; +} + +int bxget_debug (void) +{ + return bx_flex_debug; +} + +void bxset_debug (int bdebug ) +{ + bx_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from bxlex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + bxin = stdin; + bxout = stdout; +#else + bxin = (FILE *) 0; + bxout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * bxlex_init() + */ + return 0; +} + +/* bxlex_destroy is for both reentrant and non-reentrant scanners. */ +int bxlex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + bx_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + bxpop_buffer_state(); + } + + /* Destroy the stack itself. */ + bxfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * bxlex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *bxalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *bxrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void bxfree (void * ptr ) +{ + free( (char *) ptr ); /* see bxrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 254 "lexer.l" + + + + int +bx_yyinput(char *buf, int max_size) +{ + int len; + + if (lex_input_size == 0) { + fprintf(stderr, "lex: no characters in string input buffer.\n"); + exit(1); + } + + len = strlen(lex_input_ptr) + 1; + if (len > max_size) + len = max_size; + + memcpy(buf, lex_input_ptr, len); + + return(len); +} + + void +bx_add_lex_input(char *buf) +{ + lex_input_ptr = buf; + lex_input_size = strlen(buf); + + // Since we're parsing from strings, flush out + // all current buffer state, so the next read + // requests from yyinput + + bx_flush_buffer( YY_CURRENT_BUFFER ); +} + +#endif /* if BX_DEBUGGER */ + diff --git a/bochs/bx_debug/lexer.l b/bochs/bx_debug/lexer.l new file mode 100644 index 00000000..ba69aca6 --- /dev/null +++ b/bochs/bx_debug/lexer.l @@ -0,0 +1,288 @@ +%{ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// + +#include +#include + +#ifdef WIN32 + #include + #define YY_NO_UNISTD_H +#endif + +#include "debug.h" +#if BX_DEBUGGER + +#include "parser.h" + +int bx_yyinput(char *buf, int max_size); +#undef YY_INPUT +#define YY_INPUT(buf, ret, max_size) (ret = bx_yyinput(buf, max_size)) + +static char *lex_input_ptr = NULL; +static unsigned lex_input_size = 0; + +#if BX_SUPPORT_X86_64 + #define LONG_MODE_8BL_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_8BL_REG); } + #define LONG_MODE_16B_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_16B_REG); } + #define LONG_MODE_32B_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_32B_REG); } + #define LONG_MODE_64B_REG(reg) \ + { bxlval.uval = reg; return(BX_TOKEN_64B_REG); } +#else + #define LONG_MODE_8BL_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } + #define LONG_MODE_16B_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } + #define LONG_MODE_32B_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } + #define LONG_MODE_64B_REG(reg) \ + { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } +#endif + +%} + +%x EXAMINE +%x DISASM + +%% +<*>[ \t]+ ; // eat up whitespace +set { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SET); } +on { bxlval.bval = 1; return(BX_TOKEN_ON); } +off { bxlval.bval = 0; return(BX_TOKEN_OFF); } +crc { bxlval.sval = strdup(bxtext); return(BX_TOKEN_CRC); } +c | +cont | +continue { bxlval.sval = strdup(bxtext); return(BX_TOKEN_CONTINUE); } +step | +s { bxlval.sval = strdup(bxtext); return(BX_TOKEN_STEPN); } +next | +n | +p { bxlval.sval = strdup(bxtext); return(BX_TOKEN_STEP_OVER); } +blist { bxlval.sval = strdup(bxtext); return(BX_TOKEN_LIST_BREAK); } +vb|vbreak { bxlval.sval = strdup(bxtext); return(BX_TOKEN_VBREAKPOINT); } +lb|lbreak { bxlval.sval = strdup(bxtext); return(BX_TOKEN_LBREAKPOINT); } +break | +b|pb | +pbreak { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PBREAKPOINT); } +info { bxlval.sval = strdup(bxtext); return(BX_TOKEN_INFO); } +cr | +creg { bxlval.sval = strdup(bxtext); return(BX_TOKEN_CONTROL_REGS); } +dr | +dreg { bxlval.sval = strdup(bxtext); return(BX_TOKEN_DEBUG_REGS); } +sreg { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SEGMENT_REGS); } +r { bxlval.sval = strdup(bxtext); return(BX_TOKEN_R); } +reg|regs | +registers { bxlval.sval = strdup(bxtext); return(BX_TOKEN_REGS); } +fp|fpu { bxlval.sval = strdup(bxtext); return(BX_TOKEN_FPU); } +sse | +xmm { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SSE); } +mmx { bxlval.sval = strdup(bxtext); return(BX_TOKEN_MMX); } +cpu { bxlval.sval = strdup(bxtext); return(BX_TOKEN_CPU); } +idt { bxlval.sval = strdup(bxtext); return(BX_TOKEN_IDT); } +ivt { bxlval.sval = strdup(bxtext); return(BX_TOKEN_IVT); } +gdt { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GDT); } +ldt { bxlval.sval = strdup(bxtext); return(BX_TOKEN_LDT); } +tss { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TSS); } +tab { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TAB); } +linux { bxlval.sval = strdup(bxtext); return(BX_TOKEN_LINUX); } +delete | +del | +d { bxlval.sval = strdup(bxtext); return(BX_TOKEN_DEL_BREAKPOINT); } +bpe { bxlval.sval = strdup(bxtext); return(BX_TOKEN_ENABLE_BREAKPOINT); } +bpd { bxlval.sval = strdup(bxtext); return(BX_TOKEN_DISABLE_BREAKPOINT); } +quit | +exit | +q { bxlval.sval = strdup(bxtext); return(BX_TOKEN_QUIT); } +x | +xp { BEGIN(EXAMINE); bxlval.sval = strdup(bxtext); return(BX_TOKEN_EXAMINE); } +restore { bxlval.sval = strdup(bxtext); return(BX_TOKEN_RESTORE); } +setpmem { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SETPMEM); } +query { bxlval.sval = strdup(bxtext); return(BX_TOKEN_QUERY); } +pending { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PENDING); } +take { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TAKE); } +dma { bxlval.sval = strdup(bxtext); return(BX_TOKEN_DMA); } +irq { bxlval.sval = strdup(bxtext); return(BX_TOKEN_IRQ); } +pic { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PIC); } +u | +disasm { BEGIN(DISASM); bxlval.sval = strdup(bxtext); return(BX_TOKEN_DISASM); } +hex { bxlval.sval = strdup(bxtext); return(BX_TOKEN_HEX); } +instrument { bxlval.sval = strdup(bxtext); return(BX_TOKEN_INSTRUMENT); } +stop { bxlval.sval = strdup(bxtext); return(BX_TOKEN_STOP); } +doit { bxlval.sval = strdup(bxtext); return(BX_TOKEN_DOIT); } +trace { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TRACE); } +trace-reg { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TRACEREG); } +trace-mem { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TRACEMEM); } +switch-mode { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SWITCH_MODE); } +size { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SIZE); } +ptime { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PTIME); } +sb { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TIMEBP); } +sba { bxlval.sval = strdup(bxtext); return(BX_TOKEN_TIMEBP_ABSOLUTE); } +record { bxlval.sval = strdup(bxtext); return(BX_TOKEN_RECORD); } +playback { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PLAYBACK); } +modebp { bxlval.sval = strdup(bxtext); return(BX_TOKEN_MODEBP); } +print-stack { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PRINT_STACK); } +watch { bxlval.sval = strdup(bxtext); return(BX_TOKEN_WATCH); } +unwatch { bxlval.sval = strdup(bxtext); return(BX_TOKEN_UNWATCH); } +read { bxlval.sval = strdup(bxtext); return(BX_TOKEN_READ); } +w|write { bxlval.sval = strdup(bxtext); return(BX_TOKEN_WRITE); } +show { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SHOW); } +ldsym { bxlval.sval = strdup(bxtext); return(BX_TOKEN_LOAD_SYMBOLS); } +symbols { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SYMBOLS); } +slist { bxlval.sval = strdup(bxtext); return(BX_TOKEN_LIST_SYMBOLS); } +global { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GLOBAL); } +where { bxlval.sval = strdup(bxtext); return(BX_TOKEN_WHERE); } +print-string { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PRINT_STRING); } +ne2k|ne2000 { bxlval.sval = strdup(bxtext); return(BX_TOKEN_NE2000); } +page { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PAGE); } +vga { bxlval.sval = strdup(bxtext); return(BX_TOKEN_VGA); } +pci { bxlval.sval = strdup(bxtext); return(BX_TOKEN_PCI); } +all { bxlval.sval = strdup(bxtext); return(BX_TOKEN_ALL); } +al { bxlval.uval = BX_DBG_REG8L_AL; return(BX_TOKEN_8BL_REG);} +bl { bxlval.uval = BX_DBG_REG8L_BL; return(BX_TOKEN_8BL_REG);} +cl { bxlval.uval = BX_DBG_REG8L_CL; return(BX_TOKEN_8BL_REG);} +dl { bxlval.uval = BX_DBG_REG8L_DL; return(BX_TOKEN_8BL_REG);} +sil { LONG_MODE_8BL_REG(BX_DBG_REG8L_SIL); } +dil { LONG_MODE_8BL_REG(BX_DBG_REG8L_DIL); } +spl { LONG_MODE_8BL_REG(BX_DBG_REG8L_SPL); } +bpl { LONG_MODE_8BL_REG(BX_DBG_REG8L_BPL); } +r8b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R8); } +r9b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R9); } +r10b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R10); } +r11b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R11); } +r12b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R12); } +r13b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R13); } +r14b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R14); } +r15b { LONG_MODE_8BL_REG(BX_DBG_REG8L_R15); } +ah { bxlval.uval = BX_DBG_REG8H_AH; return(BX_TOKEN_8BH_REG);} +bh { bxlval.uval = BX_DBG_REG8H_BH; return(BX_TOKEN_8BH_REG);} +ch { bxlval.uval = BX_DBG_REG8H_CH; return(BX_TOKEN_8BH_REG);} +dh { bxlval.uval = BX_DBG_REG8H_DH; return(BX_TOKEN_8BH_REG);} +ax { bxlval.uval = BX_DBG_REG16_AX; return(BX_TOKEN_16B_REG);} +bx { bxlval.uval = BX_DBG_REG16_BX; return(BX_TOKEN_16B_REG);} +cx { bxlval.uval = BX_DBG_REG16_CX; return(BX_TOKEN_16B_REG);} +dx { bxlval.uval = BX_DBG_REG16_DX; return(BX_TOKEN_16B_REG);} +si { bxlval.uval = BX_DBG_REG16_SI; return(BX_TOKEN_16B_REG);} +di { bxlval.uval = BX_DBG_REG16_DI; return(BX_TOKEN_16B_REG);} +bp { bxlval.uval = BX_DBG_REG16_BP; return(BX_TOKEN_16B_REG);} +sp { bxlval.uval = BX_DBG_REG16_SP; return(BX_TOKEN_16B_REG);} +r8w { LONG_MODE_16B_REG(BX_DBG_REG16_R8); } +r9w { LONG_MODE_16B_REG(BX_DBG_REG16_R9); } +r10w { LONG_MODE_16B_REG(BX_DBG_REG16_R10); } +r11w { LONG_MODE_16B_REG(BX_DBG_REG16_R11); } +r12w { LONG_MODE_16B_REG(BX_DBG_REG16_R12); } +r13w { LONG_MODE_16B_REG(BX_DBG_REG16_R13); } +r14w { LONG_MODE_16B_REG(BX_DBG_REG16_R14); } +r15w { LONG_MODE_16B_REG(BX_DBG_REG16_R15); } +eax { bxlval.uval = BX_DBG_REG32_EAX; return(BX_TOKEN_32B_REG);} +ebx { bxlval.uval = BX_DBG_REG32_EBX; return(BX_TOKEN_32B_REG);} +ecx { bxlval.uval = BX_DBG_REG32_ECX; return(BX_TOKEN_32B_REG);} +edx { bxlval.uval = BX_DBG_REG32_EDX; return(BX_TOKEN_32B_REG);} +esi { bxlval.uval = BX_DBG_REG32_ESI; return(BX_TOKEN_32B_REG);} +edi { bxlval.uval = BX_DBG_REG32_EDI; return(BX_TOKEN_32B_REG);} +ebp { bxlval.uval = BX_DBG_REG32_EBP; return(BX_TOKEN_32B_REG);} +esp { bxlval.uval = BX_DBG_REG32_ESP; return(BX_TOKEN_32B_REG);} +r8d { LONG_MODE_32B_REG(BX_DBG_REG32_R8); } +r9d { LONG_MODE_32B_REG(BX_DBG_REG32_R9); } +r10d { LONG_MODE_32B_REG(BX_DBG_REG32_R10); } +r11d { LONG_MODE_32B_REG(BX_DBG_REG32_R11); } +r12d { LONG_MODE_32B_REG(BX_DBG_REG32_R12); } +r13d { LONG_MODE_32B_REG(BX_DBG_REG32_R13); } +r14d { LONG_MODE_32B_REG(BX_DBG_REG32_R14); } +r15d { LONG_MODE_32B_REG(BX_DBG_REG32_R15); } +rax { LONG_MODE_64B_REG(BX_DBG_REG64_RAX); } +rbx { LONG_MODE_64B_REG(BX_DBG_REG64_RBX); } +rcx { LONG_MODE_64B_REG(BX_DBG_REG64_RCX); } +rdx { LONG_MODE_64B_REG(BX_DBG_REG64_RDX); } +rsi { LONG_MODE_64B_REG(BX_DBG_REG64_RSI); } +rdi { LONG_MODE_64B_REG(BX_DBG_REG64_RDI); } +rsp { LONG_MODE_64B_REG(BX_DBG_REG64_RSP); } +rbp { LONG_MODE_64B_REG(BX_DBG_REG64_RBP); } +r8 { LONG_MODE_64B_REG(BX_DBG_REG64_R8); } +r9 { LONG_MODE_64B_REG(BX_DBG_REG64_R9); } +r10 { LONG_MODE_64B_REG(BX_DBG_REG64_R10); } +r11 { LONG_MODE_64B_REG(BX_DBG_REG64_R11); } +r12 { LONG_MODE_64B_REG(BX_DBG_REG64_R12); } +r13 { LONG_MODE_64B_REG(BX_DBG_REG64_R13); } +r14 { LONG_MODE_64B_REG(BX_DBG_REG64_R14); } +r15 { LONG_MODE_64B_REG(BX_DBG_REG64_R15); } +ip { return(BX_TOKEN_REG_IP); } +eip { return(BX_TOKEN_REG_EIP);} +rip { return(BX_TOKEN_REG_RIP);} +cs { bxlval.uval = BX_DBG_SREG_CS; return(BX_TOKEN_CS); } +es { bxlval.uval = BX_DBG_SREG_ES; return(BX_TOKEN_ES); } +ss { bxlval.uval = BX_DBG_SREG_SS; return(BX_TOKEN_SS); } +ds { bxlval.uval = BX_DBG_SREG_DS; return(BX_TOKEN_DS); } +fs { bxlval.uval = BX_DBG_SREG_FS; return(BX_TOKEN_FS); } +gs { bxlval.uval = BX_DBG_SREG_GS; return(BX_TOKEN_GS); } +flags|eflags { bxlval.uval = 0; return (BX_TOKEN_FLAGS); } +h|help { bxlval.sval = strdup(bxtext); return(BX_TOKEN_HELP); } +\? | +calc { bxlval.sval = strdup(bxtext); return(BX_TOKEN_CALC); } +\/[0-9]+ { BEGIN(INITIAL); bxlval.sval = strdup(bxtext); return(BX_TOKEN_XFORMAT); } +\/[0-9]*[mxduotcsibhwg]+ { BEGIN(INITIAL); bxlval.sval = strdup(bxtext); return(BX_TOKEN_XFORMAT); } +\/[0-9]+ { BEGIN(INITIAL); bxlval.sval = strdup(bxtext); return(BX_TOKEN_DISFORMAT); } +"+" { return ('+'); } +"-" { return ('-'); } +"*" { return ('*'); } +"/" { return ('/'); } +">>" { return (BX_TOKEN_RSHIFT); } +"<<" { return (BX_TOKEN_LSHIFT); } +"&" { return ('&'); } +"|" { return ('|'); } +"^" { return ('^'); } +"!" { return ('!'); } +"@" { return ('@'); } +"(" { return ('('); } +")" { return (')'); } +\'([^\\\'\n]|(\\.))*\' | /* throw away leading and trailing \" */ +\"([^\\\"\n]|(\\.))*\" { bxlval.sval = strdup(bxtext+1); bxlval.sval[strlen(bxlval.sval)-1] = 0; return(BX_TOKEN_STRING); } +0x[0-9a-fA-F]+ { bxlval.uval = strtoull(bxtext, NULL, 16); return(BX_TOKEN_NUMERIC); } +0[0-7]+ { bxlval.uval = strtoull(bxtext, NULL, 8); return(BX_TOKEN_NUMERIC); } +[0-9]+ { bxlval.uval = strtoull(bxtext, NULL, 10); return(BX_TOKEN_NUMERIC); } +[a-z-]+ { bxlval.sval = strdup(bxtext); return(BX_TOKEN_COMMAND); } +$[a-zA-Z_][a-zA-Z0-9_]* { bxlval.sval = strdup(bxtext); return(BX_TOKEN_SYMBOLNAME); } +[A-Za-z_][A-Za-z0-9_]* { bxlval.sval = strdup(bxtext); return(BX_TOKEN_GENERIC); } +<*>";" { return ('\n'); } +<*>\n { return ('\n'); } +[#][^\n]* ; // eat up comments '//' +. { return(bxtext[0]); } +. { BEGIN(INITIAL); unput(*bxtext); } +%% + + int +bx_yyinput(char *buf, int max_size) +{ + int len; + + if (lex_input_size == 0) { + fprintf(stderr, "lex: no characters in string input buffer.\n"); + exit(1); + } + + len = strlen(lex_input_ptr) + 1; + if (len > max_size) + len = max_size; + + memcpy(buf, lex_input_ptr, len); + + return(len); +} + + void +bx_add_lex_input(char *buf) +{ + lex_input_ptr = buf; + lex_input_size = strlen(buf); + + // Since we're parsing from strings, flush out + // all current buffer state, so the next read + // requests from yyinput + + bx_flush_buffer( YY_CURRENT_BUFFER ); +} + +#endif /* if BX_DEBUGGER */ diff --git a/bochs/bx_debug/linux.cc b/bochs/bx_debug/linux.cc new file mode 100644 index 00000000..9bb860a4 --- /dev/null +++ b/bochs/bx_debug/linux.cc @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +#include + +#include "bochs.h" +#include "cpu/cpu.h" + +#if BX_DEBUGGER + +#define LOG_THIS genlog-> + +// for Linux segment numbers +// these numbers are from +#define KERNEL_CS 0x10 +#define USER_CS 0x18 + +void bx_dbg_info_linux_command(void) +{ + BX_INFO (("Info linux")); + bx_dbg_sreg_t cs; + BX_CPU(dbg_cpu)->dbg_get_sreg(&cs, BX_DBG_SREG_CS); + int cpu_mode = BX_CPU(dbg_cpu)->get_cpu_mode(); + + int mode; + if (cpu_mode >= BX_MODE_IA32_PROTECTED) { + // protected mode + if (cs.sel == KERNEL_CS) { + mode = 'k'; + fprintf (stderr, "Processor mode: kernel\n"); + } else if (cs.sel == USER_CS) { + fprintf (stderr, "Processor mode: user\n"); + mode = 'u'; + } else { + mode = '?'; + fprintf (stderr, "Processor mode: ??? protected=1 but unrecognized CS\n"); + } + } else { + mode = 'r'; + fprintf (stderr, "Processor mode: real-address mode, maybe during boot sequence\n"); + } + if (mode != 'u') return; + /* user mode, look through registers and memory to find our process ID */ +} + +class syscall_names_t { +#define MAX_SYSCALLS 200 + const char *syscall_names_linux[MAX_SYSCALLS]; +public: + syscall_names_t() { init (); } + void init(); + const char *get_name(int num); +}; + +void syscall_names_t::init() +{ + for (int i=0; i". */ + +#if (N_SYSCALLS > MAX_SYSCALLS) +#error MAX_SYSCALLS must exceed N_SYSCALLS from syscalls-linux.h +#endif +} + +const char *syscall_names_t::get_name(int n) +{ + if (n < 0 || n > N_SYSCALLS) return 0; + return syscall_names_linux[n]; +} + +syscall_names_t syscall_names; + +void bx_dbg_linux_syscall(unsigned which_cpu) +{ + Bit32u eax = BX_CPU(which_cpu)->get_reg32(BX_32BIT_REG_EAX); + const char *name = syscall_names.get_name(eax); + if (name) + fprintf (stderr, "linux system call %s (#%d)\n", name, eax); + else + fprintf (stderr, "system call (#%d) is out of range\n", eax); +} + +#endif /* if BX_DEBUGGER */ diff --git a/bochs/bx_debug/make-syscalls-linux.pl b/bochs/bx_debug/make-syscalls-linux.pl new file mode 100755 index 00000000..2ffc63ac --- /dev/null +++ b/bochs/bx_debug/make-syscalls-linux.pl @@ -0,0 +1,34 @@ +#!/usr/bin/perl +# +# tested with linux 2.2.14 +# reads , outputs syscalls-linux.h + +$date = `date`; +print < syscalls-linux.h +// +EOF + +$max = 0; +while () { + $line = $_; + next unless /#define __NR_[a-z]/; + s/.*NR_//; + undef $number; + ($name, $number) = split (/[\s]+/); + if ((length $number) < 1) { + die "bad line: $line"; + } + if ($number > $max) { $max = $number; } + print "DEF_SYSCALL($number, \"$name\")\n"; +} + +print "#define N_SYSCALLS $max\n"; diff --git a/bochs/bx_debug/parser.c b/bochs/bx_debug/parser.c new file mode 100644 index 00000000..ad883c22 --- /dev/null +++ b/bochs/bx_debug/parser.c @@ -0,0 +1,4029 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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, 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse bxparse +#define yylex bxlex +#define yyerror bxerror +#define yylval bxlval +#define yychar bxchar +#define yydebug bxdebug +#define yynerrs bxnerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + BX_TOKEN_8BH_REG = 258, + BX_TOKEN_8BL_REG = 259, + BX_TOKEN_16B_REG = 260, + BX_TOKEN_32B_REG = 261, + BX_TOKEN_64B_REG = 262, + BX_TOKEN_CS = 263, + BX_TOKEN_ES = 264, + BX_TOKEN_SS = 265, + BX_TOKEN_DS = 266, + BX_TOKEN_FS = 267, + BX_TOKEN_GS = 268, + BX_TOKEN_FLAGS = 269, + BX_TOKEN_ON = 270, + BX_TOKEN_OFF = 271, + BX_TOKEN_CONTINUE = 272, + BX_TOKEN_STEPN = 273, + BX_TOKEN_STEP_OVER = 274, + BX_TOKEN_NEXT_STEP = 275, + BX_TOKEN_SET = 276, + BX_TOKEN_DEBUGGER = 277, + BX_TOKEN_LIST_BREAK = 278, + BX_TOKEN_VBREAKPOINT = 279, + BX_TOKEN_LBREAKPOINT = 280, + BX_TOKEN_PBREAKPOINT = 281, + BX_TOKEN_DEL_BREAKPOINT = 282, + BX_TOKEN_ENABLE_BREAKPOINT = 283, + BX_TOKEN_DISABLE_BREAKPOINT = 284, + BX_TOKEN_INFO = 285, + BX_TOKEN_QUIT = 286, + BX_TOKEN_R = 287, + BX_TOKEN_REGS = 288, + BX_TOKEN_CPU = 289, + BX_TOKEN_FPU = 290, + BX_TOKEN_SSE = 291, + BX_TOKEN_MMX = 292, + BX_TOKEN_IDT = 293, + BX_TOKEN_IVT = 294, + BX_TOKEN_GDT = 295, + BX_TOKEN_LDT = 296, + BX_TOKEN_TSS = 297, + BX_TOKEN_TAB = 298, + BX_TOKEN_ALL = 299, + BX_TOKEN_LINUX = 300, + BX_TOKEN_DEBUG_REGS = 301, + BX_TOKEN_CONTROL_REGS = 302, + BX_TOKEN_SEGMENT_REGS = 303, + BX_TOKEN_EXAMINE = 304, + BX_TOKEN_XFORMAT = 305, + BX_TOKEN_DISFORMAT = 306, + BX_TOKEN_RESTORE = 307, + BX_TOKEN_SETPMEM = 308, + BX_TOKEN_SYMBOLNAME = 309, + BX_TOKEN_QUERY = 310, + BX_TOKEN_PENDING = 311, + BX_TOKEN_TAKE = 312, + BX_TOKEN_DMA = 313, + BX_TOKEN_IRQ = 314, + BX_TOKEN_HEX = 315, + BX_TOKEN_DISASM = 316, + BX_TOKEN_INSTRUMENT = 317, + BX_TOKEN_STRING = 318, + BX_TOKEN_STOP = 319, + BX_TOKEN_DOIT = 320, + BX_TOKEN_CRC = 321, + BX_TOKEN_TRACE = 322, + BX_TOKEN_TRACEREG = 323, + BX_TOKEN_TRACEMEM = 324, + BX_TOKEN_SWITCH_MODE = 325, + BX_TOKEN_SIZE = 326, + BX_TOKEN_PTIME = 327, + BX_TOKEN_TIMEBP_ABSOLUTE = 328, + BX_TOKEN_TIMEBP = 329, + BX_TOKEN_RECORD = 330, + BX_TOKEN_PLAYBACK = 331, + BX_TOKEN_MODEBP = 332, + BX_TOKEN_PRINT_STACK = 333, + BX_TOKEN_WATCH = 334, + BX_TOKEN_UNWATCH = 335, + BX_TOKEN_READ = 336, + BX_TOKEN_WRITE = 337, + BX_TOKEN_SHOW = 338, + BX_TOKEN_LOAD_SYMBOLS = 339, + BX_TOKEN_SYMBOLS = 340, + BX_TOKEN_LIST_SYMBOLS = 341, + BX_TOKEN_GLOBAL = 342, + BX_TOKEN_WHERE = 343, + BX_TOKEN_PRINT_STRING = 344, + BX_TOKEN_NUMERIC = 345, + BX_TOKEN_NE2000 = 346, + BX_TOKEN_PIC = 347, + BX_TOKEN_PAGE = 348, + BX_TOKEN_HELP = 349, + BX_TOKEN_CALC = 350, + BX_TOKEN_VGA = 351, + BX_TOKEN_PCI = 352, + BX_TOKEN_COMMAND = 353, + BX_TOKEN_GENERIC = 354, + BX_TOKEN_RSHIFT = 355, + BX_TOKEN_LSHIFT = 356, + BX_TOKEN_REG_IP = 357, + BX_TOKEN_REG_EIP = 358, + BX_TOKEN_REG_RIP = 359, + INDIRECT = 360, + NEG = 361, + NOT = 362 + }; +#endif +/* Tokens. */ +#define BX_TOKEN_8BH_REG 258 +#define BX_TOKEN_8BL_REG 259 +#define BX_TOKEN_16B_REG 260 +#define BX_TOKEN_32B_REG 261 +#define BX_TOKEN_64B_REG 262 +#define BX_TOKEN_CS 263 +#define BX_TOKEN_ES 264 +#define BX_TOKEN_SS 265 +#define BX_TOKEN_DS 266 +#define BX_TOKEN_FS 267 +#define BX_TOKEN_GS 268 +#define BX_TOKEN_FLAGS 269 +#define BX_TOKEN_ON 270 +#define BX_TOKEN_OFF 271 +#define BX_TOKEN_CONTINUE 272 +#define BX_TOKEN_STEPN 273 +#define BX_TOKEN_STEP_OVER 274 +#define BX_TOKEN_NEXT_STEP 275 +#define BX_TOKEN_SET 276 +#define BX_TOKEN_DEBUGGER 277 +#define BX_TOKEN_LIST_BREAK 278 +#define BX_TOKEN_VBREAKPOINT 279 +#define BX_TOKEN_LBREAKPOINT 280 +#define BX_TOKEN_PBREAKPOINT 281 +#define BX_TOKEN_DEL_BREAKPOINT 282 +#define BX_TOKEN_ENABLE_BREAKPOINT 283 +#define BX_TOKEN_DISABLE_BREAKPOINT 284 +#define BX_TOKEN_INFO 285 +#define BX_TOKEN_QUIT 286 +#define BX_TOKEN_R 287 +#define BX_TOKEN_REGS 288 +#define BX_TOKEN_CPU 289 +#define BX_TOKEN_FPU 290 +#define BX_TOKEN_SSE 291 +#define BX_TOKEN_MMX 292 +#define BX_TOKEN_IDT 293 +#define BX_TOKEN_IVT 294 +#define BX_TOKEN_GDT 295 +#define BX_TOKEN_LDT 296 +#define BX_TOKEN_TSS 297 +#define BX_TOKEN_TAB 298 +#define BX_TOKEN_ALL 299 +#define BX_TOKEN_LINUX 300 +#define BX_TOKEN_DEBUG_REGS 301 +#define BX_TOKEN_CONTROL_REGS 302 +#define BX_TOKEN_SEGMENT_REGS 303 +#define BX_TOKEN_EXAMINE 304 +#define BX_TOKEN_XFORMAT 305 +#define BX_TOKEN_DISFORMAT 306 +#define BX_TOKEN_RESTORE 307 +#define BX_TOKEN_SETPMEM 308 +#define BX_TOKEN_SYMBOLNAME 309 +#define BX_TOKEN_QUERY 310 +#define BX_TOKEN_PENDING 311 +#define BX_TOKEN_TAKE 312 +#define BX_TOKEN_DMA 313 +#define BX_TOKEN_IRQ 314 +#define BX_TOKEN_HEX 315 +#define BX_TOKEN_DISASM 316 +#define BX_TOKEN_INSTRUMENT 317 +#define BX_TOKEN_STRING 318 +#define BX_TOKEN_STOP 319 +#define BX_TOKEN_DOIT 320 +#define BX_TOKEN_CRC 321 +#define BX_TOKEN_TRACE 322 +#define BX_TOKEN_TRACEREG 323 +#define BX_TOKEN_TRACEMEM 324 +#define BX_TOKEN_SWITCH_MODE 325 +#define BX_TOKEN_SIZE 326 +#define BX_TOKEN_PTIME 327 +#define BX_TOKEN_TIMEBP_ABSOLUTE 328 +#define BX_TOKEN_TIMEBP 329 +#define BX_TOKEN_RECORD 330 +#define BX_TOKEN_PLAYBACK 331 +#define BX_TOKEN_MODEBP 332 +#define BX_TOKEN_PRINT_STACK 333 +#define BX_TOKEN_WATCH 334 +#define BX_TOKEN_UNWATCH 335 +#define BX_TOKEN_READ 336 +#define BX_TOKEN_WRITE 337 +#define BX_TOKEN_SHOW 338 +#define BX_TOKEN_LOAD_SYMBOLS 339 +#define BX_TOKEN_SYMBOLS 340 +#define BX_TOKEN_LIST_SYMBOLS 341 +#define BX_TOKEN_GLOBAL 342 +#define BX_TOKEN_WHERE 343 +#define BX_TOKEN_PRINT_STRING 344 +#define BX_TOKEN_NUMERIC 345 +#define BX_TOKEN_NE2000 346 +#define BX_TOKEN_PIC 347 +#define BX_TOKEN_PAGE 348 +#define BX_TOKEN_HELP 349 +#define BX_TOKEN_CALC 350 +#define BX_TOKEN_VGA 351 +#define BX_TOKEN_PCI 352 +#define BX_TOKEN_COMMAND 353 +#define BX_TOKEN_GENERIC 354 +#define BX_TOKEN_RSHIFT 355 +#define BX_TOKEN_LSHIFT 356 +#define BX_TOKEN_REG_IP 357 +#define BX_TOKEN_REG_EIP 358 +#define BX_TOKEN_REG_RIP 359 +#define INDIRECT 360 +#define NEG 361 +#define NOT 362 + + + + +/* Copy the first part of user declarations. */ +#line 5 "parser.y" + +#include +#include +#include "debug.h" + +#if BX_DEBUGGER + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 13 "parser.y" +{ + char *sval; + Bit64u uval; + bx_bool bval; +} +/* Line 187 of yacc.c. */ +#line 332 "y.tab.c" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 216 of yacc.c. */ +#line 345 "y.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int i) +#else +static int +YYID (i) + int i; +#endif +{ + return i; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 278 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 1493 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 122 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 54 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 266 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 517 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 362 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 115, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 118, 2, 2, 2, 2, 111, 2, + 119, 120, 109, 105, 2, 106, 2, 110, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 117, 2, + 2, 116, 2, 2, 121, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 112, 113, 114 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 6, 8, 10, 12, 14, 16, 18, + 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, + 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, + 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, + 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, + 119, 121, 125, 129, 133, 137, 140, 144, 148, 151, + 155, 158, 162, 166, 170, 173, 177, 181, 185, 188, + 193, 198, 203, 209, 215, 221, 224, 228, 232, 237, + 242, 248, 251, 255, 258, 261, 265, 270, 275, 278, + 283, 289, 295, 301, 307, 313, 319, 325, 328, 334, + 337, 341, 345, 348, 352, 357, 360, 363, 367, 371, + 375, 381, 387, 393, 399, 403, 407, 411, 415, 419, + 424, 428, 434, 442, 446, 450, 454, 455, 457, 460, + 463, 466, 469, 472, 475, 478, 482, 486, 490, 493, + 498, 502, 506, 509, 514, 520, 524, 528, 533, 537, + 540, 544, 549, 553, 558, 564, 568, 573, 579, 583, + 587, 591, 596, 600, 604, 608, 612, 616, 620, 624, + 628, 632, 636, 640, 644, 648, 652, 656, 660, 664, + 668, 672, 676, 680, 684, 688, 692, 696, 700, 704, + 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, + 748, 752, 756, 760, 764, 768, 772, 775, 779, 781, + 783, 785, 787, 789, 791, 793, 795, 797, 799, 801, + 805, 809, 813, 817, 821, 825, 829, 833, 837, 840, + 843, 847, 849, 851, 853, 855, 857, 859, 861, 863, + 865, 867, 869, 873, 877, 881, 885, 889, 893, 897, + 901, 905, 909, 912, 915, 918, 921 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int16 yyrhs[] = +{ + 123, 0, -1, 123, 124, -1, 124, -1, 143, -1, + 144, -1, 145, -1, 146, -1, 147, -1, 150, -1, + 152, -1, 153, -1, 154, -1, 155, -1, 156, -1, + 158, -1, 157, -1, 148, -1, 149, -1, 159, -1, + 160, -1, 161, -1, 162, -1, 163, -1, 164, -1, + 165, -1, 166, -1, 167, -1, 168, -1, 169, -1, + 170, -1, 171, -1, 135, -1, 136, -1, 137, -1, + 134, -1, 128, -1, 129, -1, 130, -1, 131, -1, + 138, -1, 139, -1, 133, -1, 132, -1, 140, -1, + 141, -1, 142, -1, 172, -1, 173, -1, -1, 115, + -1, 15, -1, 16, -1, 32, -1, 33, -1, 8, + -1, 9, -1, 10, -1, 11, -1, 12, -1, 13, + -1, 74, 90, 115, -1, 73, 90, 115, -1, 75, + 63, 115, -1, 76, 63, 115, -1, 77, 115, -1, + 83, 98, 115, -1, 83, 63, 115, -1, 83, 115, + -1, 93, 175, 115, -1, 72, 115, -1, 67, 125, + 115, -1, 68, 125, 115, -1, 69, 125, 115, -1, + 78, 115, -1, 78, 90, 115, -1, 79, 64, 115, + -1, 79, 17, 115, -1, 79, 115, -1, 79, 32, + 175, 115, -1, 79, 81, 175, 115, -1, 79, 82, + 175, 115, -1, 79, 32, 175, 175, 115, -1, 79, + 81, 175, 175, 115, -1, 79, 82, 175, 175, 115, + -1, 80, 115, -1, 80, 175, 115, -1, 84, 63, + 115, -1, 84, 63, 90, 115, -1, 84, 87, 63, + 115, -1, 84, 87, 63, 90, 115, -1, 88, 115, + -1, 89, 90, 115, -1, 17, 115, -1, 18, 115, + -1, 18, 90, 115, -1, 18, 44, 90, 115, -1, + 18, 90, 90, 115, -1, 19, 115, -1, 21, 61, + 125, 115, -1, 21, 54, 116, 90, 115, -1, 21, + 4, 116, 175, 115, -1, 21, 3, 116, 175, 115, + -1, 21, 5, 116, 175, 115, -1, 21, 6, 116, + 175, 115, -1, 21, 7, 116, 175, 115, -1, 21, + 127, 116, 175, 115, -1, 24, 115, -1, 24, 174, + 117, 174, 115, -1, 25, 115, -1, 25, 175, 115, + -1, 25, 63, 115, -1, 26, 115, -1, 26, 175, + 115, -1, 26, 109, 175, 115, -1, 23, 115, -1, + 86, 115, -1, 86, 63, 115, -1, 30, 26, 115, + -1, 30, 34, 115, -1, 30, 38, 151, 151, 115, + -1, 30, 39, 151, 151, 115, -1, 30, 40, 151, + 151, 115, -1, 30, 41, 151, 151, 115, -1, 30, + 43, 115, -1, 30, 42, 115, -1, 30, 14, 115, + -1, 30, 45, 115, -1, 30, 85, 115, -1, 30, + 85, 63, 115, -1, 30, 91, 115, -1, 30, 91, + 93, 90, 115, -1, 30, 91, 93, 90, 126, 90, + 115, -1, 30, 92, 115, -1, 30, 96, 115, -1, + 30, 97, 115, -1, -1, 90, -1, 126, 115, -1, + 35, 115, -1, 37, 115, -1, 36, 115, -1, 48, + 115, -1, 47, 115, -1, 46, 115, -1, 27, 90, + 115, -1, 28, 90, 115, -1, 29, 90, 115, -1, + 31, 115, -1, 49, 50, 175, 115, -1, 49, 50, + 115, -1, 49, 175, 115, -1, 49, 115, -1, 52, + 63, 63, 115, -1, 53, 90, 90, 90, 115, -1, + 55, 56, 115, -1, 57, 58, 115, -1, 57, 58, + 90, 115, -1, 57, 59, 115, -1, 61, 115, -1, + 61, 175, 115, -1, 61, 175, 175, 115, -1, 61, + 51, 115, -1, 61, 51, 175, 115, -1, 61, 51, + 175, 175, 115, -1, 61, 70, 115, -1, 61, 60, + 125, 115, -1, 61, 71, 116, 90, 115, -1, 62, + 64, 115, -1, 62, 98, 115, -1, 65, 90, 115, + -1, 66, 90, 90, 115, -1, 94, 31, 115, -1, + 94, 17, 115, -1, 94, 18, 115, -1, 94, 19, + 115, -1, 94, 24, 115, -1, 94, 25, 115, -1, + 94, 26, 115, -1, 94, 27, 115, -1, 94, 28, + 115, -1, 94, 29, 115, -1, 94, 23, 115, -1, + 94, 77, 115, -1, 94, 66, 115, -1, 94, 67, + 115, -1, 94, 68, 115, -1, 94, 69, 115, -1, + 94, 52, 115, -1, 94, 72, 115, -1, 94, 74, + 115, -1, 94, 73, 115, -1, 94, 78, 115, -1, + 94, 75, 115, -1, 94, 76, 115, -1, 94, 84, + 115, -1, 94, 86, 115, -1, 94, 126, 115, -1, + 94, 35, 115, -1, 94, 37, 115, -1, 94, 36, + 115, -1, 94, 48, 115, -1, 94, 47, 115, -1, + 94, 46, 115, -1, 94, 53, 115, -1, 94, 61, + 115, -1, 94, 79, 115, -1, 94, 80, 115, -1, + 94, 49, 115, -1, 94, 62, 115, -1, 94, 21, + 115, -1, 94, 93, 115, -1, 94, 30, 115, -1, + 94, 83, 115, -1, 94, 95, 115, -1, 94, 94, + 115, -1, 94, 115, -1, 95, 175, 115, -1, 90, + -1, 63, -1, 4, -1, 3, -1, 5, -1, 6, + -1, 7, -1, 127, -1, 102, -1, 103, -1, 104, + -1, 174, 105, 174, -1, 174, 106, 174, -1, 174, + 109, 174, -1, 174, 110, 174, -1, 174, 100, 174, + -1, 174, 101, 174, -1, 174, 107, 174, -1, 174, + 108, 174, -1, 174, 111, 174, -1, 118, 174, -1, + 106, 174, -1, 119, 174, 120, -1, 90, -1, 63, + -1, 4, -1, 3, -1, 5, -1, 6, -1, 7, + -1, 127, -1, 102, -1, 103, -1, 104, -1, 175, + 117, 175, -1, 175, 105, 175, -1, 175, 106, 175, + -1, 175, 109, 175, -1, 175, 110, 175, -1, 175, + 100, 175, -1, 175, 101, 175, -1, 175, 107, 175, + -1, 175, 108, 175, -1, 175, 111, 175, -1, 118, + 175, -1, 106, 175, -1, 109, 175, -1, 121, 175, + -1, 119, 175, 120, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 139, 139, 140, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 196, 197, 202, 203, 208, 209, 210, 211, 212, + 213, 218, 223, 231, 239, 247, 255, 260, 265, 273, + 281, 289, 297, 305, 313, 318, 326, 331, 336, 341, + 346, 351, 356, 361, 366, 371, 376, 384, 389, 394, + 399, 407, 415, 423, 431, 436, 441, 446, 454, 462, + 467, 472, 476, 480, 484, 488, 492, 499, 504, 509, + 514, 519, 524, 529, 534, 542, 550, 555, 563, 568, + 573, 578, 583, 588, 593, 598, 603, 608, 613, 618, + 623, 628, 633, 638, 643, 648, 656, 657, 660, 668, + 676, 684, 692, 700, 708, 716, 724, 731, 739, 747, + 752, 757, 762, 770, 778, 786, 794, 799, 804, 812, + 817, 822, 827, 832, 837, 842, 847, 852, 860, 865, + 873, 881, 889, 894, 899, 906, 911, 916, 921, 926, + 931, 936, 941, 946, 951, 956, 962, 968, 974, 982, + 987, 992, 997, 1002, 1007, 1012, 1017, 1022, 1027, 1032, + 1037, 1042, 1047, 1052, 1057, 1062, 1072, 1083, 1089, 1102, + 1107, 1117, 1122, 1138, 1150, 1160, 1165, 1173, 1191, 1192, + 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, + 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, + 1213, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, + 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, + 1238, 1239, 1240, 1241, 1242, 1243, 1244 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "BX_TOKEN_8BH_REG", "BX_TOKEN_8BL_REG", + "BX_TOKEN_16B_REG", "BX_TOKEN_32B_REG", "BX_TOKEN_64B_REG", + "BX_TOKEN_CS", "BX_TOKEN_ES", "BX_TOKEN_SS", "BX_TOKEN_DS", + "BX_TOKEN_FS", "BX_TOKEN_GS", "BX_TOKEN_FLAGS", "BX_TOKEN_ON", + "BX_TOKEN_OFF", "BX_TOKEN_CONTINUE", "BX_TOKEN_STEPN", + "BX_TOKEN_STEP_OVER", "BX_TOKEN_NEXT_STEP", "BX_TOKEN_SET", + "BX_TOKEN_DEBUGGER", "BX_TOKEN_LIST_BREAK", "BX_TOKEN_VBREAKPOINT", + "BX_TOKEN_LBREAKPOINT", "BX_TOKEN_PBREAKPOINT", + "BX_TOKEN_DEL_BREAKPOINT", "BX_TOKEN_ENABLE_BREAKPOINT", + "BX_TOKEN_DISABLE_BREAKPOINT", "BX_TOKEN_INFO", "BX_TOKEN_QUIT", + "BX_TOKEN_R", "BX_TOKEN_REGS", "BX_TOKEN_CPU", "BX_TOKEN_FPU", + "BX_TOKEN_SSE", "BX_TOKEN_MMX", "BX_TOKEN_IDT", "BX_TOKEN_IVT", + "BX_TOKEN_GDT", "BX_TOKEN_LDT", "BX_TOKEN_TSS", "BX_TOKEN_TAB", + "BX_TOKEN_ALL", "BX_TOKEN_LINUX", "BX_TOKEN_DEBUG_REGS", + "BX_TOKEN_CONTROL_REGS", "BX_TOKEN_SEGMENT_REGS", "BX_TOKEN_EXAMINE", + "BX_TOKEN_XFORMAT", "BX_TOKEN_DISFORMAT", "BX_TOKEN_RESTORE", + "BX_TOKEN_SETPMEM", "BX_TOKEN_SYMBOLNAME", "BX_TOKEN_QUERY", + "BX_TOKEN_PENDING", "BX_TOKEN_TAKE", "BX_TOKEN_DMA", "BX_TOKEN_IRQ", + "BX_TOKEN_HEX", "BX_TOKEN_DISASM", "BX_TOKEN_INSTRUMENT", + "BX_TOKEN_STRING", "BX_TOKEN_STOP", "BX_TOKEN_DOIT", "BX_TOKEN_CRC", + "BX_TOKEN_TRACE", "BX_TOKEN_TRACEREG", "BX_TOKEN_TRACEMEM", + "BX_TOKEN_SWITCH_MODE", "BX_TOKEN_SIZE", "BX_TOKEN_PTIME", + "BX_TOKEN_TIMEBP_ABSOLUTE", "BX_TOKEN_TIMEBP", "BX_TOKEN_RECORD", + "BX_TOKEN_PLAYBACK", "BX_TOKEN_MODEBP", "BX_TOKEN_PRINT_STACK", + "BX_TOKEN_WATCH", "BX_TOKEN_UNWATCH", "BX_TOKEN_READ", "BX_TOKEN_WRITE", + "BX_TOKEN_SHOW", "BX_TOKEN_LOAD_SYMBOLS", "BX_TOKEN_SYMBOLS", + "BX_TOKEN_LIST_SYMBOLS", "BX_TOKEN_GLOBAL", "BX_TOKEN_WHERE", + "BX_TOKEN_PRINT_STRING", "BX_TOKEN_NUMERIC", "BX_TOKEN_NE2000", + "BX_TOKEN_PIC", "BX_TOKEN_PAGE", "BX_TOKEN_HELP", "BX_TOKEN_CALC", + "BX_TOKEN_VGA", "BX_TOKEN_PCI", "BX_TOKEN_COMMAND", "BX_TOKEN_GENERIC", + "BX_TOKEN_RSHIFT", "BX_TOKEN_LSHIFT", "BX_TOKEN_REG_IP", + "BX_TOKEN_REG_EIP", "BX_TOKEN_REG_RIP", "'+'", "'-'", "'|'", "'^'", + "'*'", "'/'", "'&'", "INDIRECT", "NEG", "NOT", "'\\n'", "'='", "':'", + "'!'", "'('", "')'", "'@'", "$accept", "commands", "command", + "BX_TOKEN_TOGGLE_ON_OFF", "BX_TOKEN_REGISTERS", "BX_TOKEN_SEGREG", + "timebp_command", "record_command", "playback_command", "modebp_command", + "show_command", "page_command", "ptime_command", "trace_command", + "trace_reg_command", "trace_mem_command", "print_stack_command", + "watch_point_command", "symbol_command", "where_command", + "print_string_command", "continue_command", "stepN_command", + "step_over_command", "set_command", "breakpoint_command", + "blist_command", "slist_command", "info_command", "optional_numeric", + "regs_command", "fpu_regs_command", "mmx_regs_command", + "sse_regs_command", "segment_regs_command", "control_regs_command", + "debug_regs_command", "delete_command", "bpe_command", "bpd_command", + "quit_command", "examine_command", "restore_command", "setpmem_command", + "query_command", "take_command", "disassemble_command", + "instrument_command", "doit_command", "crc_command", "help_command", + "calc_command", "vexpression", "expression", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 43, 45, 124, 94, 42, + 47, 38, 360, 361, 362, 10, 61, 58, 33, 40, + 41, 64 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 122, 123, 123, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 125, 125, 126, 126, 127, 127, 127, 127, 127, + 127, 128, 128, 129, 130, 131, 132, 132, 132, 133, + 134, 135, 136, 137, 138, 138, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 140, 140, 140, + 140, 141, 142, 143, 144, 144, 144, 144, 145, 146, + 146, 146, 146, 146, 146, 146, 146, 147, 147, 147, + 147, 147, 147, 147, 147, 148, 149, 149, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 151, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 163, 163, 163, 164, 165, 166, 167, 167, 167, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 169, 169, + 170, 171, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 173, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 2, 3, 3, 2, 3, + 2, 3, 3, 3, 2, 3, 3, 3, 2, 4, + 4, 4, 5, 5, 5, 2, 3, 3, 4, 4, + 5, 2, 3, 2, 2, 3, 4, 4, 2, 4, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, + 3, 3, 2, 3, 4, 2, 2, 3, 3, 3, + 5, 5, 5, 5, 3, 3, 3, 3, 3, 4, + 3, 5, 7, 3, 3, 3, 0, 1, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 2, 4, + 3, 3, 2, 4, 5, 3, 3, 4, 3, 2, + 3, 4, 3, 4, 5, 3, 4, 5, 3, 3, + 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 53, 54, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 0, 3, 0, 36, 37, 38, 39, 43, + 42, 35, 32, 33, 34, 40, 41, 44, 45, 46, + 4, 5, 6, 7, 8, 17, 18, 9, 10, 11, + 12, 13, 14, 16, 15, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 47, 48, + 93, 0, 0, 94, 98, 0, 0, 0, 0, 0, + 55, 56, 57, 58, 59, 60, 0, 0, 0, 115, + 221, 220, 222, 223, 224, 219, 218, 226, 227, 228, + 0, 107, 0, 0, 225, 0, 244, 243, 245, 246, + 247, 242, 241, 249, 250, 251, 0, 0, 109, 0, + 0, 0, 248, 0, 242, 0, 112, 0, 0, 0, + 0, 0, 0, 0, 136, 136, 136, 136, 0, 0, + 0, 0, 0, 0, 0, 0, 148, 139, 141, 140, + 144, 143, 142, 0, 152, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, + 0, 51, 52, 0, 0, 0, 70, 0, 0, 0, + 0, 65, 0, 74, 0, 0, 0, 0, 0, 78, + 85, 0, 0, 0, 68, 0, 0, 0, 116, 91, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 216, 0, 0, 1, 2, + 138, 0, 0, 95, 0, 0, 0, 0, 0, 0, + 0, 0, 239, 238, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 111, 263, 264, 262, 0, + 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 110, 0, 264, 113, 145, 146, 147, 126, 118, 119, + 137, 136, 136, 136, 136, 125, 124, 127, 0, 128, + 0, 130, 133, 134, 135, 150, 0, 151, 0, 0, + 155, 0, 156, 158, 162, 0, 0, 165, 0, 0, + 0, 160, 0, 168, 169, 170, 0, 71, 72, 73, + 62, 61, 63, 64, 75, 77, 0, 76, 0, 0, + 86, 67, 66, 0, 87, 0, 117, 92, 69, 173, + 174, 175, 210, 182, 176, 177, 178, 179, 180, 181, + 212, 172, 198, 200, 199, 203, 202, 201, 208, 188, + 204, 205, 209, 184, 185, 186, 187, 189, 191, 190, + 193, 194, 183, 192, 206, 207, 213, 195, 196, 211, + 215, 214, 197, 217, 96, 97, 0, 0, 0, 0, + 0, 0, 99, 0, 240, 233, 234, 229, 230, 235, + 236, 231, 232, 237, 0, 266, 257, 258, 253, 254, + 259, 260, 255, 256, 261, 252, 114, 0, 0, 0, + 0, 129, 0, 149, 153, 0, 157, 163, 0, 166, + 0, 254, 255, 161, 171, 79, 0, 80, 0, 81, + 0, 88, 0, 89, 102, 101, 103, 104, 105, 100, + 106, 108, 120, 121, 122, 123, 131, 0, 154, 164, + 167, 82, 83, 84, 90, 0, 132 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 52, 53, 203, 54, 152, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 331, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 135, 153 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -161 +static const yytype_int16 yypact[] = +{ + 1101, -84, -34, -77, 538, -73, 854, 575, 646, -26, + -20, -17, 1253, -71, -161, -161, -69, -41, -40, -39, + -38, -35, 527, 3, -8, 34, -25, 505, -43, 1, + 2, 21, 21, 21, -13, 13, 14, 48, 49, 11, + -76, -14, 694, -50, -47, -46, 12, 24, 843, 1182, + 843, -161, 1020, -161, 17, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, 39, -68, -161, -161, 18, 19, 20, 22, 25, + -161, -161, -161, -161, -161, -161, 29, 21, 30, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + 915, -161, 915, 915, -161, 563, -161, -161, -161, -161, + -161, 32, -161, -161, -161, -161, 843, 843, -161, 843, + 843, 843, -161, 301, -161, 843, -161, 452, 45, 46, + 47, 50, 51, 52, 43, 43, 43, 43, 62, 66, + 67, -44, -70, 68, 70, 72, -161, -161, -161, -161, + -161, -161, -161, 714, -161, 874, 74, 73, 85, -66, + 86, 782, 21, 88, 89, -161, 112, 91, 92, 109, + 98, -161, -161, 110, 111, 113, -161, 117, 119, 120, + 122, -161, 123, -161, 124, 843, 125, 843, 843, -161, + -161, 887, 126, 127, -161, -64, 101, 128, -161, -161, + 129, 1199, 130, 143, 144, 145, 147, 151, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 167, 168, 170, + 171, 172, 173, 174, 175, 176, 177, 188, 198, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 223, 224, 225, 226, -161, 227, 1212, -161, -161, + -161, 228, 229, -161, 843, 843, 843, 843, 843, 114, + 230, 843, -161, -161, -48, 915, 915, 915, 915, 915, + 915, 915, 915, 915, 915, -161, 232, 232, 232, -22, + 232, 843, 843, 843, 843, 843, 843, 843, 843, 843, + -161, 843, -85, -161, -161, -161, -161, -161, -161, -161, + -161, 43, 43, 43, 43, -161, -161, -161, 231, -161, + 257, -161, -161, -161, -161, -161, 1225, -161, 235, 261, + -161, 239, -161, -161, -161, 146, 240, -161, 266, 843, + 843, -161, 1246, -161, -161, -161, 253, -161, -161, -161, + -161, -161, -161, -161, -161, -161, 324, -161, 354, 386, + -161, -161, -161, 255, -161, -61, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, 1259, 1272, 1285, 1298, + 1311, 260, -161, 1324, -161, -161, -161, -1, -1, -1, + -1, -161, -161, -161, 273, -161, 232, 232, -4, -4, + -4, -4, 232, 232, 232, 634, -161, 262, 270, 271, + 285, -161, -21, -161, -161, 288, -161, -161, 1337, -161, + 289, 69, 232, -161, -161, -161, 1350, -161, 1363, -161, + 1376, -161, 290, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, 286, -161, -161, + -161, -161, -161, -161, -161, 298, -161 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -161, -161, 363, -24, -49, -2, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -160, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -161, -161, -161, -161, -161, -161, -161, -161, + -161, -161, -105, -7 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -264 +static const yytype_int16 yytable[] = +{ + 276, 157, 118, 214, 134, 332, 333, 334, 204, 205, + 101, 14, 15, 222, 212, 185, 225, 227, 215, 338, + 196, 197, 282, 340, 351, 292, 383, 293, 294, 492, + 466, 100, 321, 189, 190, 221, 201, 202, 104, 213, + 226, 231, 119, 277, 176, 341, 177, 283, 223, 352, + 216, 384, 295, 296, 493, 198, 102, 297, 298, 299, + 300, 301, 302, 303, 158, 224, 186, 217, 218, 228, + 159, 339, 444, 160, 178, 179, 180, 181, 311, 312, + 182, 103, 187, 313, 314, 315, 316, 317, 318, 319, + 188, 199, 200, 290, 506, 321, 311, 312, 455, 295, + 296, 219, 206, 207, 208, 317, 318, 319, 301, 302, + 303, 209, 210, 321, 230, 136, 137, 138, 139, 140, + 110, 111, 112, 113, 114, 115, 211, 229, 134, 281, + 134, 134, 280, 330, 284, 285, 286, 348, 287, 306, + 307, 288, 308, 309, 310, 289, 291, 305, 322, 136, + 137, 138, 139, 140, 110, 111, 112, 113, 114, 115, + 324, 325, 326, 349, 385, 327, 328, 329, 356, -263, + -263, 467, 468, 469, 470, 154, 346, 335, -263, -263, + -263, 336, 337, 342, 355, 343, 321, 344, 366, 362, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 350, 353, 142, 357, 441, 358, 363, 364, 376, 154, + 378, 379, 311, 312, 143, 144, 145, 313, 359, 315, + 316, 360, 318, 319, 365, 367, 368, 361, 369, 321, + 149, 150, 370, 151, 371, 372, 142, 373, 374, 375, + 377, 381, 382, 386, 387, 389, 311, 312, 143, 144, + 145, 313, 359, 315, 316, 360, 318, 319, 390, 391, + 392, 477, 393, 321, 149, 150, 394, 151, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 436, 437, 438, + 439, 440, 404, 405, 443, 406, 407, 408, 409, 410, + 411, 412, 413, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 414, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 415, 465, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 136, 137, 138, + 139, 140, 110, 111, 112, 113, 114, 115, 428, 429, + 430, 431, 432, 434, 435, 442, 471, 472, 478, 321, + 474, 475, 481, 482, 476, 479, 480, 136, 137, 138, + 139, 140, 110, 111, 112, 113, 114, 115, 484, 486, + 491, 488, 490, 295, 296, 499, 515, 502, 297, 298, + 299, 300, 301, 302, 303, 503, 504, 154, 501, 136, + 137, 138, 139, 140, 110, 111, 112, 113, 114, 115, + 505, 311, 312, 508, 510, 514, 313, 314, 315, 316, + 317, 318, 319, 516, 142, 279, 320, 154, 321, 0, + 0, 0, 0, 507, 311, 312, 143, 144, 145, 313, + 359, 315, 316, 360, 318, 319, 0, 0, 0, 485, + 0, 321, 149, 150, 142, 151, 0, 0, 0, 154, + 0, 0, 0, 0, 311, 312, 143, 144, 145, 313, + 359, 315, 316, 360, 318, 319, 0, 0, 0, 487, + 0, 321, 149, 150, 0, 151, 142, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 311, 312, 143, 144, + 145, 313, 359, 315, 316, 360, 318, 319, 0, 0, + 0, 489, 0, 321, 149, 150, 0, 151, 136, 137, + 138, 139, 140, 110, 111, 112, 113, 114, 115, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 136, 137, 138, 139, 140, 110, 111, 112, 113, 114, + 115, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 311, 312, 0, 0, 191, 313, 314, 315, + 316, 317, 318, 319, 0, 192, 0, 323, 154, 321, + 0, 0, 0, 0, 0, 193, 194, 183, 136, 137, + 138, 139, 140, 110, 111, 112, 113, 114, 115, 0, + 154, 0, 116, 0, 0, 142, 0, 0, 0, 117, + 0, 0, 0, 0, 0, 0, 0, 143, 144, 145, + 0, 146, 0, 0, 147, 0, 0, 142, 0, 0, + 195, 0, 0, 149, 150, 0, 151, 0, 0, 143, + 144, 145, 0, 146, 0, 0, 147, 0, 141, 0, + 0, 0, 184, 0, 0, 149, 150, 0, 151, 136, + 137, 138, 139, 140, 110, 111, 112, 113, 114, 115, + 0, 0, 0, 295, 296, 142, 0, 0, 297, 298, + 299, 300, 301, 302, 303, 0, 0, 143, 144, 145, + 304, 146, 0, 0, 147, 0, 0, 0, 0, 0, + 148, 0, 0, 149, 150, 0, 151, 136, 137, 138, + 139, 140, 110, 111, 112, 113, 114, 115, 0, 154, + 0, 0, 0, 0, 0, 0, 0, 136, 137, 138, + 139, 140, 110, 111, 112, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 311, 312, 142, 0, 0, 313, + 314, 315, 316, 317, 318, 319, 0, 0, 143, 144, + 145, 321, 146, 0, 0, 155, 0, 154, 0, 0, + 0, 156, 0, 0, 149, 150, 0, 151, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, + 0, 0, 0, 0, 142, 136, 137, 138, 139, 140, + 110, 111, 112, 113, 114, 115, 143, 144, 145, 0, + 146, 0, 0, 147, 142, 0, 0, 0, 0, 220, + 0, 0, 149, 150, 0, 151, 143, 144, 145, 0, + 146, 0, 0, 147, 0, 0, 0, 0, 0, 345, + 0, 0, 149, 150, 0, 151, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 154, 136, 137, 138, 139, + 140, 110, 111, 112, 113, 114, 115, 120, 121, 122, + 123, 124, 110, 111, 112, 113, 114, 115, 0, 0, + 0, 0, 142, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 143, 144, 145, 0, 146, 0, + 0, 147, 0, 0, 0, 0, 0, 354, 0, 0, + 149, 150, 0, 151, 0, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125, 120, 121, + 122, 123, 124, 110, 111, 112, 113, 114, 115, 0, + 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 126, 143, 144, 145, 0, 146, + 0, 0, 147, 0, 0, 0, 127, 128, 129, 0, + 130, 149, 150, 0, 151, 0, 0, 0, 0, 131, + 0, 0, 132, 133, 311, 312, 0, 0, 125, 313, + 314, 315, 316, 317, 318, 319, 0, 311, 312, 347, + 0, 321, 313, 314, 315, 316, 317, 318, 319, 0, + 0, 0, 380, 0, 321, 126, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 127, 128, 129, + 278, 130, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 132, 133, 0, 0, 1, 2, 3, + 0, 4, 0, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 16, 17, 18, 0, 0, + 0, 0, 0, 0, 0, 0, 19, 20, 21, 22, + 0, 0, 23, 24, 0, 25, 0, 26, 0, 0, + 0, 27, 28, 0, 0, 29, 30, 31, 32, 33, + 0, 0, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 0, 0, 43, 44, 0, 45, 0, 46, 47, + 0, 0, 0, 48, 49, 50, 0, 0, 1, 2, + 3, 0, 4, 0, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 51, 16, 17, 18, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 20, 21, + 22, 0, 0, 23, 24, 0, 25, 0, 26, 0, + 0, 0, 27, 28, 0, 0, 29, 30, 31, 32, + 33, 0, 0, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 0, 0, 43, 44, 0, 45, 0, 46, + 47, 0, 0, 0, 48, 49, 50, 0, 0, 232, + 233, 234, 0, 235, 0, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 14, 15, 51, 245, 246, 247, + 0, 0, 0, 0, 0, 0, 0, 0, 248, 249, + 250, 251, 0, 0, 252, 253, 0, 0, 0, 0, + 0, 0, 0, 254, 255, 0, 0, 0, 256, 257, + 258, 259, 0, 0, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 0, 0, 269, 270, 161, 271, 0, + 0, 0, 0, 0, 0, 272, 273, 274, 0, 162, + 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, + 0, 164, 165, 166, 167, 168, 169, 275, 170, 311, + 312, 0, 0, 0, 313, 314, 315, 316, 317, 318, + 319, 0, 311, 312, 388, 0, 321, 313, 314, 315, + 316, 317, 318, 319, 0, 311, 312, 433, 0, 321, + 313, 314, 315, 316, 317, 318, 319, 0, 171, 0, + 473, 0, 321, 0, 172, 173, 311, 312, 0, 174, + 175, 313, 314, 315, 316, 317, 318, 319, 0, 311, + 312, 483, 0, 321, 313, 314, 315, 316, 317, 318, + 319, 0, 311, 312, 494, 0, 321, 313, 314, 315, + 316, 317, 318, 319, 0, 311, 312, 495, 0, 321, + 313, 314, 315, 316, 317, 318, 319, 0, 311, 312, + 496, 0, 321, 313, 314, 315, 316, 317, 318, 319, + 0, 311, 312, 497, 0, 321, 313, 314, 315, 316, + 317, 318, 319, 0, 311, 312, 498, 0, 321, 313, + 314, 315, 316, 317, 318, 319, 0, 311, 312, 500, + 0, 321, 313, 314, 315, 316, 317, 318, 319, 0, + 311, 312, 509, 0, 321, 313, 314, 315, 316, 317, + 318, 319, 0, 311, 312, 511, 0, 321, 313, 314, + 315, 316, 317, 318, 319, 0, 311, 312, 512, 0, + 321, 313, 314, 315, 316, 317, 318, 319, 0, 0, + 0, 513, 0, 321 +}; + +static const yytype_int16 yycheck[] = +{ + 49, 8, 4, 17, 6, 165, 166, 167, 32, 33, + 44, 32, 33, 63, 90, 22, 63, 63, 32, 63, + 27, 64, 90, 93, 90, 130, 90, 132, 133, 90, + 115, 115, 117, 58, 59, 42, 15, 16, 115, 115, + 87, 48, 115, 50, 115, 115, 115, 115, 98, 115, + 64, 115, 100, 101, 115, 98, 90, 105, 106, 107, + 108, 109, 110, 111, 90, 115, 63, 81, 82, 115, + 90, 115, 120, 90, 115, 115, 115, 115, 100, 101, + 115, 115, 90, 105, 106, 107, 108, 109, 110, 111, + 56, 90, 90, 117, 115, 117, 100, 101, 120, 100, + 101, 115, 115, 90, 90, 109, 110, 111, 109, 110, + 111, 63, 63, 117, 90, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 115, 115, 130, 90, + 132, 133, 115, 90, 116, 116, 116, 63, 116, 146, + 147, 116, 149, 150, 151, 116, 116, 115, 155, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 115, 115, 115, 90, 63, 115, 115, 115, 192, 100, + 101, 331, 332, 333, 334, 63, 183, 115, 109, 110, + 111, 115, 115, 115, 191, 115, 117, 115, 90, 196, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 115, 115, 90, 115, 90, 116, 115, 115, 215, 63, + 217, 218, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 115, 115, 115, 115, 115, 117, + 118, 119, 115, 121, 115, 115, 90, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 115, 115, + 115, 115, 115, 117, 118, 119, 115, 121, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 284, 285, 286, + 287, 288, 115, 115, 291, 115, 115, 115, 115, 115, + 115, 115, 115, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 115, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 115, 321, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 90, 355, 117, + 115, 90, 359, 360, 115, 115, 90, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 115, 376, + 115, 378, 379, 100, 101, 115, 90, 115, 105, 106, + 107, 108, 109, 110, 111, 115, 115, 63, 115, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 115, 100, 101, 115, 115, 115, 105, 106, 107, 108, + 109, 110, 111, 115, 90, 52, 115, 63, 117, -1, + -1, -1, -1, 472, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, -1, -1, -1, 115, + -1, 117, 118, 119, 90, 121, -1, -1, -1, 63, + -1, -1, -1, -1, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, -1, -1, -1, 115, + -1, 117, 118, 119, -1, 121, 90, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, -1, -1, + -1, 115, -1, 117, 118, 119, -1, 121, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 100, 101, -1, -1, 51, 105, 106, 107, + 108, 109, 110, 111, -1, 60, -1, 115, 63, 117, + -1, -1, -1, -1, -1, 70, 71, 50, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, + 63, -1, 54, -1, -1, 90, -1, -1, -1, 61, + -1, -1, -1, -1, -1, -1, -1, 102, 103, 104, + -1, 106, -1, -1, 109, -1, -1, 90, -1, -1, + 115, -1, -1, 118, 119, -1, 121, -1, -1, 102, + 103, 104, -1, 106, -1, -1, 109, -1, 63, -1, + -1, -1, 115, -1, -1, 118, 119, -1, 121, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + -1, -1, -1, 100, 101, 90, -1, -1, 105, 106, + 107, 108, 109, 110, 111, -1, -1, 102, 103, 104, + 117, 106, -1, -1, 109, -1, -1, -1, -1, -1, + 115, -1, -1, 118, 119, -1, 121, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, -1, 63, + -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, + -1, -1, -1, -1, 100, 101, 90, -1, -1, 105, + 106, 107, 108, 109, 110, 111, -1, -1, 102, 103, + 104, 117, 106, -1, -1, 109, -1, 63, -1, -1, + -1, 115, -1, -1, 118, 119, -1, 121, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 63, -1, -1, + -1, -1, -1, -1, 90, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 102, 103, 104, -1, + 106, -1, -1, 109, 90, -1, -1, -1, -1, 115, + -1, -1, 118, 119, -1, 121, 102, 103, 104, -1, + 106, -1, -1, 109, -1, -1, -1, -1, -1, 115, + -1, -1, 118, 119, -1, 121, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 63, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, + -1, -1, 90, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 102, 103, 104, -1, 106, -1, + -1, 109, -1, -1, -1, -1, -1, 115, -1, -1, + 118, 119, -1, 121, -1, -1, 63, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 63, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, + -1, -1, -1, 90, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 90, 102, 103, 104, -1, 106, + -1, -1, 109, -1, -1, -1, 102, 103, 104, -1, + 106, 118, 119, -1, 121, -1, -1, -1, -1, 115, + -1, -1, 118, 119, 100, 101, -1, -1, 63, 105, + 106, 107, 108, 109, 110, 111, -1, 100, 101, 115, + -1, 117, 105, 106, 107, 108, 109, 110, 111, -1, + -1, -1, 115, -1, 117, 90, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 102, 103, 104, + 0, 106, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 118, 119, -1, -1, 17, 18, 19, + -1, 21, -1, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, -1, 35, 36, 37, -1, -1, + -1, -1, -1, -1, -1, -1, 46, 47, 48, 49, + -1, -1, 52, 53, -1, 55, -1, 57, -1, -1, + -1, 61, 62, -1, -1, 65, 66, 67, 68, 69, + -1, -1, 72, 73, 74, 75, 76, 77, 78, 79, + 80, -1, -1, 83, 84, -1, 86, -1, 88, 89, + -1, -1, -1, 93, 94, 95, -1, -1, 17, 18, + 19, -1, 21, -1, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 115, 35, 36, 37, -1, + -1, -1, -1, -1, -1, -1, -1, 46, 47, 48, + 49, -1, -1, 52, 53, -1, 55, -1, 57, -1, + -1, -1, 61, 62, -1, -1, 65, 66, 67, 68, + 69, -1, -1, 72, 73, 74, 75, 76, 77, 78, + 79, 80, -1, -1, 83, 84, -1, 86, -1, 88, + 89, -1, -1, -1, 93, 94, 95, -1, -1, 17, + 18, 19, -1, 21, -1, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 115, 35, 36, 37, + -1, -1, -1, -1, -1, -1, -1, -1, 46, 47, + 48, 49, -1, -1, 52, 53, -1, -1, -1, -1, + -1, -1, -1, 61, 62, -1, -1, -1, 66, 67, + 68, 69, -1, -1, 72, 73, 74, 75, 76, 77, + 78, 79, 80, -1, -1, 83, 84, 14, 86, -1, + -1, -1, -1, -1, -1, 93, 94, 95, -1, 26, + -1, -1, -1, -1, -1, -1, -1, 34, -1, -1, + -1, 38, 39, 40, 41, 42, 43, 115, 45, 100, + 101, -1, -1, -1, 105, 106, 107, 108, 109, 110, + 111, -1, 100, 101, 115, -1, 117, 105, 106, 107, + 108, 109, 110, 111, -1, 100, 101, 115, -1, 117, + 105, 106, 107, 108, 109, 110, 111, -1, 85, -1, + 115, -1, 117, -1, 91, 92, 100, 101, -1, 96, + 97, 105, 106, 107, 108, 109, 110, 111, -1, 100, + 101, 115, -1, 117, 105, 106, 107, 108, 109, 110, + 111, -1, 100, 101, 115, -1, 117, 105, 106, 107, + 108, 109, 110, 111, -1, 100, 101, 115, -1, 117, + 105, 106, 107, 108, 109, 110, 111, -1, 100, 101, + 115, -1, 117, 105, 106, 107, 108, 109, 110, 111, + -1, 100, 101, 115, -1, 117, 105, 106, 107, 108, + 109, 110, 111, -1, 100, 101, 115, -1, 117, 105, + 106, 107, 108, 109, 110, 111, -1, 100, 101, 115, + -1, 117, 105, 106, 107, 108, 109, 110, 111, -1, + 100, 101, 115, -1, 117, 105, 106, 107, 108, 109, + 110, 111, -1, 100, 101, 115, -1, 117, 105, 106, + 107, 108, 109, 110, 111, -1, 100, 101, 115, -1, + 117, 105, 106, 107, 108, 109, 110, 111, -1, -1, + -1, 115, -1, 117 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 17, 18, 19, 21, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 35, 36, 37, 46, + 47, 48, 49, 52, 53, 55, 57, 61, 62, 65, + 66, 67, 68, 69, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 83, 84, 86, 88, 89, 93, 94, + 95, 115, 123, 124, 126, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 115, 44, 90, 115, 115, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 54, 61, 127, 115, + 3, 4, 5, 6, 7, 63, 90, 102, 103, 104, + 106, 115, 118, 119, 127, 174, 3, 4, 5, 6, + 7, 63, 90, 102, 103, 104, 106, 109, 115, 118, + 119, 121, 127, 175, 63, 109, 115, 175, 90, 90, + 90, 14, 26, 34, 38, 39, 40, 41, 42, 43, + 45, 85, 91, 92, 96, 97, 115, 115, 115, 115, + 115, 115, 115, 50, 115, 175, 63, 90, 56, 58, + 59, 51, 60, 70, 71, 115, 175, 64, 98, 90, + 90, 15, 16, 125, 125, 125, 115, 90, 90, 63, + 63, 115, 90, 115, 17, 32, 64, 81, 82, 115, + 115, 175, 63, 98, 115, 63, 87, 63, 115, 115, + 90, 175, 17, 18, 19, 21, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 35, 36, 37, 46, 47, + 48, 49, 52, 53, 61, 62, 66, 67, 68, 69, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 83, + 84, 86, 93, 94, 95, 115, 126, 175, 0, 124, + 115, 90, 90, 115, 116, 116, 116, 116, 116, 116, + 125, 116, 174, 174, 174, 100, 101, 105, 106, 107, + 108, 109, 110, 111, 117, 115, 175, 175, 175, 175, + 175, 100, 101, 105, 106, 107, 108, 109, 110, 111, + 115, 117, 175, 115, 115, 115, 115, 115, 115, 115, + 90, 151, 151, 151, 151, 115, 115, 115, 63, 115, + 93, 115, 115, 115, 115, 115, 175, 115, 63, 90, + 115, 90, 115, 115, 115, 175, 125, 115, 116, 106, + 109, 115, 175, 115, 115, 115, 90, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 175, 115, 175, 175, + 115, 115, 115, 90, 115, 63, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 175, 175, 175, 175, + 175, 90, 115, 175, 120, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 120, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 115, 151, 151, 151, + 151, 115, 90, 115, 115, 90, 115, 115, 175, 115, + 90, 175, 175, 115, 115, 115, 175, 115, 175, 115, + 175, 115, 90, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 126, 115, 115, + 115, 115, 115, 115, 115, 90, 115 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +#else +static void +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + fprintf (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + fprintf (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + look-ahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 50: +#line 191 "parser.y" + { + } + break; + + case 52: +#line 198 "parser.y" + { (yyval.bval)=(yyvsp[(1) - (1)].bval); } + break; + + case 54: +#line 204 "parser.y" + { (yyval.sval)=(yyvsp[(1) - (1)].sval); } + break; + + case 60: +#line 214 "parser.y" + { (yyval.uval)=(yyvsp[(1) - (1)].uval); } + break; + + case 61: +#line 219 "parser.y" + { + bx_dbg_timebp_command(0, (yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 62: +#line 224 "parser.y" + { + bx_dbg_timebp_command(1, (yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 63: +#line 232 "parser.y" + { + bx_dbg_record_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 64: +#line 240 "parser.y" + { + bx_dbg_playback_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 65: +#line 248 "parser.y" + { + bx_dbg_modebp_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 66: +#line 256 "parser.y" + { + bx_dbg_show_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 67: +#line 261 "parser.y" + { + bx_dbg_show_param_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 68: +#line 266 "parser.y" + { + bx_dbg_show_command(0); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 69: +#line 274 "parser.y" + { + bx_dbg_xlate_address((yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 70: +#line 282 "parser.y" + { + bx_dbg_ptime_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 71: +#line 290 "parser.y" + { + bx_dbg_trace_command((yyvsp[(2) - (3)].bval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 72: +#line 298 "parser.y" + { + bx_dbg_trace_reg_command((yyvsp[(2) - (3)].bval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 73: +#line 306 "parser.y" + { + bx_dbg_trace_mem_command((yyvsp[(2) - (3)].bval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 74: +#line 314 "parser.y" + { + bx_dbg_print_stack_command(16); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 75: +#line 319 "parser.y" + { + bx_dbg_print_stack_command((yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 76: +#line 327 "parser.y" + { + bx_dbg_watchpoint_continue(0); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 77: +#line 332 "parser.y" + { + bx_dbg_watchpoint_continue(1); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 78: +#line 337 "parser.y" + { + bx_dbg_print_watchpoints(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 79: +#line 342 "parser.y" + { + bx_dbg_watch(0, (yyvsp[(3) - (4)].uval), 1); /* BX_READ */ + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 80: +#line 347 "parser.y" + { + bx_dbg_watch(0, (yyvsp[(3) - (4)].uval), 1); /* BX_READ */ + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 81: +#line 352 "parser.y" + { + bx_dbg_watch(1, (yyvsp[(3) - (4)].uval), 1); /* BX_WRITE */ + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 82: +#line 357 "parser.y" + { + bx_dbg_watch(0, (yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); /* BX_READ */ + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 83: +#line 362 "parser.y" + { + bx_dbg_watch(0, (yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); /* BX_READ */ + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 84: +#line 367 "parser.y" + { + bx_dbg_watch(1, (yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); /* BX_WRITE */ + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 85: +#line 372 "parser.y" + { + bx_dbg_unwatch_all(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 86: +#line 377 "parser.y" + { + bx_dbg_unwatch((yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 87: +#line 385 "parser.y" + { + bx_dbg_symbol_command((yyvsp[(2) - (3)].sval), 0, 0); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 88: +#line 390 "parser.y" + { + bx_dbg_symbol_command((yyvsp[(2) - (4)].sval), 0, (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 89: +#line 395 "parser.y" + { + bx_dbg_symbol_command((yyvsp[(3) - (4)].sval), 1, 0); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); free((yyvsp[(3) - (4)].sval)); + } + break; + + case 90: +#line 400 "parser.y" + { + bx_dbg_symbol_command((yyvsp[(3) - (5)].sval), 1, (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); free((yyvsp[(3) - (5)].sval)); + } + break; + + case 91: +#line 408 "parser.y" + { + bx_dbg_where_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 92: +#line 416 "parser.y" + { + bx_dbg_print_string_command((yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 93: +#line 424 "parser.y" + { + bx_dbg_continue_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 94: +#line 432 "parser.y" + { + bx_dbg_stepN_command(dbg_cpu, 1); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 95: +#line 437 "parser.y" + { + bx_dbg_stepN_command(dbg_cpu, (yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 96: +#line 442 "parser.y" + { + bx_dbg_stepN_command(-1, (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 97: +#line 447 "parser.y" + { + bx_dbg_stepN_command((yyvsp[(2) - (4)].uval), (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); + } + break; + + case 98: +#line 455 "parser.y" + { + bx_dbg_step_over_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 99: +#line 463 "parser.y" + { + bx_dbg_set_auto_disassemble((yyvsp[(3) - (4)].bval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 100: +#line 468 "parser.y" + { + bx_dbg_set_symbol_command((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 101: +#line 473 "parser.y" + { + bx_dbg_set_reg8l_value((yyvsp[(2) - (5)].uval), (yyvsp[(4) - (5)].uval)); + } + break; + + case 102: +#line 477 "parser.y" + { + bx_dbg_set_reg8h_value((yyvsp[(2) - (5)].uval), (yyvsp[(4) - (5)].uval)); + } + break; + + case 103: +#line 481 "parser.y" + { + bx_dbg_set_reg16_value((yyvsp[(2) - (5)].uval), (yyvsp[(4) - (5)].uval)); + } + break; + + case 104: +#line 485 "parser.y" + { + bx_dbg_set_reg32_value((yyvsp[(2) - (5)].uval), (yyvsp[(4) - (5)].uval)); + } + break; + + case 105: +#line 489 "parser.y" + { + bx_dbg_set_reg64_value((yyvsp[(2) - (5)].uval), (yyvsp[(4) - (5)].uval)); + } + break; + + case 106: +#line 493 "parser.y" + { + bx_dbg_load_segreg((yyvsp[(2) - (5)].uval), (yyvsp[(4) - (5)].uval)); + } + break; + + case 107: +#line 500 "parser.y" + { + bx_dbg_vbreakpoint_command(bkAtIP, 0, 0); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 108: +#line 505 "parser.y" + { + bx_dbg_vbreakpoint_command(bkRegular, (yyvsp[(2) - (5)].uval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); + } + break; + + case 109: +#line 510 "parser.y" + { + bx_dbg_lbreakpoint_command(bkAtIP, 0); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 110: +#line 515 "parser.y" + { + bx_dbg_lbreakpoint_command(bkRegular, (yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 111: +#line 520 "parser.y" + { + bx_dbg_lbreakpoint_symbol_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 112: +#line 525 "parser.y" + { + bx_dbg_pbreakpoint_command(bkAtIP, 0); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 113: +#line 530 "parser.y" + { + bx_dbg_pbreakpoint_command(bkRegular, (yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 114: +#line 535 "parser.y" + { + bx_dbg_pbreakpoint_command(bkRegular, (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); + } + break; + + case 115: +#line 543 "parser.y" + { + bx_dbg_info_bpoints_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 116: +#line 551 "parser.y" + { + bx_dbg_info_symbols_command(0); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 117: +#line 556 "parser.y" + { + bx_dbg_info_symbols_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 118: +#line 564 "parser.y" + { + bx_dbg_info_bpoints_command(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 119: +#line 569 "parser.y" + { + bx_dbg_info_registers_command(BX_INFO_GENERAL_PURPOSE_REGS | BX_INFO_FPU_REGS | BX_INFO_SSE_REGS); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 120: +#line 574 "parser.y" + { + bx_dbg_info_idt_command((yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 121: +#line 579 "parser.y" + { + bx_dbg_info_ivt_command((yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 122: +#line 584 "parser.y" + { + bx_dbg_info_gdt_command((yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 123: +#line 589 "parser.y" + { + bx_dbg_info_ldt_command((yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 124: +#line 594 "parser.y" + { + bx_dbg_dump_table(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 125: +#line 599 "parser.y" + { + bx_dbg_info_tss_command(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 126: +#line 604 "parser.y" + { + bx_dbg_info_flags(); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 127: +#line 609 "parser.y" + { + bx_dbg_info_linux_command(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 128: +#line 614 "parser.y" + { + bx_dbg_info_symbols_command(0); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 129: +#line 619 "parser.y" + { + bx_dbg_info_symbols_command((yyvsp[(3) - (4)].sval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); free((yyvsp[(3) - (4)].sval)); + } + break; + + case 130: +#line 624 "parser.y" + { + bx_dbg_info_ne2k(-1, -1); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 131: +#line 629 "parser.y" + { + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); free((yyvsp[(3) - (5)].sval)); + bx_dbg_info_ne2k((yyvsp[(4) - (5)].uval), -1); + } + break; + + case 132: +#line 634 "parser.y" + { + free((yyvsp[(1) - (7)].sval)); free((yyvsp[(2) - (7)].sval)); free((yyvsp[(3) - (7)].sval)); free((yyvsp[(5) - (7)].sval)); + bx_dbg_info_ne2k((yyvsp[(4) - (7)].uval), (yyvsp[(6) - (7)].uval)); + } + break; + + case 133: +#line 639 "parser.y" + { + bx_dbg_info_pic(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 134: +#line 644 "parser.y" + { + bx_dbg_info_vga(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 135: +#line 649 "parser.y" + { + bx_dbg_info_pci(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 136: +#line 656 "parser.y" + { (yyval.uval) = EMPTY_ARG; } + break; + + case 138: +#line 661 "parser.y" + { + bx_dbg_info_registers_command(BX_INFO_GENERAL_PURPOSE_REGS); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 139: +#line 669 "parser.y" + { + bx_dbg_info_registers_command(BX_INFO_FPU_REGS); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 140: +#line 677 "parser.y" + { + bx_dbg_info_registers_command(BX_INFO_MMX_REGS); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 141: +#line 685 "parser.y" + { + bx_dbg_info_registers_command(BX_INFO_SSE_REGS); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 142: +#line 693 "parser.y" + { + bx_dbg_info_segment_regs_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 143: +#line 701 "parser.y" + { + bx_dbg_info_control_regs_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 144: +#line 709 "parser.y" + { + bx_dbg_info_debug_regs_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 145: +#line 717 "parser.y" + { + bx_dbg_del_breakpoint_command((yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 146: +#line 725 "parser.y" + { + bx_dbg_en_dis_breakpoint_command((yyvsp[(2) - (3)].uval), 1); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 147: +#line 732 "parser.y" + { + bx_dbg_en_dis_breakpoint_command((yyvsp[(2) - (3)].uval), 0); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 148: +#line 740 "parser.y" + { + bx_dbg_quit_command(); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 149: +#line 748 "parser.y" + { + bx_dbg_examine_command((yyvsp[(1) - (4)].sval), (yyvsp[(2) - (4)].sval),1, (yyvsp[(3) - (4)].uval), 1); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 150: +#line 753 "parser.y" + { + bx_dbg_examine_command((yyvsp[(1) - (3)].sval), (yyvsp[(2) - (3)].sval),1, 0, 0); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 151: +#line 758 "parser.y" + { + bx_dbg_examine_command((yyvsp[(1) - (3)].sval), NULL,0, (yyvsp[(2) - (3)].uval), 1); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 152: +#line 763 "parser.y" + { + bx_dbg_examine_command((yyvsp[(1) - (2)].sval), NULL,0, 0, 0); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 153: +#line 771 "parser.y" + { + bx_dbg_restore_command((yyvsp[(2) - (4)].sval), (yyvsp[(3) - (4)].sval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); free((yyvsp[(3) - (4)].sval)); + } + break; + + case 154: +#line 779 "parser.y" + { + bx_dbg_setpmem_command((yyvsp[(2) - (5)].uval), (yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); + } + break; + + case 155: +#line 787 "parser.y" + { + bx_dbg_query_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 156: +#line 795 "parser.y" + { + bx_dbg_take_command((yyvsp[(2) - (3)].sval), 1); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 157: +#line 800 "parser.y" + { + bx_dbg_take_command((yyvsp[(2) - (4)].sval), (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 158: +#line 805 "parser.y" + { + bx_dbg_take_command((yyvsp[(2) - (3)].sval), 1); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 159: +#line 813 "parser.y" + { + bx_dbg_disassemble_current(NULL); + free((yyvsp[(1) - (2)].sval)); + } + break; + + case 160: +#line 818 "parser.y" + { + bx_dbg_disassemble_command(NULL, (yyvsp[(2) - (3)].uval), (yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 161: +#line 823 "parser.y" + { + bx_dbg_disassemble_command(NULL, (yyvsp[(2) - (4)].uval), (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); + } + break; + + case 162: +#line 828 "parser.y" + { + bx_dbg_disassemble_current((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 163: +#line 833 "parser.y" + { + bx_dbg_disassemble_command((yyvsp[(2) - (4)].sval), (yyvsp[(3) - (4)].uval), (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 164: +#line 838 "parser.y" + { + bx_dbg_disassemble_command((yyvsp[(2) - (5)].sval), (yyvsp[(3) - (5)].uval), (yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 165: +#line 843 "parser.y" + { + bx_dbg_disassemble_switch_mode(); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 166: +#line 848 "parser.y" + { + bx_dbg_disassemble_hex_mode_switch((yyvsp[(3) - (4)].bval)); + free((yyvsp[(1) - (4)].sval)); free((yyvsp[(2) - (4)].sval)); + } + break; + + case 167: +#line 853 "parser.y" + { + bx_dbg_set_disassemble_size((yyvsp[(4) - (5)].uval)); + free((yyvsp[(1) - (5)].sval)); free((yyvsp[(2) - (5)].sval)); + } + break; + + case 168: +#line 861 "parser.y" + { + bx_dbg_instrument_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 169: +#line 866 "parser.y" + { + bx_dbg_instrument_command((yyvsp[(2) - (3)].sval)); + free((yyvsp[(1) - (3)].sval)); free((yyvsp[(2) - (3)].sval)); + } + break; + + case 170: +#line 874 "parser.y" + { + bx_dbg_doit_command((yyvsp[(2) - (3)].uval)); + free((yyvsp[(1) - (3)].sval)); + } + break; + + case 171: +#line 882 "parser.y" + { + bx_dbg_crc_command((yyvsp[(2) - (4)].uval), (yyvsp[(3) - (4)].uval)); + free((yyvsp[(1) - (4)].sval)); + } + break; + + case 172: +#line 890 "parser.y" + { + dbg_printf("q|quit|exit - quit debugger and emulator execution\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 173: +#line 895 "parser.y" + { + dbg_printf("c|cont|continue - continue executing\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 174: +#line 900 "parser.y" + { + dbg_printf("s|step [count] - execute #count instructions on current processor (default is one instruction)\n"); + dbg_printf("s|step [cpu] - execute #count instructions on processor #cpu\n"); + dbg_printf("s|step all - execute #count instructions on all the processors\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 175: +#line 907 "parser.y" + { + dbg_printf("n|next|p - execute instruction stepping over subroutines\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 176: +#line 912 "parser.y" + { + dbg_printf("vb|vbreak - set a virtual address instruction breakpoint\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 177: +#line 917 "parser.y" + { + dbg_printf("lb|lbreak - set a linear address instruction breakpoint\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 178: +#line 922 "parser.y" + { + dbg_printf("p|pb|break|pbreak - set a physical address instruction breakpoint\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 179: +#line 927 "parser.y" + { + dbg_printf("d|del|delete - delete a breakpoint\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 180: +#line 932 "parser.y" + { + dbg_printf("bpe - enable a breakpoint\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 181: +#line 937 "parser.y" + { + dbg_printf("bpd - disable a breakpoint\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 182: +#line 942 "parser.y" + { + dbg_printf("blist - list all breakpoints (same as 'info break')\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 183: +#line 947 "parser.y" + { + dbg_printf("modebp - toggles mode switch breakpoint\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 184: +#line 952 "parser.y" + { + dbg_printf("crc - show CRC32 for physical memory range addr1..addr2\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 185: +#line 957 "parser.y" + { + dbg_printf("trace on - print disassembly for every executed instruction\n"); + dbg_printf("trace off - disable instruction tracing\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 186: +#line 963 "parser.y" + { + dbg_printf("trace-reg on - print all registers before every executed instruction\n"); + dbg_printf("trace-reg off - disable registers state tracing\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 187: +#line 969 "parser.y" + { + dbg_printf("trace-mem on - print all memory accesses occured during instruction execution\n"); + dbg_printf("trace-mem off - disable memory accesses tracing\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 188: +#line 975 "parser.y" + { + dbg_printf("restore [path] - restore bochs root param from the file\n"); + dbg_printf("for example:\n"); + dbg_printf("restore \"cpu0\" - restore CPU #0 from file \"cpu0\" in current directory\n"); + dbg_printf("restore \"cpu0\" \"/save\" - restore CPU #0 from file \"cpu0\" located in directory \"/save\"\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 189: +#line 983 "parser.y" + { + dbg_printf("ptime - print current time (number of ticks since start of simulation)\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 190: +#line 988 "parser.y" + { + dbg_printf("sb - insert a time breakpoint delta instructions into the future\n"); + free((yyvsp[(1) - (3)].sval));free((yyvsp[(2) - (3)].sval)); + } + break; + + case 191: +#line 993 "parser.y" + { + dbg_printf("sba