Descripción del contenido de la página

Historial del desarrollo de Forth 5mx, un Forth para la computadora Psion 5mx, escrito en OPL+.


A pesar de que el desarrollo de Forth 5mx está detenido, de vez en cuando le hago algún retoque al programa.

Este fichero contiene la relación detallada de cambios realizados al programa desde sus orígenes.

Código fuente


Copyright (C) 2004-2010 Marcos Cruz (

This file is part of Forth 5mx.

Forth 5mx 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
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, see <>.


- This version history is a detailed work diary
to register every little change in the code.

- In this text all Forth 5mx words are uppercase.
Nevertheless in the code of the program and its
comments (both OPL and Forth), uppercase is used
only for ANS Standard words.

- Forth words mentioned in this and any other text always have
spaces at both sides, to prevent misunderstandings.

Forth 5mx History


- In forth5mx_procs.opp, `editcmd%(Kmaxcmd%) = 22` caused an error because
  `Kamxcmd%` was not defined. It seems an unfinished improvement, because the
array definition is `local editcmd%(13)`. The fix is `editcmd%(12) = 22`.

- Bug found in proc lineedit$:(): every special key performs a backspace.
  The reason was the "not" notworking, so the first command was always matched:
  until not editcmd%(cmd%) or editcmd%(cmd%)=key%
  I don't remeber why I changed that in 2010-07. The solution:
  until editcmd%(cmd%)=0 or editcmd%(cmd%)=key%

- Some improvements in the proc lineedit$:(). The cursor is not shown any more after entering the command.
- Bug fix: in the proc lineedit$:(), Ctrl E called the missing proc bye:(). The proc bye:() has been created with the code at the label xbye::, and it's called from both places.

- License added. Final revision before publishing.

- New word NEWLINE in the extend file, needed by the Forth Foundation Library.

- New primitive D= , but not finished.

- Bug fixed. The proc number:() didn't work with hex digits because of the last changes.

- Bug fixed. The proc numberq:() didn't work with upper case hex digits.
  I rewrote it with COPX functions.
- Bug fixed. The proc number:() didn't work with upper case hex digits.

- The input line proc is rearranged at the right and left arrows control structures (no new funcionality added).
  This is the first step to implement a variant of the word movement, with Control+Shift: go to the nearest space or dash.

- The command line history is kept beetwen sessions,
  in a text file.

- New high level word in the extend file:  2LITERAL
- New high level words D- and DNEGATE don't work yet because they depend on words not defined: UM+ and D+ .
- New high level words [IFDEF] and [IFUNDEF] .
- First coding to keep the command line history beetwen sessions,
  in a text file.

- The unfinished [IF] is factored into pieces to make it easier to debug.
  Nevertheless a don' t success to get the recursion to work (it's an old bug).
  I use the code from pforth.
- Bug fixed in . (dot): when _TOS was not defined, the minus sign was not shown because a wrong offset in the peekl().

- The behaviour of the up and down keys at the commad line is interchanged. Now they behave like in GNU bash.
- Text added at the hello message: " A 'will be ANS' Forth for the Psion 5mx computer"
- First incomplete version of the word ENVIRONMENT? , in the extend file.
  that are defined as high level constants,
  and with most of the rest, defined as constants.
  In they future the word sets query strings could calculate their result,
  or at least be defered words for easier update.

- Bug fixed in the proc unlimited_ioread.
  The end of file was not detected in READ-FILE .

- Added C+! as a primitive.

- MOVE modified: it moved cells and now it moves bytes
  (I misunderstood the standard). I comment it out and
  make it use the code of CMOVE .
- WARNING flag primitive variable implemented for redefinitions check.
- _WARNING macro created to select wheter this featured will be compiled into the Forth system or not.
- _FIND_LOCALS macro created to define also in header&:() (in the file forth5mx_procs.opp) the locals used by the included file forth5mx_inc_find.opp.
- I start working on the Search and Search Extensions wordsets:
  KWordLists% created.
  CURRENT created as a primitive variable.
  CONTEXT created in OPL but as a high level variable with alloted space.
  SET-CURRENT created in the extend file.
  GET-CURRENT created in the extend file.
  DEFINITIONS created in the extend file.
  LAST-WORDLIST created as a primitive variable.

- CS-ROLL and CS-PICK defined in the extend file.
- EMIT? defined in the extend file as defered to TRUE .
- MS implemented as a primitive, but with the 1/20 seconds resolution of the OPL pause.

- Bug fixed: there was call to the old proc prompt:() in the editor, after changing the screen font.
  It was replaced it by the macro _OK, factored from the macro _PROMPT.
- The useless constant KRelease% and its Forth partner are commented out.
  A new macro _VERSION is defined at the very beginning of the program
  and used in the proc hello:(). No way to access it from Forth yet.

- New constant KIncludePath$ to be used in assembler loading functions.
- Path deleted from all OPL+ #include.

- Bug fixed in SCREENINFO : two returned values used the same stack position.

- Bug fixed in QUIT : the loop that closes all opened source files didn't updated the source recursion.
  That's way the Forth system crashed after an error in a source file.

- New macro _SBUFFER_FREE and new primitive SBUFFER-FREE , both needed because of the
  new word SBUFFER-FREE in the file sbuffer.f.

- Bug fixed: Macro _PLUS_SBUFFER modified to reflect the changes
  in the high level version (file sbuffer.f).

- Bug fixed: The Forth word FILE-READ inherited the OPL ioread() 16 KiB limitation!
  I wrote the proc unlimited_ioread& to solve that.

- Little bug fixed in the debug proc: the stack pointer chars ("<" and ">") did not show at the start.

- C! made a bit faster using "peekb()" instead of "peekl() and 255".

- Bug fixed: PLUCK did the same than OVER when _TOS was not defined.
  The bug was found while implementing the machine code data stack.
- The OPL code of the word + is improved. Now it is a bit faster: It does not use the macro _NIP any more. This way it saves one "Peek and Poke" step.

- Finished the changes to make conditional compilation on _DSOURCE, though the _DSOURCE part is now written yet.
- Finished the alternative compilation for the string buffer, with C descriptor objects. It doesn't work yet, it resets the Forth.

- Sysram1.txh changed to Sysram1.oxh because standard OPL does not accept it (I still depend on OPL because the app created by OPL+ doesn't run: I must compile the OPL code created by OPL+ must be recompiled with the standard OPL compiler. I don't know
- Macros _PARSE and _PARSE_WORD are renamed to_PARSED and _PARSED_WORD.
- New _PARSE and PARSE_WORD macros, ANS compliant.
- New faster macro _PARSE_TOS used in the word PARSE .
- New faster macro _PARSE_OFF used in the comment words ( and \ instead of the normal _PARSE.
- OPL+ code modified to reflect the changes in the parse macros.

- Sysram1.txh included and GETFILESIZE activated.

- Finished the new versions (without _TOS) of LSHIFT and RSHIFT.

- New primitive EVALUATE .
- procs save_source and restore_source now are #included in the main code, to be used by EVALUATE and INCLUDE-FILE .
- proc close_source_file and close_file are deprecated. Their content is now in INCLUDE-FILE .
- (SOURCE-ID) and SOURCE! are not needed any more but kept.
- New local file_id%.

- Try to write EVALUATE in high level, based on the code of Win32Forth.
- sourceid% and family changed to sourceid&.
- New primitive variable (SOURCE-ID) to change from high level code the value returned by SOURCE-ID .
- New primitive SOURCE! to change the values returned by SOURCE .

- The arrays xt&, name&, and control_bits%, and the allocated space at names& are all deprecated.
  Now one allocated space, at headers&, holds all that information. Macros are used to fetch addresses and values from headers&.
    I did it because the proc data space was full with 2048 Forth words, and I needed to compile more that that.

- New primitive word 2CONSTANT .

- Bug fixed: ALIGN now used instead of ALIGNED after using all CREATOR" in the extend file.
- The debug process for the conditional compiling on the TOS macro is almost finished.

- Big changes begin, to make a faster Forth by three ways:
  1) Use only local variables if possible (so all code must be in one proc, and calling procs be simulated with #include).
    2) Use assembler versions (with OCX) for as much primitive words as possible.
    3) Use C++ functions and descriptors (with CPX).
- The forth virtual machine proc code is moved into the main Forth proc.
- The load_line proc code is moved into the refille proc.
- The refill code is #included where needed.
- The code of build_variables, build_constant and build_hilevel are moved into the main proc.
- Transformed the string: proc into the _STORE_STRING macro.
- Made a much simpler version of the _STORE_STRING macro, called _COMPILE_PARSED.
- Transformed the constant: proc into the _CONSTANT macro.
- Transformed the variable: proc into the _VARIABLE macro.
- The prompt: proc is transformed into a macro (without the battery message thing).
- The bye: proc is deleted, and a simple stop used instead.
- Proc numberq&: renamed number&:.

- New primitive word (-LOOP) and new word -LOOP .

- New primitive words TOLOWER and TOUPPER taken from gforth.
- LOWER modified like UPPER before.

- UPPER modified: now it doesn't return a new string. It's the way most of the UPPER I know work.

- Finished and fixed the code to close all open source in QUIT , so also in ABORT .
- Bug fixed in [COMPILE] : after a "not found" error, now ABORT is called.

- Added dummy empty definitions for ENVIRONMENT and FORTH5MX in the extend file. They are needed to make some code compatible with other Forths.

- Bug fixed. I forgot the POSTPONE in LITERAL :
    : LITERAL ?compiling POSTPONE (literal) , ; IMMEDIATE

- CD renamed CHDIR because CD is a valid hex number (I saw this change in the Win32Forth sources).
- CD" renamed CHDIR" too.

- New word INCLUDE? in the extend file, taken from pForth.
- ?COMPILING added into LITERAL and ['] .
- I changed this code:
    : literal, POSTPONE (literal) , ;
    : ['] ' literal, ; IMMEDIATE
  to this:
    : LITERAL ?compiling (literal) , ; IMMEDIATE
    : ['] ?compiling ' POSTPONE LITERAL ; IMMEDIATE
  I think it is clear now. Also, I was not sure the old version was really bug free.

- New macros _2RDROP.
- New words RDROP and 2RDROP .
- Bug fixed in FILE-STATUS : the stack was not properly expanded.

- New macros _INCREASE_STACK, _PUSH?(), _DUP and _RDROP.

- The label xexit:: is moved just before xnext:: to spare one jump. It is litle bit faster.
- New macro _3DROP to make the code easier to read.
- New primitive CMOVE> (it was already written but not linked to any header).
- New macro _DEPTH.

- Important bug fixed in the FVM: NEXT pointed to NOOP and EXIT pointed to NEXT ! That's why EXIT didn't work when called from a high level definition.
- ?DO finished and tested! The new primitive (?DO) does the job.
- LOOP fixed : In PsiForth, the loop finished when index>=limit but in ANS Forth the condition is index=limit.
- +LOOP fixed: In PsiForth, the loop finished when index>=limit but in ANS Forth the condition is index>(limit-1).
- New macro _NIP .
- First draft of a fixed version of _PARSE_WORD (the actual behaviour is not ANS because it returns an OPL string, not the string address inside the Forth input buffer).

- All macros renamed to begin with an underscore.
- New macros _PARSE_WORD and _PARSE used instead of parse_word$:() and parse$:().
- New macros to make the string buffer code simpler.
- Bug fixed in FIND , caused by the yesterday changes: when the word as not found, the c-addr was not keep.
- New primitive: QUERY .
- New macros to call words in the OPL code: _CALL_XT, _CALL_NT and _CALL_WP
- New primitive INTERPRET . Now INCLUDE-FILE and QUIT calls it with OPL+ macros.
- New primitive EVALUATE . Not finished yet.
- Improved SAVE-INPUT and RESTORE-INPUT to include the new variable ib_len&
- New OPL variable ib_len&, needed to implement EVALUATE . It has to be initialized every time ib$ changes. The _PARSE macros familiy is updated to use it.
- New macros _DROP and _2DROP .

- MARKER fixed: now it stores also the threads.
- New macro COMMA?() used instead of the proc comma:().
- New macros CALCULATE_HASH and  LOCALS_OF_CALCULATE_HASH used instead of the proc hash%:().
- New macros GET_PACKED and GET_PACKED_LOCALS used instead of the proc packed$:().
- Improved the OPL code for FIND : as the parameter is a counted string, there's no need for stack manipulation and GET_PACKED. We use the OPL peek$ function instead.

- ALIAS added as a primitive. Aliases has the same xt than the original word.
  That causes some strange effects.
  The code:
    ' TYPE alias retype  ' retype >name .name
  will show "TYPE". Also, WORDS will show RETYPE as a primitive,
  because it uses the xt for calculations.
- First draft of SEE written, in an apart source file. It only dumps the definition header, for helping while debugging.

- The command history system was buggy. Fixed.

- showline proc simplified and improved: automatic horizontal scroll implemented, so now it is possible to edit lines longer than the screen width. The whole code has been much simplified: no more nested if-endif needed!

- lineedit$ proc improved: clipboard paste with Ctrl-V. Useless option "menubutton" removed (it displayed the task list).

- lineedit$ proc improved: movement across words with Ctrl+Left and Ctrl+Right. Also, trailing spaces are not erased any more after moving the cursor to the line start.

- Command line history implemented. Nevertheless, the OPL proc data space is almost filled and there's room only for 3 lines. I may store the history in a memory heap instead, or in the Forth data space.

- The word DEBUG-SOUND? renamed ERROR-SOUND? . Now Forth makes sound  before reporting an error.
- Now the debugging after an error is optional.

- proc debug%:() improved: option to turn the debugging off.

- New word DEBUG-SOUND? for provisional debug sound control. The sound itself can not be changed from Forth.

- KMaxHeaders% = 1300

- Larger margins for .R in .HEADER to make the WORDS list clearer.

- New variable DEBUG? to turn debugging on and off; OPL debug% proc modified accordingly.
- New word S' that does the same as the ANS S" but with single quotes. I need it to use doble quotes inside strings in a program!

- Modified the OPL code for the word .R ; fixed the bug that avoided to print -1.

- Gforth version of SEARCH taken out from the extend file.
- F83 version of SEARCH taken out from the extend file (still not adapted).
- OPL version reactivated. So SEARCH is a primitive now. It can not work with strings longer than 255 chars.

- New word D>S in the extend file. Unfinished: it does not care about signs.
- Fixed bug in REPOSITION-FILE : the D>S equivalent code dropped the wrong byte. Used the new D>S instead.
- The buggy FILE-SIZE has been rewritten. Now it works, but it is unfinished: it returns a dummy ior flag.
- New procs version$ and mm$ to calculate the program version from the compilation date.
- C! and C, are modified to be ANS compatible: they store only the low order byte.

- New word GEFILESIZE , from the OPX SysRam1. The standard word FILE-SIZE is not ready yet. Unfinished. I need the OXH file.

- New system for the program version: date and release.
  So, KVersion%, KRevision% and their Forth equivalents are deleted. New constants KRelease and RELEASE .
    The proc build$: is renamed version$: and rewritten.

- New word PLACE in the extend file.
  It was taken from "An so Forth..." by J.L. Bezemer, 2001-04-06,
  but I had a word called STR! that did the same, just better. So I used my code for PLACE .
- New words SVARIABLE and CERASE in the extend file.

- COLDSTART modified: now it calls EXTEND before QUIT . That way, the extend file is automatically loaded every time.
  It also calls CR and PROMPT .
- Because of that change, source_recursion% has to be initialized to 1.
  That is needed for the procs save_source and restore_source to work before QUIT inits source_recursion%.
- New OPL variable dp0& to store the data pointer address after creating all primitive words.
- COLD modified: it restores dp& to dp0&.
- So now Forth 5mx automatically loads the extend file at the start and can be reseted with COLD .

- New primitive ANS word FILE-STATUS .

- New primitive ANS word UNLOOP.
- Bug found: It seems that MARKER does not work fine yet. I think the problem is the thread array.
- Proc debug: renamed to debug%: and modified: new abort option.
- The PsiForth structure of (OF) is made cleaner, with only one exit point.
- Stack comments added to ENDCASE.

- Bug found: MARKER should store thread_pointer% too.
- The word MARKER is rewritten as a primitive. That was simpler than making thread_pointer% accesible to Forth code.
- New primitive word (MARKER) to do the job of the words created by MARKER.
- CREATOR array modified to include MARKER .

- Deleted two calls to the proc file_name$: (that doesn't exist yet), in DELETE-FILE and DIR .

- New primitive variable DP for the address of dp&, whose value is returned by HERE . DP was needed to write MARKER .
- Fixed bug: The OPL code of (VALUE) was written right after that of (PRIMITIVE-VARIABLE) . That made the later to execute the former, instead of the code of (CONSTANT) .
- MARKER finished. It keeps and restore the values of DP and (LATEST) .

- Fixed bug in SCONSTANT : ALIGNED should be ALIGN .
- New primitive word (VALUE) .
- New words in the extend file: VALUE <TO> [TO] and TO .
- <TO> [TO] and TO do the same as <IS> [IS] and [IS] .
- Added the new element "value" to the creators array used by WORDS .

- DODEFER renamed (DEFER) .
- NOP renamed NOOP .
- DEFER rewritten combining the original PsiForth code and the one in the gforth file defer.fs.
- New words <IS> and [IS] copied from the gforth file defer.fs.
- IS rewritten in the extend file, to use <IS> and [IS] .
- (DEFER) modified because of the extra cell in CREATE .

- New variable (LATEST) to return the address of last_nt&.
    That will be needed to write MARKER . The word LATEST remains unchanged.
    Other solution could be to make LATEST itself the variable and change the code in the extend file.

- Code migrated to OPL+ with Neuon OPL+.
- New proc build$:() to return the build date.

- New unique UID from Symbian.

 - New primitive word :NONAME .
 - New primitive word ** (raise to a power).
 - New primitive word RSHIFT .

- New high level word WITHIN , taken from the ANS Forth documentation.
- New primitive words C" and (CSLITERAL) .
- New primitive words TIB and #TIB .
- New variable SPAN .
- New primitive word EXPECT .
- Bug fixed in OPL proc lineedit$:(). The lenght parameter is made long integer to receive tos& as lenght from EXPECT and ACCEPT. The new constant K80& is used to call lineedit&:() from refill&:(), because OPL doesn't accept simply 80 any more (why?).

- STRING: renamed to SCONSTANT in the extend file.

- New primitive word EXTEND to load the extend file, now renamed forth5mx_extend.f

- New word 2ROT in the extend file.

- DEBUG renamed (DEBUG") .
- New immediate primitive DEBUG" that needs a text in the input stream. In compile mode, it compiles (DEBUG") .
- New primitive DEBUG that doesn't need a text. It is easier for interpret mode debugging.
- The DUMP code is factored out in the new proc dump:(), to be called by debug:().
- debug:() improved with a DUMP command for both stacks.
- S0 and R0 renamed to SP0 and RP0 for clarity.
- New constants in the extend file:
  They make the control structures code more clear.
- New primitive DEBUG# that needs a number on the stack as the debug point title.
- (LOOP) and (+LOOP) words modified with an "else" for clarity.
    They had two exit points (for speed, perhaps? I should test it).

- Bug found in EXIT : it doesn't exit. To solve it, DEBUG must be improved.
- Improved debug:(). Now it is possible to examine also the return stack.

- Little POSTPONE bug fixed: in the OPL code, the "not found" error needed a "goto xabort" after it.
- Serious bug found: variables created by OPL as STATE , >IN and BASE ,
  returned the address of their own PFA, not that of the OPL variable (that was stored in the PFA).
  This bug was "programmed" by me with my last changes one month ago.
  Solved by using a new word, (PRIMITIVE-VARIABLE) , to make the runtime job.
  In fact, its code is that of (CONSTANT) .
  The inner workings of WORDS are modified to list such words like normal variables.

- VARIABLE and CONSTANT are primitive now. That way, they don't depend upon CREATE .
- New proc variable:(). That way, WORDS lists the properly the variables created in OPL.

- New primitive (CREATE) .
- WORDS modified: it now lists properly words created by CREATE and DOES> .
- WORDS modified: it now uses nt (name token) instead of xt (execution token).

- "nfa" (name field address) comments changed to the more logical "nt" (name token).
- last_nfa& renamed last_nt&.
- header&:() changed. It compiles the nt (name token) before the cell that will be pointed by xt.
  That way, >NAME is straight and nothing else is affected.
- New proc parse_word$:() that does the same as word$:() but always with a space as delimiter. It's a bit faster.
- New primitive word PARSE-WORD , not in the Standard but mentioned in it.

- Proc header&:() modified: it does not return last_nfa& any more. Only primitive:() used the return value.
- Unused proc colon:() deleted.
- In PsiForth, <BUIlDS was needed to allot an extra byte before
  calling CREATE . That cell was used to store
  the address of the run time code after DOES> .
  The problem is that <BUILDS does not belong to the ANS Standard,
  and indeed and extra cell is needed to store that addrees in the defined word.
  To use the standard form CREATE DOES> I had to change CREATE this way:
  Now, all headers created by CREATE have an extra cell before the pfa.
  It is used by DOES> to store the address of the run time code.
  This change forced the change of the following words:
  Now all those words skip the extra cell.
  The word DODOES was adapted and renamed to (DOES>) .
  It is compiled by the new DOES> in the last defined word.
  Also the procedure constant&:() had to be adapted.
- Unused return deleted in proc constant&:(), renamed constant:().
- Proc handler:() renamed to handler&:(), because it returns last_nfa&.
- Proc primitive:() renamed to primitive&:(), because it returns last_nfa&.
- ' DOCOLON EXECUTE failed because of the PsiForth
  distinction between primitive words created by handle&:() and those created by primitive&:().
  Words created by handler&:() did not stored their xt in xt&() but their name number.
  Such distinction, I think, was made to list the word creators in WORDS , but
  it was not logical and made the word >NAME complex and terribly slow (it uses a brute force search algorithm!).
  I got rid of handler&:(). Now all primitive words are created by primitive&:().
  To make >NAME simpler and really fast, I have to store the name number in the dictionary, to make it accesible with xt.
  Anyway, the glossary used (xt, cfa, nfa...) is not exact. I have to compare it to the Standard.

- New proc unsigned:().
- New procs signed_unsigned:(), complement2:(), signed&:().
- Finished U. and U.R .
- Written U< and U> .

- Fixed little PsiForth bug: the word . failed when printing the biggest number: 2147483647.
  To solve it, one of the arithmetic operations was divided in two steps.
- First workings to write words U. and U.R .

- In the extend file: Used POSTPONE instead of COMPILE and [COMPILE] .

- Bug fixed in report_error. The calculation of errorlocation% can not be negative anymore.
- s0& and r0& renamed to sp0& and rp0& for clarity.
- PROMPT factored to an OPL procedure to be called from PROMPT itself and QUIT.
- REFILL factored to an OPL procedure to be called from REFILL itself and QUIT.
- QUIT is now a primitive and ANS compatible.
- Deleted the PsiForth primitive INTERPRET . Now its job is done by QUIT .
- ABORT modified. It is another name for QUIT . I don't understand their difference in the Standard.
- COLD modified to call QUIT instead of PROMPT and ABORT .
- Now we use x prefix only for Forth execution tokens or OPL execution labels:
  xbattstat& and xvolume& renamed to battstat& and volume&.
  xstate& and xbase& renamed to state& and base&.
- The word NEXT did not have name. Now it has.
- All OPL abs() (floating) changed to iabs() (integer).
- proc loadline$ renamed loadline&. It now returns a flag, used by REFILL.
- REFILL does not test if the input buffer is empty. No more need for that.
- INCLUDED , INCLUDE and INCLUDE-FILE not only open the file as before, but interpret and close it.
  Now they are ANS compatible and their bugs are fixed: interpretation or execution continues after them.
  Note: The code of their interpreter is duplicated from QUIT (no way to factor it yet).
- BYE factored again to a procedure, because the line editor calls it.

- "Unfixed PsiForth unbug" that was "misfixed" in 2005.03.13:
  The word LEAVE was fixed to work only in compilation mode, but that's wrong.
  Now it keeps the mode control, but compiles the new primitive word (LEAVE), which does the run-time job.

- Deleted the unused PsiForth word (CREATE) . CREATE now does the whole job.
- tp% renamed to thread_pointer% for clarity.
- LIT, renamed to LITERAL, for clarity.
- LIT renamed to (LITERAL) for clarity, like (SLITERAL) before.

- New high level ANS word CHAR in the extend file.
- CMOVE changed to be ANS compatible.
- New ANS primitive word CMOVE> .
- New ANS primitive word MOVE .
- The PsiForth word MOVE$ is renamed SMOVE and upgraded: faster and smarter.
- $, renamed to S, and changed:
  It doesn't align the data space pointer any more. SLITERAL must do it. That's more logical (also C, doesn't align).
  It uses the new word SMOVE to do the job.
- SLITERAL modified. It now uses duplicated code of S, , and aligns the data space pointer.

- Fixed silly bug in POSTPONE that causes the compilation of non immediate words fail.

- Deleted the PsiForth word COMPILING that did STATE @ .
- Fixed bug in SLITERAL : the final goto xnext was missing. It causes the word go to next primitive in intepreting mode.
- Fixed bug in SlITERAL : It was used 1 instead of KImmediate% in its creation. That's why POSTPONE didn't work with SLITERAL .
- The word [COMPILE] is rewritten as a primitive.
- The word POSTPONE is rewritten as a primitive.
- The PsiForth word ?ERROR was renamed ?ABORT and modified to do the function of the high level (ABORT") that was compiled by ABORT" .
- Deleted the high level language (ABORT") .

- Sorted the extend file. ANS Forth words in upper case. The PsiForth words are moved to extend_psiforth.txt file.

- Bug fixed in plus_sbuffer&:(). It returned one byte more in the string lenght. It caused COMPARE to fail, an so [IF] .
- New primitive U< . Provisionally, it is a synonym of < .
- New primitive MOVE . Provisionally, it is a synonym of CMOVE .

- numberq:() and number:() renamed to numberq%:() and number&:().

- New variable /SBUFFER .
- New primitive SBUFFER+ .
- Improved +SBUFFER .

- Commented the return stack effect of >R R> 2>R 2R> R@ and 2R@ .
- Fixed little bug in debug:().
- string_to_buffer:() renamed to to_sbuffer:() and factored with the new procedure plus_buffer:().
- New primitive +SBUFFER .
- New primitive SBUFFER .
- New variable (SBUFFER) .
- New constants 'SBUFFER and 'SBUFFER; .
- New primitive SBUFFER+! .

- New primitive >SBUFFER to store a string in the circular string buffer.
- string_to_buffer:() improved: it doesn't align the buffer pointer, there's no need.
- All global temporal variables now are locals in the main loop procedure. That is faster.
- The procedure hash:() is improved for more speed.

- Deleted the word CLS . The standard word PAGE was created some time ago, but CLS was not deleted.
- The procedures don't use global temporal variables any more, but locals. That is safer and faster.
- Deleted the useless proc bye:(). The word BYE can do the stop.

- The following words are fixed (they don't use pad$ any more):

- Fixed bug in S" , $, and (SLITERAL) : the dp update didn't calculate the byte needed to store the string lenght.
- Improved debug:(), inspired in a Forth code of mine. It now can examine any stack element and use the words ? and TYPE .
- New primitive SCREENINFO , analog to the OPL command.
- Fixed bug in $, : the stack manipulation was wrong. The original PsiForth code was right.

- The proc string:() now uses poke$ instead of move:(). That is easier.
- S" uses string_to_buffer:().
- WORD and PARSE use string_to_buffer:() instead of string:() and pad&, and then fix the stack.
- UPPER and LOWER use string_to_buffer:() instead of string:() and pad&.
- The words (SLITERAL) , S" and $, now call cell_aligned&:() instead of doing the calculation "x& = ((y&) or 3) +1".

- New: circular string buffer in allocated memory. That solves the PAD use problems. Now several strings can be used without the last to corrupt the last but one. The Standard clearly says that no standard word uses PAD.
- New proc string_to_buffer:() and related global variables.
- New proc cell_aligned:() to make the one cell alignement.

- Simplified the end of S" : there is no need to go to $, , MOVE$ and CMOVE because string:() already places the string. It's enough then to adjust dp& and go to 2DROP.
- Bug found in SLITERAL : The compilation of (SLITERAL) corrupts the string in PAD stored in the dictionary space.
- Changed PAD : it returns de address of pad$
- All PAD operations are made with pad$. No need to use the dictionary space.
- WORD and PARSE simplified: no need to call string:() at the end, they can use the address of pad$.
- The changes about PAD solve the SLITERAL bug.

- Renamed the PsiForth $LIT to the standard SLITERAL .
- Added a compile only check in COMPILE .
- Fix: SLITERAL renamed (SLITERAL) .
- New immediate primitive SLITERAL that compiles (SLITERAL) and stores the string on the stack into the dictionary.

- Fixed bug in the backslash$ procedure.
- Fixed serious Forth 5mx bug: The variable& procedure and variable_integer& created constants with the variable values. They should create constants with the OPL addresses of the OPL variables. The original PsiForth code used constant& and addr(), what
was right, but I decided to factorize and forgot to finish the code. I found the bug when working on my FHP program: the Forth STATE variable didn't change when the OPL xstate& variable did!
- Deleted the useless variable& and variable_integer& procedures (in PsiForth, already existed the variable& procedure, but it was not used and it did the same as the constant& procedure).
- The build_variables procedure uses now constant& instead of the two deleted procedures.
- So, xstate% has to be changed to xstate&.
- So, toin% has to be changed to toin&.

- New primitive DIR$ analog to the OPL dir$.
- New primitive SETPATH analog to the OPL setpath.
- New procedures whole_path$, only_path$, parent_dir$ and backslash$.
- New global array recursive_path$.
- New global variables home_path$ and include_path$.
- Goal finished!: the include paths now are relative to the file that is being included.

- Changed the name of sourcepath$ to path$.
- Changed the name of the word SOURCEPATH to PATH .
- New primitive words CD and CD" to manage the file path.
- New word PWD in the extend file.
- Deleted the PsiForth word >SOURCEPATH .
- Deleteted the word >SOURCEPATH+ .

- Deleted the words SAVE and LOAD , and all code related to images. All that is useless since the use of the common heap as main memory. I will recode it later in a new way.
- Source files are opened now in text mode, so the procedure loadline$ can be much simpler; the flag close_source_file% and all about filebuffer$ are no longer needed.

- New procedures save_source and restore_source just to make the source recursion.
- The words SAVE-INPUT and RESTORE-INPUT can not be used for source recursion. I misunderstood the Standard. I rewrited them.

- Modified ABORT to close recursively all open source files.
- Fixed recent bug: the text "loading" ws not shown while loading a file.
- Succesful recursion from command line to source file and back.
- Modified the procedure debug to print a message.

- New global array recursive_filebuffer$.
- New global variable ib_opl_addr& ti be used in REFILL .
- Optimized the control chars translation loop in REFILL for greater speed.
- Deleted the useless word CALL (for EPOC 16).
- The procedure debug updated to show the input buffer and source recursion state.

- Start working on recursion for INCLUDE .
- New constant KMaxSourceRecursions%
- New global array recursive_ib$
- New global source_recursion%

- New global variable ib_addr& to store the address of the input buffer.
- Optimized the procedures parse$ and word$ for speed: no calculations inside the loop; the return string is caculated with the mid$ OPL function instead of the pack$ procedure.
- The procedure pack$ is no longer needed.

- Fixed a recent bug in REFILL : it made the program crash at the end of an included file.
- Fixed the new versions of the word$ and parse$ procedures. They use >IN instead of changing ib$.
- Changed the procedure report_error to be compatible with the use of >IN .
- New procedure close_source_file.
- Changed the word ABORT and the procedure loadline$ to use close_source_file
- Bug fixed: the source file was closed before the execution of its last line. If something was left in the stack, RESTORE-INPUT crashed the program.
  The solution is not to close the file in loadline$ but to set a flag for REFILL to close it.
  It slows down a bit because of the flag comparation in the interpreting loop.
- New global variable close_source_file% to close the included file after its last line.
- Because of the experimental use of SAVE-INPUT and RESTORE-INPUT , no source file should change the stack!

- Written first versions of SAVE-INPUT and RESTORE-INPUT .
- New primitive word INCLUDE-FILE .
- Modified the OPL procedure loadline$ to use RESTORE-INPUT .
- Changed DEBUG to print the stack content.

- Unsuccesful tests with new versions of word$ and parse$ procedures that use >IN instead of changing the lenght or tib$.

- New OPL global variable ib$ for the input buffer.

- New primitive ANS word INCLUDED .
- New OPL procedure variable_integer&.
- Changed the OPL global xstate& to xstate%. It should be a bit faster.

- New ANS words [IF] [ELSE] and [THEN] in the extend file.

- Changed sourceid& to sourceid% for more speed.
- Optimized the procedure loadline$ with integer parameters.
- New primitive words LOWER and UPPER . One of them is needed for the new words [IF] and [ELSE] , not finished yet.

- Optimized the word -TRAILING for more speed.

- New OPL procedure parse$.
- Changed the words S" .( (  and \ to use parse$ instead of word$.
  The change in S" solved the problem about null strings.
- New ANS word PARSE .
- Optimized the OPL procedures word$ and parse$ with integer variables.

- New OPL global variable toin& for the Forth variable >IN .
- New ANS word >IN .
- New OPL global variable sourceid& for the Forth word SOURCE-ID .
- New ANS word SOURCE-ID .
- Deleted the constant LOADING that returned the address of loading&.
- Deleted the OPL global variable loading&. The new sourceid& will do the work of loading& and more.
- New OPL global variable i%.
- The word QUERY is now a bit faster, with i% and KKeySpace% instead of i& and KKeySpace&.
- Renamed the word QUERY to REFILL , with changes to make it ANS compatible.
- New OPL global variable xdrop& for the xt of DROP , now needed in the high level definition of QUIT .
- Deleted the useless final EXIT in the PsiForth definition of QUIT .
- PsiForth bug fixed: the procedure variable& was unused and all variables were created by the procedure constant&.
- New OPL procedure build_variables.
- The word >IN is now created by the OPL procedure build_variables.
- Renamed the OPL variables docol&, dovar& and doconst& to docolon&, dovariable& and doconstant& for clarity. Also the related names and labels.

- Renamed the OPL array prec% to control_bits% for clarity.
- Renamed the OPL parameters header$ and imm% to _name$ and _control_bits% for clarity.
- Renamed the OPL parameter name$ to _name$ for clarity.
- New OPL global variable nfa& for clarity in some procedures.
- Renamed the OPL variable last& to last_nfa& for clarity.
- The word <= is a primitive word now. The high level definition was: 1+ < .
- The word >= is a primitive word now. The high level definition was: 1- > .
- Deleted the useless PsiForth constant BYTE .
- Memory space increased from 64 Kb to 128 Kb to make a compilation speed test.
- The OPL procedure find& is now a bit faster than the PsiForth original. Some calculations taken off from the loop and made only once at the start.
- New ANS word RECURSE in the extend file.

- Changed the definition of 2! in the extend file. Now it is faster.
  It was: DUP ROT SWAP ! CELL+ !
  Now it is (from DPANS94): SWAP OVER ! CELL+ !
- Changed the definition of 2@ in the extend file. Now it is faster.
  It was: DUP @ SWAP CELL+ @ SWAP
  Now it is (from DPANS94): DUP CELL+ @ SWAP @
- New word POSTPONE in the extend file. It is based on COMPILE and [COMPILE] , which are keeped.
- The OPL array cfa&() is renamed to xt&() for clarity.
- Changed the primitive word WORD to make it ANS compatible.
- Changed the primitive word FIND to make it ANS compatible.
- Changed the word ' in the extend file because of the changes in WORD and FIND .
- Changed the words [CHAR] and CONTROL in the extend file because of the changes in WORD .
- New OPL procedure counted_string$, similar to string$.
- Renamed the primitive words BYTE+ and BYTE- to CHAR+ and CHAR- for ANS compatibility.
- The word CHARS is now a primitive. It has to be a nop in this system.
- The word COMPILE, is now a primitive, and it has a compile only control.
- New words [DEFINED] and [UNDEFINED] in the extend file.
- Fixed PsiForth bug: the primitive word LEAVE now can be used only in compilation mode.
- Renamed the primitive words ?COMP and ?EXEC to ?COMPILING and ?EXECUTING for clarity.

- New ANS word COMPILE, in the extend file, now used by [COMPILE] instead of , .

- Deleted the word DEL in the extend file. There's no need for it.

- The word ALLOCATE now returns an ior for ANS compatibility.
- The word REALLOC is renamed to RESIZE and now returns an ior for ANS compatibility.
- The word FREEALLOC is renamed to FREE and now returns an ior for ANS compatibility.

- Renamed the PsiForth primitive word >INDICATOR to BUSY for "OPL compatibility".
- Changed the parameter order of the word SCREEN to be the same as in OPL.
- Found PsiForth bug: the word SCREENINFO doesn't work. It should be rewritten. I make it noop.
- Renamed the PsiForth primitive words RP@ and SP@ to RP and SP .
- The words INVERT 2+ and 2- are primitives now.
- Renamed the OPL vector labels xonep and xonem to x1plus and x1minus for clarity.
- Renamed the word ALLOC to ALLOCATE for ANS compatibility.

- Changed the primitive word GCIRCLE to use the fill flag, like the OPL instruccion.
- Deleted the primitive word GFILLEDCIRCLE , now useless.
- Changed the primitive word GELLIPSE to use the fill flag, like the OPL instruccion.
- Deleted the primitive word GFILLEDELLIPSE , now useless.
- Renamed the OPL label xother:: to xtasks::

- Renamed the word AT to AT-XY for ANS compatibility.
- Renamed the OPL vector labels used for the words <# # #S #> [ and ] with the ANS names of the words.
- Deleted the nop primitive words EDIT and LIST reserved in PsiForth.
- Deleted unused PsiForth code for the primitive word DP because it's already a constant,
  and deleted the constant DP itself because it's useless: HERE gives the content of the address DP gives.

- New ANS word S>D in the extend file.
- Fixed REPOSITION-FILE FILE-POSITION and FILE-SIZE to use double precision parameteres
  for ANS compatibiity, though they are dummy.
- Changed KThreads% back to 128 from 64.
- The primitive word ?DUP is made independent from DUP to avoid PsiForth spaghetti code.

- New primitive words DATE>SECS and SECS>DATE for the OPL equivalents.
- New OPL global variables temp0% ... temp6%.
- New OPL constants K3Cells& ... K5Cells&.
- Changed KThreads% from 128 to 64. The program valsycukta loads in 26 seconds instead of  29.
- New word -SECONDS in the extend file, to make speed tests easy.
- The PsiForth primitive word FREE is renamed to the ANS stantard UNUSED .
- Fixed PsiForth bug in the word .R : it printed a trailing space.
- Start of REMarking every primitive word with their name, ANS wordset and stack effect.

- New primitive word: MKDIR .

- Fixed silly bug of mine: line feed code is not 11 but 10.
  That's why READ-LINE didn't work.
- New versions of WRITE-LINE and READ-LINE already tested.

- Problem found: when files are opened in text mode, the OPL command iowrite
  always writes a line terminator, what makes imposible the Forth word WRITE-FILE to work.
  In fact, that's why WRITE-LINE and WRITE-FILE were synonyms until now.
  The solution is to open all files in binary mode
  and rewrite READ-LINE and WRITE-LINE to care about line terminators.
- New OPL constant KKeyLineFeed&.
- New OPL variable line_terminator$.
- Changes in R/O R/W W/O to open all files in binary mode.
- BIN changed to do nothing.
- New versions of WRITE-LINE and READ-LINE not tested yet.

- Fixed a bug of mine in 2R@ : it took one cell wrong.
- Fixed PsiForth bug:
  the OPL procedure word$ didn't skip initial delimiters but spaces,
  what made imposible to create one space strings with s"  " .
  Nevertheless, now it's impossible to create empty strings with s" " .
  I should fix that.
- Fixed bug of mine in READ-LINE : the flag was inverted.

- New ANS word /STRING in the extend file.
- New high level version of SEARCH (taken from gforth)
  to avoid the OPL 255 chars limit.
- New string words in the extend file, taken from gforth:
- New ANS primitive word 2R@ .
- New OPL global variable temp2&.
- New version of the primitive word COMPARE
  without strings, to avoid the OPL 255 chars limit.

- Fixed PsiForth bug: DUMP left one parameter on the stack.
- New version of -TRAILING
  without strings, to avoid the OPL 255 chars limit.
- New version of TYPE
  without strings, to avoid the OPL 255 chars limit.

- New ANS words 2VARIABLE 2! and 2@ in the extend file.

- Used the OPL heap for mem& instead of an array.
  That way, the 65516 bytes procedure limit is far, and there's room for more words.
- The memory is set to 65536 bytes instead of the original 12000,
  and the maximum number of words is 1024 instead of 525.
- New primitive word >SOURCEPATH+ for easy testing of my program eeo.fth.
- New ANS word ?DO in the extend file.

- Fixed bug of mine in the word SEARCH :
  it returned the lenght of the found string, not that of the remainder string.

- The limit of 510 headers is not enough for me,
  so I change it to 525, the maximum possible without error:
  OPL error -92 because of the 65516 bytes limit for data procedure.
  I think it would be better to use the OPL heap than an array.

- New words in the extend file: 2+ and 2- .
  They better should be primitives, though.
- Fixed PsiForth bug in 2OVER : it worked like 2DUP .

- New ANS primitive word RENAME-FILE .
  However, its return parameter ior is not yet calculated.
- Fixed silly bug of mine:
  of course, 2>R and 2R> didn't work in high level form!
  They are primitives now.
- New ANS word ABORT" in the extend file.

- OPL variable uid1& renamed to uid&.
  It holds the unique Psion app ID, and marks the first memory address of the system, for saving and loading.
- Fixed PsiForth bug in FILE-SEEK :
  it kept the fileid on the stack.
- New ANS word REPOSITION-FILE in the extend file.
- New ANS word FILE-POSITION in the extend file.
- New word REWIND-FILE in the extend file for the OPL equivalent.
- New ANS word FILE-SIZE in the extend file.
- Changed the order of parameters in FILE-SEEK to a more usual way.
- Changed READ-FILE for ANS compatibility.
- New ANS primitive word WRITE-LINE , now just a synonym of WRITE-FILE.
- New ANS primitive word READ-LINE .

- Created OPL ioopen constants with build_constants&.
- Created ANS Forth constants W/O R/O and R/W in the extend file.
- Fixed PsiForth bug in OPEN-FILE :
  The OPL variable temp& was used, but then changed by the procedure packed$.
  Created new OPL global fam% to prevent that.
- New ANS primitive word: CREATE-FILE .
- Changed READ-FILE for ANS compatibility.
- New ANS word INVERT in the extend file, but not perfect, it must be fixed.
- New ANS word BIN in the extend file, to change file access methods.
- New ANS word REPOSITION-FILE in the extend file, not finished.
- New ANS word FILE-POSITION in the extend file, not finished.

- The words ( and \ are primitives now.
- The definitions in the ans.fth file move to the extend file.
- New application icon.
- The word .( is a primitive word now.
- The primitive word FROM is renamed to INCLUDE for ANS compatibility.
- The primitive word DELETE is renamed to DELETE-FILE for ANS compatibility.
- OPL labels of file words renamed to their real names for easy reading.
- The word OPEN-FILE now is simpler and faster than the PsiForth one:
  it doesn't use the return stack any more.
- Deleted unused OPL global variables uid2& and uid3&.

- The primitive word ASCII is renamed to [CHAR] for ANS compatibility.
- The primitive word " is renamed to S" for ANS compatibility.
- New ANS primitive word: ROLL .
- The word NOT is now identical to 0= for ANS compatibility.
- New ANS primitive word: -TRAILING .
- New OPL global variables: temp1$,temp2$,a1&,u1&,a2&,u2&.
- New ANS primitive word: SEARCH .
- New ANS primitive word: COMPARE .
- The high level word ENDIF is renamed to THEN for ANS compatibility.
- Key code OPL long integer constants are renamed to the OPL intenger equivalents.

- Fixed bug of mine about case sensitive controls.
- New high level words in ans.fth:
  ." [CHAR] <= >= BLANK OFF ON 2>R 2R>
- First changes to make a command history system.
- New global CurrentHistory%

- Words are not case sensitive any more.
- Words can have any character up to 255, not just ASCII.
- Proc lineedit$:() modified to accept all chars up to 255.
- Fixed PsiForth bug: the error message in interpret_only was wrong.
- New word S" for ANS compatibility: it is just another name for " .
- New source file for ANS compatibility: ans.fth.
- First new ANS word in ans.fth: .( .

History of PsiForth, by its unknown author.
PsiForth was the origin of Forth 5mx.

Copyright © 1999 by Integrated Services
Arnhem, The Netherlands

v0.225 27feb2000,01mar2000
        load image if specified on command line,
        otherwise tries to load image named full.
        improved cold start randomizer
v0.224 20feb2000
        ctrl-e during query terminates PsiForth
        increased #headers. Found a maximum ..
v0.223 18feb2000
        adding PsiForth.mbm icon
        keytable. tested for in lineedit, but not used yet
        backlight, backlight?  silk key 2 toggles. ctrl-l
        illegal key beeps
        fixed non-decimal number input
        not truncating keys > 8 bit.
v0.222 16feb2000
        align aligned (fixed proc aligned:)
        proc header: aligns dp
v0.222 13feb2000
        . and .r respect base, added temp1&
        PsiForth instead Forth32
        number input respects base too.
v0.221 12feb2000
        0 0 at  for upper left