# ----------------------------------------------------------------------------- #
# Copyright (C) 2000,2002 Berlin h-peter recktenwald <phpr@snafu.de>		#
# "lib4th" : Forth dynamically linkable shared library for i468+ pc linux.	#
# lib4th is QT licensed, read ./doc/LEGAL for licensing terms			#
# ----------------------------------------------------------------------------- #

Ver. 0.0.26 (25-Jun-2000)
was the first trial-release, not thoroughly tested, and not at all "complete"...
execute "relse.sh" in main directory, for the actual version number.

# ----------------------------------------------------------------------------- #

lib4th
======

"lib4th" is a Forth kernel implemented as a sharable dynamically loadable 
library, written in assembly, compiled with "nasm-0.98-3e", relying on no 
further libraries, based on linux-pc-i386(+) kernel 2.2.10+ system calls.

It provides the core wordset according to ansi standard as described in the
"dpans94" document, and most of the additional wordsets, plus several extensions 
to as much as possible complying with the f.i.g.-model and later standards.

Particularly, lib4th does not implement the FLOATING wordsets but, provide the 
"rational" words for rational numbers "floating point" calculations. No cpu 
specific f.p. words will be implemted, due to unsufficient exactness as well 
by ANS-Forth definition and IEEE standards.

The BLOCK files wordset is slowly (very slowly!) under construction...
Any other ANS-Forth wordsets are available plus, many more words.

    ./f8 tools all-words bye
displays what is implemented, or about to be.


The library is not supposed to be "portable", though because besides the system 
calls it does not rely on Linux or ELF specific data structures any other fairly 
close ia-32 models (re "asmutils"!) should be suitable, after minor changes.

It was compiled and tested with
    1)
	linux-i586-pc kernel 2.2.14-rtl2.0 - rtlinux/debian 2.2,
	glibc 2.1.3, gcc 2.95.2, binutils 2.10.91, ldd 1.9.11, shutils 1.16.
    2)
	Linux 2.2.5 i586-unknown - redhat-6.0/Black Cat,
	glibc 2.1.1, egcs-2.91.66, binutils 2.9.1.0.23, ldd 2.1.1, shutils 1.16.
    3)
	linux-i586-pc kernel 2.4.0, re 1) - cpl & short tests, debian 2.2
    4)
	linux-i586-pc kernel 2.2.19, debian 2.2, (L4 current -8/2001- devel)
	glibc 2.1.3, gcc 3.1, binutils 2.11.90, ldd 2.1.3, shutils 2.0.


# ----------------------------------------------------------------------------- #

Running the binaries
====================

optionally define the lib4th env. vari "F8INI", for instance:
    export F8INI="only forth definitions ans hex ' .s also hidden idx>xec \
		4th>abs (ok) ! also linux also editor also testvoc also forth also"

The environment variable can then be used for (initial) input at program invocation
    ./f8 system f8ini
which can be compiled to always being evaluated on startup, re "Makefile", but 
might then involve a security risk when not running in a safely protected system.
Alternatively, it could even be used to reduce that risk, re the {real-user} word
and, the env-vari content will not be visible in the process data ("ps", etc).

execute
    make install
    ./f8		(dynamically linked w. dll)
or
    ./4			(statically linked "calc4th" to static lib)
to testing whether the pre-compiled binaries would do.

Basic usage
===========

    execute calc4th, 4 or f8, each of which are minimal binaries, to entering 
    the Forth kernel interpreter/compiler loop as set up in the library. 
    re {include} to load a program, etc.
    
    with an orderly installed documentation directory, use 
	help help
    in a running lib4th system, for the rsp. words' glossary text.
    

# ----------------------------------------------------------------------------- #

Documentation
=============

Documentation provided in "doc" directory:
    "glossary" and "glossary.idx" compiled from the sourcefiles' comments,
    "ansdoc.inc" for the supplemental required ANS system documentation.
    "answset_idx" is a checklist of what is implemented.
    "a-forth-design.inc" some (lengthy) notes on lib4th implementation details.
    Other articles wrt lib4th and the DPANS94 document in <ans> sub-directory.

    template.asm, ../src/calc4th.asm, ../src/f8.asm are example applications.

    docs adjusted for console screen size of 132x60 chars, min. width=120 chars, 
    html docs for orderly appearance in simple text print-out w/ "lynx"-browser.
    
    Text "glossary" and "glossary.idx", (fairly quickly) by
	<make doc>		basic reference, the comments from asm sources.

    Linked html docs can be generated w/
	<make html>		words by name and voc, linked to glossary text
	<make topx>		words reference by topic
	<make xref>		words & assembly labels cross reference
    executed from the main directory, docs go to <doc> dir, "l4*.html" names.
    which is done w/ a set of bash scrpts, thus *very* slow, ca 15m ea.

supplemental "lib4th-doc-ref" archive:
    ansi draft ("dpans94") in html and plain ascii text form,
    f6 sources, which implement an extended f.i.g.-model for 680xx cpu-s,
    w32f sources for an i486 assembler, un-modified.

"lib4th" docs available at
    http://home.snafu.de/phpr/lib4th.doc.f8.tar.bz2	(as cpl'd from source)
    http://home.snafu.de/phpr/lib4th-doc-ref.tar.bz2	(common 4th)
    http://home.snafu.de/phpr/lhpf8.html		(intro: en, de)

Compiling:
    Execute <make> to receive some hints on compiling, edit Makefile to suit.

# ----------------------------------------------------------------------------- #

Pre-requisites
==============

Hardware
    IBM-PC type computer, w. i486+ compatible cpu, preferrably i586+ type

Linux 
    i586(+)-pc-Linux-ELF system, a "stable" 2.2+ or 2.4+ kernel,
    mmx extensions and <cpuid> available to the processor (try "cpuid mmx");
    all rsp "lib4th" calls can be compiled in non-mmx variants, which might
    be preferrable when applications supposed to use float instructions are
    planned - undefine variable MMX in Makefile to forcing non-mmx variants.
    "lib4th" does not use any FPU operations, only <femms> supplied.
Other OS
    might do, if supported by "asmutils", but were never tried...

"asmutils"
    htp://linuxassembly.org/asmutils.html

patched, assembler "nasm-0.98-3e".
    the basic debugged version "nasm-0.98e" might do but, neither the original 
    "nasm" nor the (currently, 3/2001) utterly broken development versions will!
patches to upgrading from 0.98 to 0.98-3e:
    http://home.snafu.de/phpr/e-lhputils.html#nasm	(en)
    http://home.snafu.de/phpr/lhputils.html#nasm	(de)
my private, patches including variant of debian 2.2 GNU/GPL licensed version:
    http://home.snafu.de/phpr/nasm-0.98-3.1_i386.deb	(binary)

"lib4th" source, latest version available at
    http://home.snafu.de/phpr/lib4th.src.tar.bz2	(source package)
    http://home.snafu.de/phpr/lhpf8.html		(en L4 home page)
    http://home.snafu.de/phpr/lhpf8d.html		(de)
    http://home.snafu.de/phpr/lhpf8td.html		(de, Forth intro)

# ----------------------------------------------------------------------------- #

Compiling the library
=====================

...requires a working(!) nasm version and GNU-ish make, gcc, linker!
...works from any user accout which has access to the required utils.
...links w/o libc if "libc.a" in library search path, during "make"!

Main defaults, edit file MConfig, to configure for Makefile:

    CFLAGS	= -O2 -fomit-frame-pointer -nostartfiles -nostdlib
    AS		= /usr/src/asm/nasm/nasm
    LD		= ld
    LDFLAGS	= -shared
    LDCONFIG	= ldconfig
    INSTALL	= install
    INSTFLAGS	= -m644 -gusers -D
    LISDIR	= ./doc/lis/
    DOCDIR 	= /usr/local/doc/lib4th
    LIBDIR 	= /usr/local/lib

Always at least test dynamic library compilation to assure that lib4th doesn't 
duplicate any names from other, included or linked libraries - in which case 
<ld> would report an error and point to the name(s) concerned:
    SOLIB	= yes

Make-tags (examples, re actual "Makefile")

    make	or
    make help	displays the supported make tags w/ a short explanation

    make help|less
		if console screen size smaller than 132x60 chars

then
    make new	check for utilities and support files, forcedly compile
or
    make all	compile as usual
    make 4	generating the statically linked "calc4th" variant


finally try, e.g.
    ./f8 10 20 2dup \* \$. + u. bye
arguments may be up to 4K bytes, "quoted", or not, as the rsp shell requires.

to executing an interactive Forth job just enter
    ./f8

Optionally execute
    make tests

or, from main directory
    (cd tests;t.sh)

if all went well
    make install

just the glossary
    make docs

NOTE:
    <make install> after compiling just the lib's, before testing.
    if compiling from an un-privileged (no "sudo" &c, available), do
    <ldconfig> as root to make the dll available to dyn. linked L4 programs or, 
    execute w/ e.g.
	(LD_LIBRARY_PATH="/usr/local/lib/lib4th.so" program-name)

# ----------------------------------------------------------------------------- #

A NOTE ON "NASM":

    Oderly assembly and linking should not produce any warnings!

    Warnings during assembly would most certainly point to faulty binary even 
    if the assembly apparently finished ok. particularly, 
	"warning: label alone on a line without a colon might be in error"
    almost for certain is due to an error!

    further, "nasm" might well be expected to emanate quite silly error messages
    which not at all point to the real cause. if those messages occur the assembly
    would always end up in something unuseable, thus should be taken seriously!

    f.i., <make depend> w. "error 139", which should be pointing to a segfault, 
    probably due to endless recursion, could occur if an include-file was not in 
    the search path or, if an unbalanced %if..-sequence was found.

    By <make> generated '(ignored)' errors are also nothing to worry about.

    asm-listings
	stored to doc/lis directory, cut to significant content (ca. 1.4MB).
	copy util/lis2sel.true to lis2sel to leaving the listings unchanged.
	lib4th-static variant listing always remains unchanged (ca. 3MB).
    asm-error logfiles
	go to the doc/lis directory.
	
    nasm, by producing it's specific "listing", or when dependencies scanning 
    can become annoyingly slow. Thus dependencies are (hopefully...) found by 
    two simple shell scripts (admin/fdinc, admin/mupdt). The lengthy useless
    parts of listings, about 4MB+ of meaningless "macroes listing", can only
    be suppressed with the ".nolist" string after each single macro header. If 
    "_nolist" set, instead, this may be set to not/listing by a %defined value.
    Even the relatively few "asmutils" calls expand to more than 1MB of text.
    Short listing mode saves about 6MB of text output and 50% of "make"-time!
    
# ----------------------------------------------------------------------------- #

Programming with "lib4th":

    re above, "Pre-requisites":
    ! Use an assembler, "nasm-0.98-3e" tested and ok, plain "nasm" won't do !
    Everything in this distribution made up for (my version of) "nasm-0.98-3e".


    LIB4TH
    ------

    With lib4th you can almost as easy as with high level Forth, and superior
    to any other hi-level "language", write your (quasi-)assembler programs.

    Directly programming a Forth program is just assembly, only difference 
    being the fact that no special knowledge required but Forth.

    Insert the include lines to top of program assembly:
	%include "version.inc"	; may be any, is expected by other include-s
	%include "system.inc"	; basic defn's from "asmutils"
	%include "termbits.inc"	; terminal defn
	%include "fcntl.inc"	; i/o mode
	%include "vt.inc"	; vt struc's
	%include "reloc.inc"	; for <kernref>
	%include "constants.inc"; F8 description data
	%include "lib4th.mac"	; programming support
	%include "errno.inc"	; error messages
	%include "pushpop.mac"	; (sic)
	%include "ascictrl.inc"	; chtrl cars names
	%include "limits.h.inc"	; host system constants

    and probably, to aid on debugging
	%include "debug.inc"	; debugging macros

    last, for all library words (which extends the binary by about 60K+!)
	%include "lib4words.inc"

    macro XN type, list_of_names ...
	provided for extern-s to explicitely named words, which might be the 
	better choice, mainly for small programs, or even less overhead with

    macro jmpx (callname)
    macro callx (callname)
	which also define the particular external reference.


    START4TH, END4TH
    ----------------

    A macro is provived for easy startup, setting up required memory areae, 
    global and external and, register references

	START4TH 0, help_prcedure, ptr_to_prog_entry_rel_to_kernelref
    and at end of 4th program

	END4TH
    which provides for 256-aligned last ptr in program.


    CREA4TH ACTV4TH CLON4TH
    -----------------------
    NOTE: multi-tasking w/ multiple internally set-up jobs was tested and ok,
    in the early development stages, only, and most certainly won't work with
    the current version. this is left until the library is fairly "complete".


	CREA4TH
    setting up a Forth clone (independently m.tasking job), yet in-active.
    prepare any data the standard setup doesn't provide (re "lib4th.mac").

	ACTV4TH
    start the clone.

	CLON4TH
    at clone entry, to finish clone's initiation.


    Those macroes aren't secret, thus re "lib4th.mac" to get an idea of what  
    assembly will by done, inside, and further, pse. re glossary.
    
    After START4TH:

    context
	    {root}
    current
	    {root}
    registers
	which should be preserved by any non-4th procedures:
	    eax		tos cell
	    ebx		kernel base address, i.e. the library,
	    edi		datastack, tos item is @eax.
	    esi		ptr to local variables.
	    ebp		reference into user-variables area

    Kernel reference, ebx, can (and should, before any subsequent call to the 
    library) any time be restored quite easily, by (global function):
	    call getref

    Wrapping for "C" or other languages would also require to saveing these
    registers and associated memory areae. Just this, no other precautions.

    Execution of Forth words at assembly level is simply <call>-ing the 
    respective names. Enter any calls to 4th words as
    
	    call (callname)
    or, use the macro calls, which additionally define 'extern (callname)'
    
	    callx (callname)
	    jmpx (callname)
    where (callname) may differ from common 4th names because of inadequate
    naming facilities in "nasm" (or almost any other non-Forth assembler).
    Re glossary or { help name } for any non-standard, asm-specific names.

    Calling and registers conventions described in glossary.
    Any other programming is assembly as usual and not restricted by "lib4th".


    MAKEing a 4th Program
    ---------------------

    Have "lib4th.so" in library path, or refer explicitely, then procede as 
    in the libraries "Makefile":

	PROG	= prog4th
	ASFLAGS += -DDATE=\"$(shell date +%y%m%d)\"
	ASFLAGS += -d__PROG=\"$(PROG)\"

	ASFLAGS += -d__LINUX__ -d__KERNEL__=22 -d__OPTIMIZE__=__O_SPEED__

	ASFLAGS += -f elf -w+orphan-labels
	ASFLAGS += -i./src/ -i./inc/ -i./inc/asmutils/ -i./inc/dbg/

	CFLAGS	= -O2 -fomit-frame-pointer -nostartfiles -nostdlib
    
	%.o:	%.asm
		nasm $(ASFLAGS) $<

	prog4th: prog4th.o lib4th.so Makefile
		gcc $(CFLAGS) -o prog4th prog4th.o ./lib4th.so
		strip --strip-unneeded --remove-section=.comment prog4th

# ----------------------------------------------------------------------------- #
# INSTALL lib4th <eof>
