# Notebook Database File

#--------------------------------------------------
# Adding a Primitive

page {Adding a Primitive} {Primitives are defined using the <m>code</m>, <m>mcode</m>, and <m>next</m> macros.
Since we use subroutine threaded code, everything is raw assembly. Here's
an example:

 code 'my_first_word', my_first_word
  upsh 1
  upsh 1
  call plus
 next

This defines a new word (<m>my_first_word</m>) which adds 1 + 1. Any
primitive can be defined using these two macros. If you need
functionality defined in Forth rather than assembly, use the <m>embed</m>
macro:

 code 'swap.swap', swap_print_swap
  embed 'swap . swap'
 next

If you need a word to execute at compile time rather than be called
during execution, use <m>mcode</m> rather than <m>code</m>

 mcode 'ret', f_ret
  inline 0xC3           ; Compile a RET into the current definition
 next

Whenever possible define words in Forth rather than assembly. It makes
finding and fixing bugs much easier for those of us working on the official core.

The preferred file placements are: all assembly code in <b>forth.f</b>,
all Forth code in <b>forth.f</b>, all compile-time words in
<b>forth-ic.asm</b>. Make sure your changes don't break existing words
before submitting code to those working on the official core.} 1078948965


#--------------------------------------------------
# block-editor.f

page block-editor.f { ( RetroForth Core Block Editor )
 ( --------------------------------------------------------- )
 ( This version uses traditional 1k blocks as opposed to the )
 ( 512 byte blocks used in earlier releases. The native      ) 
 ( version will eventually use this format as well. )

 0 variable lastBlock
 pad 1024 + constant blockBase
 : block 1024 * blockBase + ;
 : select dup lastBlock ! ;

 : vl 32 emit 32 emit dup 64 type cr 64 + ;
 : dashes times '- emit repeat dashes ;
 : ed.hline '( emit 32 emit 64 dashes 32 emit ') emit cr ;

 : view clear
        ed.hline
        lastBlock @ block
        vl vl vl vl vl vl vl vl vl vl vl vl vl vl vl vl 
        ed.hline lastBlock @ . cr
 ;
 : edit 64 * lastBlock @ block + s drop drop view ;
 : delete 64 * lastBlock @ block + 61 0 fill view ;} 1078956410


#--------------------------------------------------
# Contributors

page Contributors {Many people have contributed to RetroForth's development. I'm sure this
list is incomplete, but it lists all contributors I'm currently aware of.

<b>Tom Novelli</b>

<i>We are indebeted to Tom for creating RetroForth, maintaing and developing
it from 1998 to 2002 and for his countless contributions to the RETRO5
and RETRO6 codebases.</i>

<i>Tom also helped to write IsForth, another very nice Forth system (with
more standard functionality). IsForth only works under Linux right now,
but if you need more power than RetroForth has, be sure to check it out.</i>

<b>Charles Childers</b>

<i>I have developed and maintained RetroForth since 2002. I am
responsible for nearly everything in RETRO5, the RETRO-NG prototype that
became RetroForth 6, and most of the contents of the <b>forth.f</b> file.
Many of the primitives in RetroForth 6, including loops, if/then, and so
on were also coded by me.</i>

<i>I run two websites, a primary one (http://www.retroforth.org) and the
older one (http://retro.tunes.org). The second site is devoted to the
[native] port.</i>

<i>These days I also maintain all of the official ports ([linux], [dos],
[windows], and [native]). I am also the primary author of this manual.</i>

<b>Ron Aaron</b>

<i>Ron ported RetroForth/[Linux] to [FASM], and then to [Windows]. His changes
were merged (with a few modifications) into the official codebase
resulting in Release 6.20. Because of his work, future ports should be
much easier.</i>

<b>Torkjel</b>

<i>We don't know much about Torkjel. He wrote the [linux]-sdl port. I'd
like to extend my thanks to him for his work on RetroForth.</i>

<b>ASau</b>

<i>Made some suggestions resulting in a far better version of [html.f]</i>} 1080007801


#--------------------------------------------------
# Customizing the Kernel

page {Customizing the Kernel} {The RetroForth Core consists of three files (forth-ic.asm, forth.asm, &
forth.f). These are designed to be common to all ports; can be assembled
with either [NASM] or [FASM]; and are generally the most worked on part of
the entire project. If you intend to customize RetroForth at all, you
will want to study the following pages.

* [Threading Model]
* [Dictionary Structure]
* [Adding a Primitive]
* [The Macros]
* [Registers]
* [Tweaking the Makefile]

You can drop in your customized [Forth core] into any recent (6.20 and
higher) release of RetroForth and it <i>should</i> work without problems.
This assumes that you don't change the entire implementation or core
registers. Otherwise you can just copy over your Forth core to take
advantage of the latest drivers and ports.

A helpful set of books on assembly language can be ordered for free from
Intel here: http://developer.intel.com/design/pentium4/manuals/index2.htm} 1079202995


#--------------------------------------------------
# Design Philosophy

page {Design Philosophy} {                            Design Philosophy
                          of RETRO Native Forth

     Computer software is a technology in its infancy, a mere fifty years
old.  The last 25 years in particular have seen an explosion in the
software business.  However, software has seen little innovation while
hardware technology has improved phenomenally (notwithstanding the advent
of lousy slave-made parts).  Proven software techniques of forty years ago
have yet to reach widespread use, in deference to the "latest and
greatest"  proprietary solutions of dubious value.  Thanks to agressive
marketing, we make huge investments in these dead-end technologies
(through our businesses and governments, if not personally) and we end up
with a reliance on a heap of complicated, error-prone, poorly understood
junk software.

     Complexity will dominate the software industry for the foreseeable
future.  The Retro philosophy is a simple alternative for those willing to
make a clean break with legacy software.  A Retro system can communicate
with other systems, but it won't run much legacy software, especially
proprietary software without source code.  An emulation layer could be
added, but doing so would defeat the purpose of a simple operating system.
I think TCP/IP support is all the compatibility that's needed.

     At first Retro will appeal to computer hobbyists and electronic
engineers.  Once the rough edges are smoothed out, it could catch on with
ordinary folks who don't like waiting five minutes just to check their
email (not to mention the long hours of setup and maintenance).  Game
programmers who take their craft seriously may also be interested.
Businesses might even see a use for it, if the managers decide it's more
cost-effective to carefully design software for specific needs, rather
than buying off-the-shelf crap and spending countless manhours working
around the bugs.  Since it's not practical for businesses to make a clean
break, my advice is to run Retro (and its ilk) on separate machines
connected by a network.  Retro is efficient enough to run on older
machines that would otherwise sit idle, being too slow for the latest
Microsoft bloatware (or Linux, for that matter).

     I strive to avoid the extraneous.  That applies even to proven
technologies, if I don't need them.  If my computer isn't set up for
people to log in over the network, I don't want security features; they
just get in the way.  If I'm only running programs I wrote, I should be
able to run them with full access to the hardware; I don't need protection
from viruses.  If I download something I don't trust, then I can run it in
an isolated process, which is customary with Unix and kin.  But that's not
core functionality.  All that's needed is the flexibility to add things
like security, graphical interfaces, and distributed processing - if the
need ever arises.

     In programming languagues, I was misled.  It's the Tower of Babel all
over again.  The thousands of languages in existence all fall into a
handful of archetypes: Assembler, LISP, FORTRAN and FORTH represent the
earliest descendants of nearly all languages.  I hesitate to name a
definitive "object-oriented" language, and here's why: Object-Oriented
programming is just a technique, and any language will suffice, even
Assembler.  The complexites of fancy languages like Ada and C++ are a
departure from reality -- the reality of the actual physical machine. 
When it all boils down, even LISP, FORTRAN and FORTH are only extensions
of the machine. 

     I chose FORTH as the "native tongue" of Retro.  LISP, FORTRAN, and
other languages can be efficiently implemented as extensions of FORTH, but
the reverse isn't so efficient.  Theoretically all languages are
equivalent, but when design time, compilation time, and complexity are
accounted for, FORTH is most efficient.  FORTH also translates most
directly to the hardware.  (In fact, FORTH has been implemented in
hardware; these "stack machines" are extremely efficient.)  FORTH is also
the easiest language to implement from scratch - a major concern when
you're trying to make a clean break.  So with simplicity in mind, FORTH
was the obvious choice. 

    I'm perfectly happy working with text only, and I go to great lengths
to avoid using the standard graphical environments, which have major
problems: windows, pulldown menus, and mice.  Windows can't share the
screen nicely; that idea is hopeless.  Pulldowns are tedious.  Mice get in
the way of typing without reducing the need for it; all they give me is
tendonitis.  Their main use is for drawing. 

    Some of my favorite interfaces: Telix, Telegard BBS, Pine, Pico, Lynx,
and ScreamTracker.  All "hotkey" interfaces where you press a key or two
to perform an action.  Usually the important commands are listed at the
bottom of the screen, or at least on a help screen.  The same principles
apply to graphical interfaces: use the full screen, except for a status
and menu area on one edge.  Resist the temptation to clutter up the
screen. 

    As for switching between programs, the Windows methods suck; the only
thing worse is Unix job control (jobs, fg, and such).  The Linux method is
tolerable: Alt-Arrows, Alt-F1, Alt-F2, etc.  Still, things could be
better: F11 and F12 cycle back and forth through all open programs; Alt-F1
assigns the currently selected program to F1, and likewise for the other
function keys.  Programs just won't use function keys - Control and Alt
combinations are less awkward and easier to remember, besides.  I'll also
want a "last channel" key and a "task list" key; maybe I'll borrow those
stupid Win95 keys.  The Pause key will do like it says - pause the current
program - and Ctrl-Pause (Break) will kill it.

    One more thing: consistency.  I like programs to look different so I
can tell them apart, but the keys should be the same as much as possible. 
Keys should be configured in one place, for all programs.  Finally,
remember the most consistent interface, one of the few constants
throughout the history of computing - the text screen and keyboard, and
the teletypewriter before that.  Don't overlook it.


    More to come, maybe... :)
    "If it's on line, it's a work in progress."

    Tom Novelli
    3/4/2000} 1078633313


#--------------------------------------------------
# Development Logs

page {Development Logs} {Back when I (Charles Childers) took over development, I wrote a series of
detailed, daily logs to show my progress. Since I released RetroForth
6.01, these have ceased to be written, but the old ones are still useful
for insight into my learning curve and problematic areas of the codebase.} 1079202189


#--------------------------------------------------
# Dictionaries

page Dictionaries {Starting in Release 6.24, RetroForth has three dictionaries (which we
also call vocabularies) which can be used to store words.

* macros
* forth
* domain

The <m>macro</m> vocabulary is used to store special functions for the
compiler. Any word defined in it is executed <i>at compile time</i>.
These words can not be invoked from the interpreter.

The <m>forth</m> vocabulary stores all non-macro words in the [forth
core]. It can be added to freely.

Finally, the <m>domain</m> vocabulary is used to store all code written
for a specific application. This keeps the listing of words cleaner and
helps to factor and organize code.

<i>Historical Note: All versions of RetroForth, from Release 4a on have
had the <m>forth</m> and <m>macro</m> vocabularies. Access to switching
them was removed after Charles took over development. They reappeared in
Release 6.23, and the <m>domain</m> vocabulary was added in Release 6.24.</i>} 1080143248


#--------------------------------------------------
# Dictionary Structure

page {Dictionary Structure} {RetroForth has a fairly simple dictionary structure. The <i>code</i> and
<i>mcode</i> macros create the following assembly code for each word:

 c: dd link_to_previous_word
 dd pointer_to_cfa
 db length_of_name
 db "name"
 b: ... assembly code ...
 ret

So <i>code '+', plus</i> becomes:

 c: dd PREVIOUS_WORD
 dd plus
 db 1
 db "+"
 plus: ... assembly code ...

In <b>forth.asm</b> the final dictionary links are resolved.} 1078951871


#--------------------------------------------------
# DOS

page DOS {The DOS port is 100% identical to the [Native] port, but adds a .COM
wrapper to load the kernel and start protected mode. Right now you can't
return to DOS from it, but that should change in the near future.} 1078683302


#--------------------------------------------------
# Early goals

page {Early goals} {This is a transcription of my original outline for what became known as
RETRO.  It dates back to August or September 1998.  I planned on having
everything but the virtual machine done by 1999.  Yeah right :)  It's
March 2000 and I haven't done half the stuff on this list.  The goals
haven't changed much, though... I set aside a few things: encryption,
security, parallel processing, and the *-windows inspired GUI.


 Forth-based OS
 --------------
 Startup - read kernel, protected mode
 Forth interpreter
  Load block file w/ basic words
  Assembler

			Important traits
			----------------
			Fast
			Simple/efficient
			Integrated encryption
			Secure from viruses & intrusion
			Ease of use (once learned)
			Shared memory
			"Fresh start" - no old baggage

 Projects
 --------
 1.  Boot loader
 2.  Startup code (get BIOS info, enter protected mode, etc...)
 3.  I/O (direct screen writes + keyboard input + disk block I/O)
 4.  Basic Forth system (a few core words + disk blocks)
 5.  Simple assembler to create primitive words (only a few asm instructions)
 + Cleanup, p-mode, block editor, metacompiler
 --- Now development can be done within the new OS
 6.  Flest out Forth
 7.  Filesystem (using Forth block routines)(?)  Add hard disk support now?
 8.  Write basic system utilities - file/text handling
 9.  Multi-tasking / Multiuser / multithreading / Parallel (F*F)
 --- Now it's usable
 10. Write applications (editor, communications...)
 11. GUI (or whatever) - must be easy (and still powerful)
 12. Other languages (like C) - Forth-style
 13. Highly accurate 386+ virtual machine (capable of running Linux & Win.NT)
     (running partly in kernel for efficiency)  + other emulators - 68k, etc.
 14. Networking (TCP/IP, PPP, etc...) + browser, email, telnet, FTP, etc.
 15. CAD
 16. Internationalization - fonts for other languages, ex.: Chinese,
     Nagari, Arabic, Hebrew.  Translate Forth words.

 GUI
 ---
 Full keyboard control (mouse is mainly for drawing, ie, CAD & Paint)
 Configurable keys
 Efficient window-switching (F-keys, not Alt-Tab)
 Keys for full-screen/window/iconify
 Switching etween graphics & textmode & resolution/color depth
 Ability to run console programs in a window
    (by rasterizing fonts instead of the video card doing it)
 Focus sharing? (keyboard control of multiple windows at once)

 Building it
 -----------
 Enter/exit graphics mode, horiz/vert lines
 Fonts/textwin-graphics, console terminal (memory-mapped), TTY terminal
 Dialog management routines
#---
So where is RetroForth/[Native] today? Well, other than the metacompiler
is's now at step 8 (writing basic system utilities). A project called FXK
may result in an exokernel based on RetroForth in the future; if so it
should fulfill more of these goals.} 1079302798


#--------------------------------------------------
# FASM

page FASM {FASM is the Flat Assembler. It has some advantages over [NASM], and other
than a few directives and macro facilities is nearly identical in syntax.
FASM is written in assembly language, and runs on DOS, Linux, and
Windows. We use FASM primarily for the RetroForth/[Windows] port, but a
RetroForth/[Linux] port is also included.

More details are at: <m>http://www.flatassembler.net</m>

If you want the FASM documentation in Notebook format, you can download
it from <m>http://download.retroforth.org/fasm_manual.nbk</m>} 1079297824


#--------------------------------------------------
# Forth core

page {Forth core} {The Forth Core is the heart of the RetroForth system. It consists of
three files, and an assembler-specific macro file. Currently the Forth
core can be assembled using [NASM] or [FASM]. It does require a few
external definitions to be useful. You can also view a [list of words].

 Filename           Inside
 -------------------------------------------
 forth-ic.asm       Interpreter and Compiler
 forth.asm          Core primitives
 forth.f            High-level extensions
 -------------------------------------------


 External Symbols Needed
 -----------------------------------
 key   | Generally these are defined
 emit  | in drivers.asm
 cr    |
 -----------------------------------} 1078859506


#--------------------------------------------------
# Getting Started

page {Getting Started} {To get started you need to download the source, decompress it, and then
compile it. The build system is heavily geared towards [Linux], so expect
problems if you try to build it under [Windows] or [DOS].

Replace MINOR with the minor version number (currently 22)

 wget http://download.retroforth.org/retroforth-6.MINOR.tar.gz
 tar xzvf retroforth-6.MINOR.tar.gz
 cd retroforth
 make

At this point you can run any of the resulting binaries:

 ports/linux-console/rf
 ports/linux-svga/rf
 ports/linux-sdl/rf
 ports/nasm-linux-console/rf
 ports/windows-console/rf.exe

Any errors will be saved into a file named ERRORLOG; compilation will
continue.

The following table lists all of the external dependencies required to
build RetroForth.

 Tool       URL                         Version
 ----------------------------------------------
 libSDL     http://www.libsdl.org       1.2.6
 SVGALIB    http://www.svgalibl.org     1.4.3
 NASM       http://nasm.sf.net          0.98.38
 FASM       http://flatassembler.net    1.50
 TCC        http://www.tinycc.org       0.90.20

Please be aware that you can build a minimal, non-graphical version with
nothing but [NASM] or [FASM]. You can also use GCC instead of TCC if you prefer.} 1078859189


#--------------------------------------------------
# History

page History {RetroForth was created in 1998. The original idea was to provide a
complete operating system written in assembly and Forth. Tom Novelli was
the original author and developed RetroForth until 2001. A document
detailing Tom's [Early
goals] is still around today.

The first version of RetroForth was simply called <i>RETRO</i>. Tom had just discovered Forth and quickly wrote a simple compiler/OS. Along the way he learned assembly language. That first version was a crude 16-bit model that used the BIOS for I/O. He quickly went on to rewrite it.

The second version of <i>RETRO/ForthOS</i> (as it was now called) was retired in September 1999. It was sloppy, buggy, and full of bells & whistles. After a lot of development, he took many of its useful parts and moved on to the next major rewrite.

This new <i>RETRO</i> was intended to be a simple Forth-OS capable of recompiling itself. It was initially written in gforth and featured a decent assembler and metacompiler. Retro3 was never completed. Tom read Starting Forth by Leo Brodie and realized that it would need some major redesign. In November 2000, Retro3 was aborted and Tom spent some time working on IsForth.

In 2001, Tom released his final versions of <i>RETRO</i>. The fourth generation had a clean, ColorForth inspired design, could start from DOS or a floppy, and had 8-bit VGA (320x200) graphics. Two versions (4a & 4b) were released; a third version was made but never released.

After a prolonged period of silence in the development of RetroForth, Charles Childers decided to release his customized version of Retro4 to the world. This was the result of a merger between the 4a and 4b codebases and had a few new functions from previous versions of RETRO in it. This release was made available on December 6, 2002, after six months of study and delving into <i>RETRO</i>'s inner workings.

After a short time, Charles varient became hosted on SourceForge. That didn't last long. At Tom's suggestion, he moved the development site to bespin.org. During the first few months of 2003, the entire content of the SF.net account was moved over to the new site.

During January 2003 Charles released the first version of <i>RETRO5</i>. It was a continuation of his work on <i>RETRO4</i>, but boasted a fairly usable set of drivers and applications. There was a persistent data storage system, block editor, debugger, and a few other small tools.

After a few months, he decided to start fresh, using what he'd learned
from his work on <i>RETRO4</i> and <i>RETRO5</i>. The new <i>RETRO-NG</i>
codebase was smaller, simpler, and generally worked better. This
experimental codebase became the foundation for <i>RETRO6</i>.

The first public release of <i>RETRO6</i> was given the version number
6.01. It still ran only as an OS, but Tom soon ported release 6.01 to
[Linux], and his changes were merged into the official codebase with
release 6.04. Charles then adapted the graphics drivers for use with
SVGALIB. This was then improved on when Torkjel adapted it for use with
libSDL and X11. Development continued, with a few month long breaks until
January 2004.

In January 2004, Ron Aaron began a port of RetroForth to [FASM]. Prior to
this all versions used [NASM]. This undertaking resulted in a much improved assembly/forth core, and a [Windows] port. Charles merged Ron's improvements into the RetroForth 6 codebase and on January 31, 2004 release 6.20, the first stable release, was finished.

We are currently at release 6.22 and work on release 6.23 is underway. We
now offer full support for [Windows], [Linux], [DOS], and Standalone ([Native]) use with a
stable Forth core, and some optional extensions. Some projects on the
horizion include support for use as a [C scripting] language, integrating a
LISP interpreter, and some early work on using RetroForth for [CGI].} 1078957526


#--------------------------------------------------
# Home

page Home {Hello, and welcome to RetroForth! This manual will take you through the
basics of setting up RetroForth, writing simple programs, customizing the
[Forth core], and porting to new operating systems. You'll also find a
detailed history, old developer's logs, philosophical documents, and much,
much more. So, without extending this brief introduction further, here's
the table of contents:

* [Home]
* [Getting Started]
* [RetroForth Tutorial]
** [List of Words]
** [Dictionaries]
* [Sample Code]
** [html.f]
** [block-editor.f]
** [math.f]
** [RetroForth:Wiki]
** [RetroForth:Compiler]
** [RetroForth:Interpreter]
* [Customizing the Kernel]
** [Threading Model]
** [Dictionary Structure]
** [Adding a Primitive]
** [The Macros]
** [Registers]
** [Tweaking the Makefile]
* [Porting RetroForth]
** [Linux]
** [Windows]
** [Native]
** [DOS]
* [History]
** [Design Philosophy]
** [Early Goals]
** [Development Logs]
** [Contributors]

Do you have suggestions for how to improve RetroForth or this manual? If
so, contact us at <m>http://www.retroforth.org</m>.
} 1080903820


#--------------------------------------------------
# html.f

page html.f { ( HTML Generation for RetroForth )
 ( ------------------------------ )

 ( Simplify later definitions )
 : emit-loop times emit repeat emit-loop ;
 : tag '< emit emit-loop '> emit ;
 : /tag '< emit '/ emit emit-loop '> emit ;
 : HREF= '= 'f 'e 'r 'h 5 emit-loop ;
 : ." '" word type ;
 : .` '` word type ;

 ( HTML file sections )
 : HTML: 'l 'm 't 'h 4 tag cr ;
 : ;HTML 'l 'm 't 'h 4 /tag cr ;
 : HEAD: 'd 'a 'e 'h 4 tag cr ;
 : ;HEAD 'd 'a 'e 'h 4 /tag cr ;
 : BODY: 'y 'd 'o 'b 4 tag ;
 : ;BODY 'y 'd 'o 'b 4 /tag ;

 ( Functions for HEAD section )
 : TITLE" '" word 'e 'l 't 'i 't 5 tag type 'e 'l 't 'i 't 5 /tag cr ; 
 : CSS" '" word 32 't 'e 'e 'h 's 'e 'l 'y 't 's '= 'l 'e 'r 32 'k 'n 'i 'l '< 21 emit-loop HREF= type '> emit cr ; 
 : BASE" '" word 32 'e 's 'a 'b '< 11 emit-loop HREF= type '> emit cr ;

 ( Functions for BODY section )
 : P: 'p 1 tag ;
 : ;P 'p 1 /tag cr ;
 : HR 'r 'h 2 tag ;
 : PRE 'e 'r 'p 3 tag type 'e 'r 'p 3 /tag cr ;
 : IMG '= 'c 'r 's 32 'g 'm 'i '< 9 emit-loop type '> emit ;
 : ?ID= '? emit 'i emit 'd emit '= emit ;
 : LINK 2dup '= 'f 'e 'r 'h 32 'a '< 8 emit-loop ?ID= type '> emit type 'a 1 /tag ;
 : [ '] word LINK ;
 : BR 'r 'b 2 tag ;

 : I" '" word 'i 1 tag type 'i 1 /tag ;
 : B" '" word 'b 1 tag type 'b 1 /tag ;
 : U" '" word 'u 1 tag type 'u 1 /tag ;
 : ." '" word type  ;
 : H1" '" word '1 'h 2 tag type '1 'h 2 /tag ;
 : H2" '" word '2 'h 2 tag type '2 'h 2 /tag ;
 : H3" '" word '3 'h 2 tag type '3 'h 2 /tag ;
 : H4" '" word '4 'h 2 tag type '4 'h 2 /tag ;} 1079718580


#--------------------------------------------------
# Index

page Index {[@pageIndex@]} 1026586734


#--------------------------------------------------
# Linux

page Linux {The Linux ports were the first to be made from the original codebase. As
noted in the [history], Tom completed a port of RetroForth 6.01 to Linux
not long after development of the <i>RETRO6</i> codebase began.

This initial port is called <i>nasm-linux-console</i> in recent releases.
It brought the first set of major changes by providing a superior set of
dictionary macros, and slight changes to the build system.

Charles then implemented Tom's suggestion to use SVGALIB to provide a
graphical version. This formed the <i>linux-svga</i> port. Not long after
this, Torkjel provided a version using libSDL to implement the graphics.
His work became the basis for <i>linux-sdl</i>.

In January 2004, Ron Aaron began porting RetroForth to [FASM]. His first
working port is called <i>linux-console</i>. He wrote a [Windows] port
soon afterwards.} 1078859546


#--------------------------------------------------
# List of Words

page {List of Words} {This is a mostly complete list of the words defined in the [forth core]
and also those required to run RetroForth.


 Word       Stack Use       Location
 -------------------------------------
 defined    ( x -- y )      forth.f
 >body      ( x -- y )      forth.f
 .(         ( -- )          forth.f
 >type      ( -- )          forth.f
 /string    ( -- )          forth.f
 '          ( -- )          forth.f
 copy$      ( -- )          forth.f
 place      ( -- )          forth.f
 count      ( x -- y )      forth.f
 string:    ( -- )          forth.f
 "          ( -- x y )      forth.f
 pop        ( x -- y )      forth.f
 push       ( x y -- )      forth.f
 stack:     ( -- )          forth.f
 array      ( -- )          forth.f
 --         ( x -- )        forth.f
 ++         ( x -- )        forth.f
 +!         ( -- )          forth.f
 on         ( x -- )        forth.f
 off        ( x -- )        forth.f
 ?negate    ( x -- x )      forth.f
 ?dup       ( x -- x x )    forth.f
 >          ( x y -- z )    forth.f
 <>         ( x y -- z )    forth.f
 <          ( x y -- z )    forth.f
 =          ( x y -- z )    forth.f
 */mod      ( -- )          forth.f
 */         ( -- )          forth.f
 /mod       ( -- )          forth.f
 neg        ( -- )          forth.f
 2drop      ( -- )          forth.f
 2dup       ( -- )          forth.f
 tuck       ( -- )          forth.f
 nip        ( -- )          forth.f
 -rot       ( -- )          forth.f
 pick       ( -- )          forth.f
 over       ( -- )          forth.f
 drop       ( x -- )        forth.f
 dup        ( x -- x x )    forth.f
 chars      ( x -- )        forth.f
 char+      ( -- )          forth.f
 cells      ( x -- )        forth.f
 cell+      ( -- )          forth.f
 allot      ( x -- )        forth.f
 align      ( -- )          forth.f
 pad        ( -- x )        forth.f
 3,         ( x -- )        forth.f
 2,         ( x -- )        forth.f
 1,         ( x -- )        forth.f
 ,          ( x -- )        forth.f
 min        ( x y -- z )    forth.f
 max        ( x y -- z )    forth.f
 and        ( -- )          forth.f
 fill       ( -- )          forth.f
 abs        ( x -- |x| )    forth.f
 mod        ( x y -- z )    forth.f
 not        ( x -- y )      forth.f
 rot        ( x y z -- )    forth.f
 swap       ( x y -- y x )  forth.f
 ;code      ( -- )          forth.f
 c,         ( x -- )        forth.f
 :code      ( -- )          forth.f
 codeX      ( -- )          forth.f
 here       ( -- x )        forth.f
 binary     ( -- )          forth.f
 octal      ( -- )          forth.f
 decimal    ( -- )          forth.f
 hex        ( -- )          forth.f
 char-size  ( -- x )        forth.f
 cell-size  ( -- x )        forth.f
 false      ( -- )          forth.f
 true       ( -- )          forth.f
 variable   ( -- )          forth.f
 constant   ( -- )          forth.f
 (          ( -- )          forth.f
 ---------------------------------------
 reset      ( -- )          forth.asm
 .s         ( -- )          forth.asm
 depth      ( -- )          forth.asm
 or         ( -- )          forth.asm
 >>         ( -- )          forth.asm
 <<         ( -- )          forth.asm
 last       ( -- )          forth.asm
 words      ( -- )          forth.asm
 word       ( -- )          forth.asm
 type       ( -- )          forth.asm
 c@         ( -- )          forth.asm
 c!         ( -- )          forth.asm
 !          ( -- )          forth.asm
 s          ( -- )          forth.asm
 .          ( -- )          forth.asm
 /          ( -- )          forth.asm
 *          ( -- )          forth.asm
 -          ( -- )          forth.asm
 +          ( -- )          forth.asm
 @          ( -- )          forth.asm
 cmove      ( x y z -- )    forth.asm
 execute    ( -- )          forth.asm
 bytes      ( -- )          forth.asm
 sp@        ( -- )          forth.asm
 source     ( -- )          forth.asm
 base       ( -- )          forth.asm
 d          ( -- )          forth.asm
 h          ( -- )          forth.asm
 ---------------------------------------
 :          ( -- )          forth-ic.asm
 ]          ( -- )          forth-ic.asm
 [          ( -- )          forth-ic.asm
 if         ( -- )          forth-ic.asm
 then       ( -- )          forth-ic.asm
 create     ( -- )          forth-ic.asm
 x,         ( -- )          forth-ic.asm
 find       ( -- )          forth-ic.asm
 mfind      ( -- )          forth-ic.asm
 ;;         ( -- )          forth-ic.asm
 ;          ( -- )          forth-ic.asm
 does>      ( -- )          forth-ic.asm
 r@         ( -- )          forth-ic.asm
 r>         ( -- )          forth-ic.asm
 >r         ( -- )          forth-ic.asm
 times      ( -- )          forth-ic.asm
 repeat     ( -- )          forth-ic.asm
 ---------------------------------------
 key        ( -- x )        drivers.asm
 emit       ( x -- )        drivers.asm
 cr         ( -- )          drivers.asm
 bye        ( -- )          drivers.asm} 1080007457


#--------------------------------------------------
# Makefile: All

page {Makefile: All} {When you execute <m>make</m>, this section is called to build all of the
ports. We have it set up for prettier output, separate error logging, and
continuation if errors are encountered.

 all:
 	@echo "RetroForth Release 6.23"
 	@echo "---------------------------------------------------------------"
 	@echo "Setting up common files..."
 	@make -kis setup
 	@echo "FASM Targets"
 	@echo ":: fasm-windows-console" >ERRORLOG
 	@make -kis fasm-windows-console 2>>ERRORLOG
 	@echo ":: fasm-windows-gui" >>ERRORLOG
 	@make -kis fasm-windows-gui 2>>ERRORLOG
 	@echo ":: fasm-linux-console" >>ERRORLOG
 	@make -kis fasm-linux-console 2>>ERRORLOG
 	@echo "NASM Targets"
 	@echo ":: nasm-linux-console" >>ERRORLOG
 	@make -kis nasm-linux-console 2>>ERRORLOG
 	@echo ":: nasm-linux-svga" >>ERRORLOG
 	@make -kis nasm-linux-svga 2>>ERRORLOG
 	@echo ":: nasm-linux-sdl" >>ERRORLOG
 	@make -kis nasm-linux-sdl 2>>ERRORLOG
 	@make -kis clean
 	@echo "Any errors encountered are listed in ERRORLOG"

First it copies the files for the [Forth core] into the directory for
each port,then it builds the [windows] ports, followed by the [linux]
ports. At the end it cleans up.} 1080007723


#--------------------------------------------------
# Makefile: Clean and Dist-clean

page {Makefile: Clean and Dist-clean} {Use <m>make clean</m> to do some general cleanups of temporary files and
the like. It is called automatically after a <m>make all</m>, so you
normally won't need to invoke it. The <m>make dist-clean</m> option does
the same thing but also removes the executable images from the directory tree.} 1079202020


#--------------------------------------------------
# Makefile: Ports

page {Makefile: Ports} {Under the Makefile each port has its own entry. This makes building
specific ports easier.

Here's how it looks:

 nasm-linux-svga:
 	@echo "| linux-svga"
 	@cd ports/linux-svga && $(NASM) retro.asm $(NASM_ARGS)
 	@cd ports/linux-svga && gcc retro.o -lvga -orf
 	@cd ports/linux-svga && chmod u+s rf
 	@cd ports/linux-svga && rm -f retro.o

First is the name of the port. This is followed by a line displaying the
name at build time, so you can visually track the process. Next is the
code to assemble, link, and setup permissions for the port. This process
is repeated for each port in the tree.} 1079201899


#--------------------------------------------------
# Makefile: Variables

page {Makefile: Variables} {Our makefile uses a few variables to help simply things. Below is a table
listing all of them, their initial values, and what they are used for.

 Variable
 ----------------------------------------------------------------------
 NASM           nasm                            Name of NASM executable
 FASM           fasm                            Name of FASM executable
 NASM_ARGS      -felf -oretro.o                 NASM arguments
 SDL            /usr/lib/libSDL-1.2.so.0        Path to libSDL
 CC             gcc                             C compiler to use
 ----------------------------------------------------------------------

You can change the value of <m>CC</m> to another <m>gcc</m> compatible C
compiler if you'd like.} 1078952348


#--------------------------------------------------
# math.f

page math.f { ( defined in forth.f )
 : /mod over over / rot rot mod ;
 : */ * / ;
 : */mod * /mod ;

 ( Obtain greatest common denominator,  x y -- z )
 : gcd dup 0 <> if swap over mod gcd ;; then drop ;} 1079201601


#--------------------------------------------------
# NASM

page NASM {NASM is the NetWide Assembler. Until recently it was the only assembler
that could handle the RetroForth source code. In January, use of [FASM]
became an option, but we still rely heavily on NASM for day to day use.

More information at: <i>http://nasm.sf.net</i>} 1078859135


#--------------------------------------------------
# Native

page Native {From the start of the RetroForth project, we have always had a native,
standalone version of the Forth interpreter. This has been removed from
the core codebase, but can still be downloaded at
<i>http://download.retroforth.org/rf-native.zip</i>. We are working to
match the functionality found in <i>RETRO5</i>. The table below shows
what is and is not implemented thus far.

 Feature                Status
 --------------------------------------------------
 IDE/ATA Read/Write     Alpha
 Persistant Data        Not supported
 Cards block editor     90% finished, needs IDE/ATA
 Menu sytem             Not supported
 DDT for RetroForth     Not supported
 Forth interprter       100%
 --------------------------------------------------

We still have a ways to go before all of this will be supported again,
but those desiring a native RetroForth will have one again before Fall
2004. I may use some example code for a simple OS kernel being worked on
by Tom to help make the new RetroForth/Native more useful.} 1079302189


#--------------------------------------------------
# Porting RetroForth

page {Porting RetroForth} {Ports are a necessary part of RetroForth's development. Ever since Tom
ported RetroForth 6.01 to [Linux], the drive towards a more modular Forth
core and easier ports has taken over. Today it's easier than ever to port
RetroForth to a new platform.

 The steps follow:
  1. Add a new subdirectory for your port
  2. Modify the makefile
  3. Implement retro.asm
  4. Implement drivers.asm and drivers.f
  5. Compile, test, and debug
  6. Share it with us!

In general, you will need to implement your own set of drivers for the
<m>key, emit, cr,</m> and <m>bye</m>. You'll also need to set up the specific
startup code in retro.asm. Overall, if you have a solid understanding of
the OS you're porting too, it should take a month or less to finish a new
port.

We currently have ports to [Linux], [Windows], [DOS], and [Native]
platforms on the x86/pc architecture.} 1079302235


#--------------------------------------------------
# Recent Changes

page {Recent Changes} {[@recentChanges@]} 1026585675


#--------------------------------------------------
# Registers

page Registers {Most registers are free for you to use, the following ones are reserved
for special functions.

 Register       Use
 ----------------------------------------
 eax            Top of Stack
 esi            Pointer to TOS
 esp            Return stack

All other registers (ebx, ecx, edx, edi, and ebp) are free for your use.
Generally, try to use the stack when possible, otherwise feel free to
take advantage of these registers.

esi is intially set to <m>sp0</m>, a 0x300 byte array. It can be <m>reset</m> to
that value at runtime.} 1078957488


#--------------------------------------------------
# RetroForth Tutorial

page {RetroForth Tutorial} {Now that you have RetroForth set up and ready for use, you can begin
writing simple programs in it. Please be aware that RetroForth does not
comply with any standards. I tend to to lean towards IsForth
compatibility, but I don't have problems with incompatible words if they prove
useful.

The Basics of Stacks

In RetroForth there are two or more stacks. All stacks can only store
numbers. The primary stack is used by most instructions. You can also use
a <i>return stack</i> for special purposes.

How do the stacks work?

  1 2 3 4 5

When RetroForth finds a number, it <i>pushes</i> that number to the top
of the stack. So it finds a <b>1</b>, and puts it onto the stack. It then
finds the <b>2</b>, and places that over the <b>1</b>. This is repeated
each time a number is encountered.

You can view the stack using a special word called <i>.s</i>. Using our
previous example, it works like follows:

  .s
  1 2 3 4 5

The 5 is on the top of the stack, the 1 is at the bottom. We can
manipulate the stack by using various words. In the descriptions below,
TOS means top of stack.

  dup   Duplicate the TOS
  drop  Remove the TOS
  swap  Switch the positions of the top two elements on the stack
  nip
  tuck
  over
  2dup
  2drop
  pick
  reset Remove all entries on the stack

Try each of these followed by <i>.s</i> and see exactly what they do.
#---
More to come...} 1078685732


#--------------------------------------------------
# RetroForth:Wiki

page RetroForth:Wiki {In March 2004, an experimental Wiki engine was written in RetroForth. The
core of this is the code in [html.f], but most of the wrapper code for
handling templates and saving the files is written in PHP.
} 1080903790


#--------------------------------------------------
# Sample Code

page {Sample Code} {Some simple programs can be examined under this section. Of these, only
the html generation code is really useful at the moment, the others will
gain usability over time.

* [html.f] HTML generation, used in [RetroForth:Wiki]
* [block-editor.f], an incomplete editor
* [math.f], extensions for mathmatic formulas
} 1080903682


#--------------------------------------------------
# Search

page Search {[@searchIndex@]} 1027085426


#--------------------------------------------------
# SEDForth

page SEDForth {SEDForth is an offshoot of the RetroForth project. It uses the same [Forth
core], including all of the primitives, but lacks the interactive nature
of RetroForth. The name derives from the fact that the parser/translator is written in
SED. This converts Forth code into assembly language, then assembles
this, along with the [Forth core] into a [Linux] application. At the time
of this writing, SEDForth is being partially rewritten to 
take full advantage of the latest version of RetroForth's core.

SEDForth does have some minor differences in definining words. Take the
following definition: <m>: ^2 dup * ;</m>  Under RetroForth, you'd
translate it into this assembly snippet:

 code '^2', power_2
  dup
  call multiply
 next

SEDForth uses a slightly different approach:

 scode power_2
  dup
  call multiply
 next

This is because the only real labels are the assembly ones under SEDForth.} 1078951152


#--------------------------------------------------
# The Macros

page {The Macros} {The [Forth core] uses macros to simplify development. Since our macros
are availible for both [NASM] and [FASM], you can use either assembler
for building the core.

The main macros you need to know:

 code 'forth_name', assembly_name
 mcode 'forth_name', assembly_name

<m>code</m> and <m>mcode</m> are used to define new primitives. They add
dictionary entries and provide an internal name for each word. If your
word does special things at compile time (such as <m>if, then, times, repeat</m>,
etc), use <m>mcode</m>. If not, use <m>code</m>. See [Adding a Primitive]
for more details including some simple examples.

 next

This is just a wrapper over the <m>ret</m> instruction. It's used for
consistancy more than anything else.

 inline BYTE, BYTE, BYTE, etc

With <m>mcode</m>, a method of adding bytes to the current word
definition is frequently needed. <m>inline</m> provides this. There is no
real limit on the number of bytes, though we recommend that lines don't
exceed five or six bytes per <m>inline</m>.

 embed 'forth code'

Many times a primitive will need to reference code written in Forth
rather than assembly. This macro allows you to embed small bits of Forth
code directly into a primitive.

 upsh VALUE/REGISTER/ADDRESS/[ADDRESS]
 upop REGISTER/[ADDRESS]

These are the core stack manipulation macros. <m>upsh</m> places a 32-bit
value on the stack; <m>upop</m> takes the top value off the stack.

 drop
 dup

These are identical to the Forth functions but are inlined for use with
the primitives.

 var 'name', name, value

Declare a Forth-accessible variable

 push
 pop

Push or pop multiple values from the stack} 1078957374


#--------------------------------------------------
# Threading Model

page {Threading Model} {RetroForth is a subroutine threaded Forth. This means that everything is
real assembly code, not a special VM-based approach. It also makes
translating Forth into assembly very easy:

 : ^2 dup * ;

 code '^2', power_2
  dup
  call multiply
 next

This easy translation is used by [SEDForth] to create tighter, native
applications using the [Forth core], and also to help migrate code
to or from assembly as needed.} 1078951207


#--------------------------------------------------
# Tweaking the Makefile

page {Tweaking the Makefile} {Starting with Release 6.20, RetroForth has used the <m>make</m> tool to
automate the build process. Prior to this we used build scripts, but
there were too many problems with them.

We now use a Makefile; if you want to add a port or otherwise tweak it,
this short guide will help you out quite a bit.

* [Makefile: Variables]
* [Makefile: All]
* [Makefile: Ports]
* [Makefile: Clean and Dist-clean]} 1079202036


#--------------------------------------------------
# User Code

page {User Code} {Use this page to extend Notebook using the 
[@helpbtn "the Tcl language"@].  Commands you add here can be used as
[@helpbtn "Magic Button"@]s and [@helpbtn "Embedded Macro"@]s.

#Tcl -- Do not delete this line! Everything after this line is Tcl code.

# Define the User Menu.  This menu pops up when you right-click on a page.
# You can add your own commands to it.
usermenu {
    Back backpage
    Home {showpage Home}
}

# Define the Edit Menu.  This menu pops up when you right-click 
# on a page in the page editor.  You can add your own commands to it.
editmenu {
    Undo             undo-change
    Redo             redo-change
    separator {}
    Cut              cut-string
    Copy             copy-string
    Paste            paste-string
    "Insert Page..." insert-page
}


# Create a magic button to go to the next page in the Tour
proc clickToContinue {name} {
	return "\[%Click here to continue...|showpage [list $name]%\]"
}

# End of page} 1073532475


#--------------------------------------------------
# Windows

page Windows {There are two versions of the Windows port. Both are based on the
codebase written by Ron Aaron in January 2004. They each differ in focus
and features.

The <m>windows-console</m> port is identical in functionality to the
<m>[linux]-console</m> port.

There is also a <m>windows-gui</m> port which provides some access to the
Windows API functions from within the Forth environment.} 1080007620


# End of Notebook Database File
