!Befunge V0.92, 3rd June 2005
--------------

!Befunge is a flexible Befunge interpreter which supports 99.9% of the Befunge-98 spec. If you don't know what Befunge is, check out its homepage at http://www.catseye.mb.ca/esoteric/ (Currently under renovation)

The interpreter is 26/32bit neutral, although a 32bit version of the Shared C Library may be needed to run it on 26bit machines. The handprint of the interpreter is 0x4A424546 (JBEF). The builtin fingerprints are:

0x42415345 (BASE)
0x43504C49 (CPLI)
0x44495246 (DIRF)
0x46494C45 (FILE)
0x46495850 (FIXP)
0x46525448 (FRTH)
0x48525449 (HRTI)
0x4D4F4445 (MODE)
0x4D4F4455 (MODU)
0x4E554C4C (NULL)
0x4F525448 (ORTH)
0x5045524C (PERL)
0x52454643 (REFC)
0x524F4D41 (ROMA)
0x5445524D (TERM)
0x544F5953 (TOYS)
0x54555254 (TURT)

See the notes near the end of this file for exact implementation details, and information about the dynamic fingerprint system.


Features:
---------

* Single-tasking or multi-tasking operation
* Befunge-93 mode
* Toggleable funge-98 instruction set support, with individual switches for file access and concurrency
* Support for unefunge, befunge and trefunge
* Configurable fungespace size (including unrestricted) and bittyness (8 or 32)
* Dynamic fingerprint system based around runtime loaded Befunge files (minifunge/funge-lib compatible)
* Stop, pause, play and single-step execution controls (multi-tasking version only)
* IP spy window to display the status of each IP (multi-tasking version only)
* Execution breakpoints (multi-tasking version only)
* Support for multiple programs loaded at once (multi-tasking version only)
* Inbuilt editor (multi-tasking version only)
* Simple trace mode (single-tasking version only)


Usage - Single tasking:
-----------------------

!Befunge can be used just like any other command line program. If you want, you can copy the executable (Befunge) out of the !Befunge application and run that by itself, as long as you use the --nowimp option to disable the WIMP interface, set <Befunge$DynaFing> to the location of your dynamic fingerprints, and ensure that <Befunge$Turtle> is set if you want to save the 'TURT' fingerprint output.

Command line switches:

--help          Display some help text and then exit
<anything else> The name of a file to load and run, in which case the
                following options can also be used:
  --nowimp      Disable the WIMP interface (Not needed if already outside the
                desktop, in a taskwindow, etc.)
  --quiet       Disable all non-Befunge messages
  --trace       Enable very simple tracing of execution
  --noprompt    Disable input prompts
  --script      The file is a script; the IP will be started at the first line
                which doesn't start with a #
  --warn        Warn about attempts to execute unimplemented instructions
  --d=dims      Set the space dimensions. Eg --d=80,25 would be for Befunge 93,
                --d=*,* for unlimited size Befunge, --d=*,*,* for unlimited
                Trefunge, etc. There is a maximum limit of 3 dimensions.
  --cellsize=n  Set the cell size to n bits. n must be 8 or 32.
  --div0=n      For Befunge-93 programs, set the result of a division by zero to
                the number n (Instead of querying the user).
  --rem0=n      For Befunge-93 programs, set the result of a remainder by zero
                to the number n (Instead of querying the user).
  --98          Enable befunge-98 instructions, and the following options:
  --concurrent  Enable concurrency (multithreading) instructions
  --files       Enable file access instructions
  --args [...]  Arguments following --args are the arguments to be sent to the
                program
  --up-is-up    Make the h instruction set the IPs delta to (0,0,1) (goes
                against the spec)

Initial setup is suitable for running befunge-93 programs (i.e. 80x25, 8 bit
cells, no extended instructions). For Befunge-98, use --98 --d=*,* --cellsize=32

Note that division by 0/remainder by 0 prompts are always shown, regardless of the --quiet/--noprompt status.

The format of the tracing output is lines of the form:

IP <id> at <pos> <flags> org. <storage offset> over <cell>, stk: <cell> [<cell> [<cell> [...]]]

Where:

* <id> is the ID number of the IP
* <pos> is its current location (relative to the origin)
* <flags> is the direction the IP is heading (one of ><^vhl, or more than one if the IP is flying), and a series of flags:
  - '"' if it is in stringmode
  - 'i' if it has the input focus
  - 'F' if it is in a dynamic fingerprint fungespace
  - 'G' if it has a 'ghost' (i.e. is in the middle of executing a dynamic fingerprint)
  - 'D' if it is dead and awaiting removal (i.e. a dynamic fingerprint is executing some =@ code, so the dying IP is being kept alive for the time being)
  - 'H' if hovermode is enabled
  - 'I' for invertmode
  - 'Q' for queuemode
  - 'S' for switchmode (See the 'MODE' fingerprint for details of these last four)
* <storage offset> is the storage offset of the IP
* <cell> is the value of the cell the IP is over, or the value of a stack cell. The cell the IP is over is either displayed as a character, or in hex, while the stack cells are displayed as decimal and if possible a character. Up to ten of the top stack cells will be shown at once.

Note that if an IP has a ghost, the stack of the IP will be shown empty since it is the ghost which 'owns' it.

When a warning message is produced, !Befunge will wait for you to press a key before continuing execution.


Usage - Multi tasking:
----------------------

On startup, !Befunge supports all the command line siwthces as listed above, apart from --help, --nowimp (otherwise it'd run the singletasking version), --quiet (since no text messages are output on the wimp interface), and --trace (since full execution control is available). The remaining options will set the defaults for the new file/load file window, and if a filename is given then that file will be loaded using those options.

Once !Befunge has loaded its icon will appear on the iconbar. Clicking with select will open the new file window, and menu will open the usual 'Info ... Quit' menu. From the new file window you can:

* Enter the name of a file to load (Or drag the file to the window to have its name entered automatically)
* Set the size of the fungespace, using a string of the same format as for the --d switch. For speed, right-clicking on this icon will cycle through a set of predefined dimensions:
  - 08,25 (i.e. Befunge-93)
  - *,* (i.e. unliminted befunge)
  - *,*,* (i.e. unlimited trefunge)
  - * (i.e. unlimited unefunge)
* Control whether the funge-98 instructions are available
* Set the command line arguments to send to Funge-98 programs
* Control whether file access and concurrency is available for Funge-98 programs
* Set the 'up' direction for trefunge files
* Control whether requests for user input should pause all IPs as opposed to letting the non-input IPs contine to run
* Control the default division by 0 and remainder by 0 values for Befunge-93 programs
* Control whether the file is treated as a script file
* Control whether input prompts are displayed
* Control whether the fungepsace is 8 or 32 bit
* Control whether warnings are displayed on attempts to execute unimplemented instructions

Leaving the divison by 0/remainder by 0 boxes blank will have !Befunge ask you what value to give each time that condition occurs. Clicking 'OK' will load/create the file, while 'cancel' will (unsurprisingly) cancel. You can also drag files to the iconbar icon to open the new file/load file window.

The program window:
-------------------

This is the window you use for interacting with the fungespace of the program. Closing this window will close the Befunge program. Along the top of the window is a toolbar. From left to right the buttons are:

* Rewind. This will stop execution of the program, clear fungespace and the output window, and reload the file from disc (Providing it originated there). It will also erase any program-specific (as opposed to IP specific) information held in the fingerprint system.
* Stop. This stops execution of the program (i.e. kills all IPs)
* Pause. This will pause a program mid-execution.
* Play-pause. This is used to singlestep the program. It will automatically Pause execution, and each time it is pressed all the IPs will move on one 'tick'
* Play. This will start execution, or continue from a pause. Play and Pause can be pressed in at the same time (by using the adjust button) to run the program slower than Play would on its own.
* IO window. This will open the window used to interact with the program, which is 80x25 characters in size.
* IP spy window. This will open the window used to examine each IP.
* Up button. This will move in the configured 'up' direction through trefunge space (i.e. the direction h goes)
* Down button. This will move in the configured 'down' direction through trefunge space (i.e. the direction l goes)

Rightmost is the status line, which displays:

* The location of the input cursor
* The direction the cursor will travel when you type (see below)
* The program input flag ('i' if some IP is awaiting input)
* The Insert mode status ('I' for Code Insert mode, 'I"' for String Insert mode, '^I' for Super Code Insert mode, '^I"' for String Insert mode which will revert to Super Code Insert mode, and an additional 'X' if cursor lock is on - see below)
* The value of the cell under the cursor. The cell will be shown in decimal, hex and as a character if possible.

In some situations the status line will change into a raised button and display a different message, e.g. the exit code returned when the program quit via the 'q' instruction. Clicking the status line will return it to its normal display.

The main part of the window can display fungespace cells, as ASCII characters. If the cell is between 0 and 31 then the character (x+48) will be drawn, but in red; i.e. a cell of value 0 will appear as a red number 0, a cell of value 10 as ':', etc. If the cell is 127 then a red '' is shown. If the cell is over 256 or under 0 then a red '' is shown.


You can enter text and code into fungespace as normal by using the keyboard. However you can also change the direction the cursor moves. E.g. pressing ctrl+left arrow will change the cursor direction to left, pressing ctrl+up will change it to up the screen, and pressing ctrl+page up will change it to 'up' through trefunge space. Delete and backspace have been changed to clear the cell under the cursor, then move the cursor one cell in the opposite direction to normal travel.

By pressing Insert you can toggle Code Insert mode on and off, which will cause blocks of characters to be shuffled in the appropriate direction whenever you type. Code Insert mode will stop the shuffling when a space is encountered, and so is useful for editing code. It will also auto-shuffle the next character after a ' or s.

Shift-Insert toggles String Insert mode - all characters will be shuffled until a quote is encountered.

Ctrl-Insert toggles Super Code Insert mode. This is the same as Code Insert mode, but the direction changing instructions ^v<>hl and [] will cause the shuffle direction to change and so is handy for editing wound up code sections.

Shift-Ctrl-Insert toggles Cursor Lock on and off. When cursor lock is on, any typing you perform will not cause the cursor to move. This is handy for typing strings, e.g. enter a couple of quotes, position the cursor over the 2nd one, turn on string insert and cursor lock, and then type away - the string will be inserted backwards. Yes this is a tricky key combination to remember, but it's a lot easier than learning to spell backwards or having to move the cursor manually.

The insert modes will automatically toggle between their string insert forms during insertion, so strings in code segments and code segments after strings will be handled OK. Note that to prevent infinite recursion, only up to 100 characters will be shuffled.

You can also drag files into the window to have them entered at the cursor using the same mechanism as the 'i' instruction in text mode.


Clicking menu over the window will open a menu allowing you to save the program, move the display to a particular location, set/clear the breakpoints, edit the value of the cell under the cursor, save the program output, change the majority of the options available on the new file/load file window, and open windows to see/edit the loaded dynamic fingerprints.

The save option will save the fungespace starting from the origin, and has no upper size limit - be wary of using it on infinite fungespaces with lots of data spread about!

Using the 'Go to' option you can center the view on a particular set of coordinates (e.g. '5,5,5', '1000', etc.), the cursor, or an IP.

The 'Breakpoints' option will open a dialog box where you can enter the coordinates of up to 8 breakpoints, and flag whether they are active. You can also use the 'Breakpoint here' option to quickly enalbe/disable a breakpoint at the location you opened the menu. If an IP attempts to execute an active breakpoint, then the program will be paused and a message displayed on the status line. Disabling the breakpoint and continuing execution will act as if nothing ever happened (i.e. in concurrent funge the IPs will still be in synch). Note that skipped cells (e.g. spaces) will not trigger a breakpoint to occur.

The 'Cell value' option allows you to enter a value for the cell the menu was opened over, in decimal, octal or hex.

The 'Save Output'/'Spool output' option allows you to save the contents of the IO window, spool the contents of the IO window (i.e. save the current contents then continue saving program output as it is produced), or stop any current spooling.

The only interpreter option you can't change from the menu is the cell size; in order to change that you must reload the (befunge) program, via the new file window.

IO window:
----------

This is where the output of the befunge program will be displayed, and your input can be entered.

IP spy window:
--------------

This allows you to monitor the status of each IP. The display is similar to that of the single-tasking trace.


Supported instructions:
-----------------------

The specification referred to here is the Funge-98 Final Specification at catseye.mb.ca (30th Sept 1998). A copy of the spec has been included in the 'specs' directory. At the points where the spec is unclear, Chris Pressey's FBBI 0.98a (at catseye.mb.ca) with patches 2003.0722 and 2003.0726 was used for reference. At the moment catseye.mb.ca seems to be down, but hopefully it'll be back soon with a new version of FBBI incorporating the above patches (if you need them before then just ask me for a copy). Testing against the Befunge Diagnostics at catseye.mb.ca will be performed soon, providing they reappear.

Char    Action          Notes
====    ======          =====
Space   Nothing         As spec.
!       Logical not     As spec.
"       Stringmode      As spec. Note that in B-93 mode, every cell will be
                        added onto the stack, so do not allow stringmode to
                        escape into a dimension of unlimited size.
#       Trampoline      As spec.
$       Pop             As spec.
%       Remainder       As spec. Note that this may return an error in
                        befunge-93 if the remainder by 0 prompt can't be written
                        or the response can't be read.
&       Input integer   As spec. Like FBBI, input is read line by line until a
                        line containing a number is found. Input is buffered, so
                        characters following the number (including newline) are
                        kept in the input stream. Errors are only possible in
                        single-tasking mode. In concurrent-funge, only one IP
                        is allowed access to the input stream at once. If in
                        single-tasking mode or the 'input pauses' flag has been
                        used then all other IPs will be frozen, else all other
                        IPs will continue to run and the input IP will stay
                        hovering over the instruction.
'       Fetch character As spec. Reflects/warns if F-98 inactive
(       Load semantics  As spec. Reflects/warns if F-98 inactive
)       Unload semanticsAs spec. Reflects/warns if F-98 inactive
*       Multiply        As spec.
+       Add             As spec.
,       Output char     As spec. All character codes are output. Errors are
                        only possible in single-tasking mode.
-       Subtract        As spec.
.       Output int      As spec. Errors are only possible in single-tasking
                        mode.
/       Divide          As spec. Note that this may return an error in
                        befunge-93 if the division by 0 prompt can't be written
                        or the response can't be read.
0-9     Push integer    As spec.
:       Duplicate       As spec.
;       Jump over       As spec. Reflects/warns if F-98 inactive
<       Go west         As spec.
=       Execute         As spec. In the multi-tasking version the program is
                        started by Wimp_StartTask, as opposed to system(). If
                        the program tries registering itself as a WIMP task
                        then !Befunge will assume it's OK and return a value of
                        0 immediately. Errors (e.g. file not found) do not get
                        detected. Reflects/warns if either F-98 or filesystem
                        instructions inactive.
>       Go east         As spec.
?       Go away         As spec.
@       Stop            As spec.
A-Z     Semantics       As spec. Initial action is to reflect/warn.
                        Reflects/warns if F-98 inactive.
[       Turn left       As spec. Reflects/warns if F-98 inactive or unefunge
\       Swap            As spec.
]       Turn right      As spec. Reflects/warns if F-98 inactive or unefunge
^       Go north        As spec. Reflects/warns if unefunge.
_       East-west If    As spec.
`       Greater than    As spec.
a-f     Push hex        As spec. Reflects/warns if F-98 inactive.
g       Get             As spec.
h       Go high         Sets the IP delta to the configured 'up' direction -
                        (0,0,1) if --up-is-up is used or
                        (0,0,-1) if --up-is-down is used (currently the default)
                        Reflects/warns if not F-98 or not trefunge.
i       Input file      As spec. In text mode, if extra-dimension data is found
                        (e.g. line feeds in an unefunge file) then the control
                        code & following data will be loaded. This is different
                        to FBBI, which ignores the extra data. Once finished, it
                        pushes the size vector and then the location vector
                        (the opposite to what the spec suggests). The size
                        vector will be of the form (x,y,z) (disregarding higher
                        dimensions), where:
                          x is the maximum number of characters found on a line
                          y is the maximum number of newlines per trefunge
                            layer +1 (thus a file containing no newlines has a
                            height of 1)
                          z is the number of formfeeds +1
                        I.e. an empty file will have size (0,1,1).
                        Reflects/warns if F-98 or filesystem are inactive.
j       Jump            As spec. Reflects/warns if F-98 inactive.
k       Iterate         As spec. Like FBBI, !Befunge loads the instruction once,
                        then iterates that same instruction (as opposed to
                        reloading the instruction each iteration). There are a
                        few differences between Befunge and FBBI when iterating
                        " or unimplemented instructions though. Note that 0k^
                        will still execute the '^', because normal execution
                        resumes straight after the k. Iterating over @ or q is
                        safe. Iterating over an instruction that tries to gain
                        the input prompt will cause the IP to pause over the k
                        instruction; it will probably take more than one clock
                        tick to execute, but the requested number of inputs
                        will still be read. Reflects/warns if F-98 inactive
l       Go low          Sets the IP delta to the configured 'down' direction -
                        (0,0,-1) if --up-is-up is used or
                        (0,0,1) if --up-is-down is used (currently the default)
                        Reflects/warns if not F-98 or not trefunge.
m       High-low If     As spec, using the directions indicated for h and l.
                        Reflects/warns if not F-98 or not trefunge.
o       Output file     As spec. Pops the file name, flags, location and size in
                        that order. Area output is from pos inclusive to pos+
                        size exclusive. Size scalars of <1 will be treated as
                        empty; i.e. don't output anything on that dimension or
                        lower. Thus a size of (x,0,5) can be used to create a
                        file containing just 4 formfeeds, no matter what x is
                        (Unless compression is used, in which case the file
                        would be empty). Reflects/warns if either F-98 or file
                        access are inactive.
p       Put             As spec.
q       Quit            As spec. Does not trigger =@ in dynamic fingerprints.
                        Reflects/warns if F-98 inactive.
r       Reflect         As spec. Reflects/warns if F-98 inactive.
s       Store char      As spec. Reflects/warns if F-98 inactive.
t       Split           As spec. Reflects/warns if F-98 or concurrency inactive
u       StackUnderStack As spec. Reflects/warns if F-98 inactive.
v       Go south        As spec. Reflects/warns if unefunge.
w       Compare         As spec. Reflects/warns if not F-98 or unefunge.
x       Absolute delta  As spec. Reflects/warns if F-98 inactive.
y       Get sys info    As spec. Currently the environment variables are empty,
                        and null length arguments are impossible (I think).
                        '.' is the path seperator. All IPs belong to team 0.
                        Reflects/warns if F-98 inactive.
z       No-op           As spec. Reflects/warns if F-98 inactive.
{       Begin block     As spec; always pushes a new stack. A bug in FBBI before
                        the 2003.0722 patch meant that it only pushes a new
                        stack if n>=0. Reflects/warns if F-98 inactive.
|       North-south If  As spec. Reflects/warns if unefunge.
}       End block       As spec; always (attempts to) pop a stack. A bug in FBBI
                        before the 2003.0722 patch meant that it only popped a
                        stack if n>=0. Reflects/warns if F-98 inactive.
~       Input character As spec. Like FBBI, input is terminated by a newline,
                        and the first character in the string is used as input.
                        Remaining characters are kept in the input stream.
                        Errors are only possible in single-tasking mode. Like
                        &, only one IP is allowed input focus at a time in
                        concurrent funge.

All other cell values reflect (and produce a warning if the corresponding option has been enabled). By 'return an error' or similar I mean that the error will be returned in the Befunge program itself, i.e. the instruction will reflect. 


Fingerprints:
-------------

Documentation for the implemented fingerprints and the dynamic fingerprint system is to be found in the 'specs' directory. The dynamic fingerprint files should be in the directory <Befunge$DynaFing>, aka !Befunge.^.DynaFing. Dynamic fingerprints override any internal fingerprint by the same name. You can also use minifunge/funge-lib files; these are expected to be named by the ASCII version of the fingerprint, with a '/fl' extension to differentiate from dynamic fingerprint files. Since I have yet to find an official/complete minifunge/funge-lib spec, this feature hasn't had much testing. But in particular:

* The (,),=,h,i,l,m,o,q,t,u,x,{ and } instructions are disabled
* g and p now acces the parent fungespace (using the parent IP's offset)
* y reports on the parent fungespace
* Dynamic fingerprint M, S and Y are unavailable
* G and P access the minifunge fungespace (using the fingerprint IP's offset)
* The fingerprint IP's storage offset is set to the same location the IP starts from, in order to emulate the isolation of minifunge code segments.

In single tasking mode dynamic/minifunge fingerprints will always execute in one clock tick, but in multi-tasking mode this will only occur if the 'Input pauses' flag is enabled (Otherwise a fingerprint may try to gain input while a paused IP in the parent fungespace already has the input focus). Places where my implementations differ from the specs (or the specs are unclear) are listed below:

0x46494c45 - FILE:

  This fingerprint is disabled if file access is disabled.

0x4d4f4445 - MODE:

  Hovermode affects the following instructions: >,<,^,v,h,l,_,|,m - I've expanded the set to include the trefunge direction controls. Other instructions such as ?,x, and the TOYS T and U are unaffected (i.e. U will act like ? and set an absolute delta, then transform into a direction control which will set relative deltas).
  Invertmode and queuemode affect only the stacks - not the stack stack. When queuemode is enabled, stack peeks (e.g. with the y instruction) happen from the opposite end of the stack.
  Currently, iterating a switchmode instruction by 'k' will overwrite the k itself with the switched instruction (Providing the iteration count is above zero). E.g. 4k[ (or 5k[) will perform 4 (or 5) ['s, and leave the k overwritten with a ]. The [ itself will then be executed and overwritten with a ], producing 4]] (or 5]]). Switch instructions encountered while in stringmode will remain unchanged.
  Note that if you disable the funge-98 instructions while one of these modes is in enabled, it will continue to affect the IP.

0x4d4f4455 - MODU:

  U pushes the C result of 'x % y', or '(x % y)+y' if x % y is less than zero. This may or may not be 'Sam Holden's unsigned-result modulo', I've got no idea.
  R pushes the C result of 'x % y'

0x4F525448 - ORTH:

  Orthogonal get and put store the address vector in the opposite order to Funge get and put; thus P in Befunge would assume a stack of [value] [y] [x]. Apart from this change, the G and P instructions are exactly the same as their Befunge counterparts - reading an undefined cell will still return a space, not an error as the Orthogonal spec says they should.
  S works by outputting characters until a 0 is found, i.e. exactly the same as >:#,_$ in Funge.
  V and W set the X/Y delta of the IP to the top stack element. Attempting to use W in unefunge will cause a reflection/warning.
  X and Y set the X/Y location of the IP to the top stack element. This location change is not subject to the storage offset, and the value will wrap if it exceeds any fungespace limits. Attempting to use Y in unefunge will cause a reflection/warning.
  Z pops the top stack element, and acts like # if it is zero (i.e. skips the next instruction)

0x5045524c - PERL:

  This fingerprint assumes that <Perl$Dir>.perl is the name of your perl interpreter. Communication is done via temporary files, so the input/output strings can be any length. The string will automatically have sensitive characters escaped. E/I will reflect if an error occurs. Execution is subject to the same conditions as the '=' instruction (i.e. WIMP tasks return 0). The fingerprint is disabled if file access is disabled.

0x52454643 - REFC:

  If the scalar 'D' pops is unrecognised, the IP will be reflected. Note that storing REFC references in 8bit fungespaces isn't a good idea, since the references returned will become too large if more than 256 are requested in one !Befunge session. Note that 'S' will return the existing reference for a vector if that vector already has one.

0x5445524D - TERM:

  Addresses to G will be clipped to lie on the screen.
  Both L and S work by outputting characters until the end of the line/screen; thus a newline is likely to be generated, and the cursor will have moved.
  In mutli-tasking mode, D and U will stop the cursor at the top/bottom of the screen should it try to leave it; in single-tasking mode no checks are performed (The corresponding VDU codes are output the required number of times).
  This fingerprint probably doesn't work as it's meant to. In single-tasking mode it tends to assume the screen is 80x25.

0x544F5953 - TOYS:

  A pushes 0 cells if 'n' is <= 0
  B pops two values from the stack, f1 and f0, (in that order), then pushes f0+f1, then f0-f1. I think this is similar to a butterfly bit operation, but all the information I've seen about it involves the use of an extra weighting variable and lots of other behind-the-scenes bits to bring the variables closer to a sine wave (It's used in DSP). If anyone has any insight into how Chris Pressey wanted this implemented, let me know!
  Fungespace copying/moving/filling (C, K, M, V, S) does nothing to fungespace if any of the scalars in the size vector are <=0. All operate relative to the fungespace origin.
  C, K, M and V assume that the stack contains the data in the following order (rightmost being top of stack):
       [source address] [size] [destination address]
  F works as the spec says: The entire stack will be written out to fungespace. If i < 0 then it will be written out backwards, i.e. the x location will decrease for each item stored (Y will still increase though). If i is zero then nothing will be written; the stack will just be emptied. The storage location used is origin relative. Attempting to use it in unefunge will cause it to reflect/warn.
  G pops a vector and i as the spec says, but then it goes on to pop j (Since there is no other logical place for j to come from). It operates in a similar way to F, in that if i < 0 the area read will be reflected X-wise, and if i == 0 nothing will be read at all. The same holds for j, except that it will obviously be reflected y-wise. The storage location used is origin relative. Attempting to use it in unefunge will cause it to reflect/warn.
  H uses the C << and >> operators, which perform arithmetic (i.e. sign-extending) shifts.
  J leaves fungespace alone if the shift value is zero. If size limits are in place then the shifted area will not be wrapped, i.e. cells moved off the edge will be lost. In trefunge the shifted area is treated as a line of cells, not a plane. Reflects/warns in unefunge.
  L and R work as spec. They reflect/warn in unefunge (I could have made them return the cell the IP is on, but only returning L or R seems a bit silly)
  O leaves fungespace alone if the shift value is zero. If size limits are in place then the shifted area will not be wrapped, i.e. cells moved off the edge will be lost. In trefunge the shifted area will be treated as a line of cells, not a plane.
  S assumes the stack is of the form:
       [cell] [source address] [size]
  T will reflect the IP if the dimension number is less than zero or greater or equal to the number of fungespace dimensions
  X, Y and Z work as spec. If size limits are in operation then the IP position will be wrapped. If Y or Z are used in unefunge (or befunge for Z), the IP will be reflected.

0x54555254 - TURT:

  The turtle starts at the origin, facing east, with a black pen (up) and white paper. A heading of 90 degrees will make the turtle travel north (i.e. positive y). Internally the turtle coordinates are held with 8 bits of precision, ready for the Draw File output (256 Draw points = 1 OS unit, which is fairly close to 1 pixel).
  P and D will reflect the IP if the top of stack is not zero or one. D doesn't really do much though, since there is no graphical display at the moment.
  Instead, the I instruction will save a Draw File of the picture as the file <Befunge$Turtle> (Defaults to <Befunge$Dir>.Turtle - Change its value in !Befunge's !Boot file if you wish). The image will be shifted so that it lies fully on the page.
  Lowering and then rasing the pen will draw nothing; the turtle must actually move for anything to be done, even if it's a distance of zero (In which case a tiny line will be used, 1/256th the length of a turtle pixel)


Known bugs and miscellany:
--------------------------

* Note that it if you create a trefunge space with only the befunge instruction set, the only instruction available to allow travel through the Z axis is the 'Go away' ? instruction; all other trefunge instructions only become available if the funge-98 instruction set is activated.

* Due to limitations in the WIMP, the fungespace window is only able to display areas from (-2000,-1000) to (2000,1000).

* The multi-tasking version will automatically suppress input prompts if there are still characters in the input stream.

* Don't expect nonprintable characters to work in the IO window (e.g. VDU codes)

* The dynamic fingerprint system hasn't had much testing, so don't try straining it too much. In particular there may be bugs in fingerprint-q.

* Also the 'invisible fingerprint' given to fingerprint IPs does have a name, that of fingerprint number 0x00000000. Any attempt to load or unload a dynamic fingerprint of that name will fail (with a reflection as is normal), since that fingerprint is reserved solely for fingerprint IPs.

* Although none of the items are greyed out/missing when you click menu over a dynamic fingerprint window, trying to change most of them will have no effect.


History:
--------

V0.92 (3rd June 2005)

* Fixed a bug in the 'PERL' (0x5045524c) fingerprint; I was acting like E
* Fixed a bug where the status bar wasn't updating if the cursor wasn't visible
* Tweaked the source code to allow compilation of a platform independent command line only version of the interpreter; see the source code for full details

V0.91 (31st May 2005)

* Fixed a bug in the breakpoint code that caused IPs to skip breakpoints
* Updated the code to use my WOUM library, resulting in new WIMP code.
* Recompiled using GCC 3.4.4, presumably resulting in increased spiffyness.

V0.90 (1st January 2004)

* Fixed a typo in the --help text, and its !Help counterpart
* Converted the source code to C, since there was no real reason for it to be in C++. This has also shaved 30K off the executable :)
* Fixed a possible bug in the '=' instruction and PERL fingerprint execution code for if Sys$ReturnCode is not set, and updated the code to return 0 if a WIMP task is started.
* Fixed a possible memory leak in the redraw code
* Tweaked the redraw code a bit so it won't center the program window on the cursor if the reset button or page up/page down are used
* Rewrote the cursor insert modes to fix a few bugs, such as super-code-insert not working with consecutive direction change instructions.

V0.89 (5th September 2003)

* Fixed the save code so it works again
* Fixed a bug in the stack size reading code which could cause a crash if the stack hadn't been used yet
* Fixed the --args command line option so that '--args' itself doesn't appear in the argument list
* Fixed funge program command line arguments so escaped characters and quoted strings work

V0.88 (26th July 2003)

* Confirmed a few bits of information with Chris Pressey:
* h should set the IPs delta to (0,0,-1)
  * Thus --up-is-down has been removed, since it is now known as the correct behaviour (and so there is no danger of me changing --up-is-up to the default)
* { and } should always push/pop a stack
* File height should be number of newlines +1 (or max of heights if in trefunge), and depth is number of form feeds +1. Width is max of the number of chars per line (so an empty file would be (0,1,1)).
  * Changed the file load code to ensure it follows the above system (before it would return (0,0,0) for an empty file)
  * Changed the file save code to ensure that files with size scalars of zero are saved properly (i.e. (0,5) should output 4 newline chars).
* Fixed the minifunge/funge-lib mode to ensure that =,i and o are disabled

V0.87 (24th July 2003)

* Fixed HRTI to use microseconds and not milliseconds
* Added 'BASE' (0x42415345), 'CPLI' (0x43504c49), 'DIRF' (0x44495246), 'FILE' (0x46494c45), 'FIXP' (0x46525448), 'FRTH' (0x46525448), and 'TERM' (0x5445524d) fingerprints. They haven't really been tested though.
* Added R to the dynamic fingerprint fingerprint
* Made dynamic fingerprints execute in one clock tick in single-tasking mode, and added the 'Input pauses' flag to emulate this in multi-tasking mode
* Swapped dynamic fingerprint pick (K) and roll (O) instructions so they work properly; i.e. pick duplicates the item while roll shuffles it ('rolls it') to the top. I'm blaming the PJSF fingerprint specs, since those are what I based the V0.85 code on
* Added minifunge/funge-lib compatability
* Added --up-is-up and --up-is-down to configure the 'up' direction, due to the contradictions in the Funge-98 spec
* Fixed the IP trace information so that the delta is displayed properly
* Protected a few instructions from buffer overruns and '(',')' from taking ages for large n (i.e. if a program accidentally deletes the 1 before executing ')')
* Added the Cursor Lock mode
* Made right clicks on the dimensions box cycle through '80,25'->'*,*'->'*,*,*'->'*'
* Fixed a redraw bug where an IP created by 't' wouldn't get drawn just after being created
* Sped up the IO window scrolling
* Fixed some bugs with input focus gaining with dynamic fingerprints
* First version to have its source code released

V0.85 (22th July 2003)

* Fixed a bug which made ;'s and their contents get executed
* Tweaked the file size reported by 'i', and fixed a bug with the y size when loading trefunge files
* Fixed 'i' so that it pushes the size and location vectors in the correct order
* Fixed '{' so that the data is moved from the current stack, not just copied
* Revamped the fingerprint system to allow for better operation, and changed it to be spec-compliant (i.e. one stack per instruction instead of a stack of fingerprint semantic frames)
* Fixed '(' so that the generated fingerprint and a 1 are pushed onto the stack
* Fixed ')' so that it pulls a fingerprint off of the stack instead of unloading the fingerprint that was last loaded.
* Added the 'HRTI' (0x48525449), 'PERL' (0x5045524c), 'MODE' (0x4d4f4445), 'MODU' (0x4d4f4455), 'ORTH' (0x4f525448), 'REFC' (0x52454643), 'TOYS' (0x544f5953), and 'TURT' (0x54555254) fingerprints. MODU might not be correct though. Not all instructions have been tested.
* Added hovermode, invertmode, queuemode and switchmode IP modes for the MODE fingerprint
* Added the dynamic fingerprint system
* Fixed single-tasking operation so that the program is supplied its arguments
* Changed '=' to use Wimp_StartTask when under the WIMP
* Changed the IP kill code so that, when multi-tasking, the text buffer won't get emptied if the IP was the input IP. Not that the death of an input IP is really possible without it being the whole Befunge program closing though.
* Fixed the multi-tasking input prompt skipping so it only prints the prompt if the input buffer doesn't contain a valid answer on the 1st attempt
* Might have fixed a bug where multiple IPs could get the input focus at once. In any case, it shouldn't be able to happen now.
* Also made it so that (wrt the multitasking version) if an answer to an input request is in the buffer then it will be returned immediately instead of taking 2 clock ticks
* Made sure the multi-tasking and single-tasking input handling is the same
* Made it so that the first press of the play-pause button will create an inital IP but not run it
* Fixed a bug where holding down the pause button could cause multiple IPs to be spawned
* Removed the loaded semantics column from the IP window since semantics can now be mixed and matched all over the place
* Added the 'Breakpoint here', 'Cell value' and save/spool output menu options
* Fixed various redraw bugs and sped up fungespace/io redraws a bit
* Added auto --nowimp activation to make using !Befunge from the command line easier
* Added the Insert modes to the fungespace editor

V0.70 (14th July 2003)

* Fixed a bug in the 's' instruction (i.e., made it work)
* Fixed the 'k' instruction so it works like FBBI
* Fixed the '{' instruction so it sets the new storage offset to ip pos+delta
* Fixed stringmode exit to make sure it skips any trailing spaces
* Fixed funge-98 stringmode to ensure ;'s are read instead of skipped
* Fixed 'i'/file load so that spaces are skipped (doh!) and data in extra dimensions are loaded as binary (e.g. loading a befunge file into unefunge will load the entire file, with line feeds marking the ends of each line)
* Fixed 'i' so that the start location of the load is pushed onto the stack along with the size (previously only the size was pushed)
* Fixed 'i' so that file sizes are reported properly
* Fixed 'y' so that the operating paradigm is 0 for programs without file access (since file access and = are controlled by the same switch)
* Changed a few bits of code to improve their speed when under extreme conditions
* Fixed a bug with the fungespace dimensions icon in the new file/load file window, which restricted its size
* Fixed a redraw bug or two
* Fixed a bug in the 'go to location' menu where only the last coordinate was not allowed to be negative
* Fixed a bug in my WIMP library which allowed the WIMP version of the program to start when in the command line
* Tweaked the redraw code a bit to improve speed
* Changed the cursor behaviour: Now ctrl+dir changes dir, while dir on its own only moves in that dir
* Changed the toolbar operation: Now adjust must be used to enter the 'slow play' mode
* Made the status line display the direction the cursor is heading, and the program input flag
* Gave the status line the ability to display alert messages
* Changed the 'q' program exit message to appear on the status line instead of the IO window
* Added unimplemented instruction warnings
* Added the breakpoint system

V0.55 (7th July 2003)

* First release


Credits:
--------

!Befunge was written by Jeffrey Lee (me@phlamethrower.co.uk).

Visit his very silly website at http://www.quote-egnufeb-quote-greaterthan-colon-hash-comma-underscore-at.info/ for more Befunge goodness :)
