Merge pull request #40 from forth-ev/8086-3.9.x

8086 3.9.x
This commit is contained in:
Carsten Strotmann 2022-08-18 11:32:56 +00:00 committed by GitHub
commit e8bf0dc77a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 4331 additions and 435 deletions

2
.gitignore vendored
View File

@ -2,3 +2,5 @@
*.log
/.DS_Store
*~
/tools/blkpack
/tools/blkunpack

File diff suppressed because one or more lines are too long

View File

@ -20,7 +20,7 @@ ende 123
\ *** Block No. 1, Hexblock 1
\ volksFORTH Loadscreen for py65 target cas 15juli2020
\ volksFORTH Loadscreen for py65 target cas 02aug2020
forth definitions
: (C [compile] ( ; IMMEDIATE \ : ) ; IMMEDIATE
@ -58,7 +58,7 @@ HERE DUP ORIGIN!
\ *** Block No. 3, Hexblock 3
\ Coldstartvalues and user variables cas 15juli2020
\ Coldstartvalues and user variables cas 02aug2020
\
0 JMP 0 JSR HERE 2- >LABEL >WAKE
@ -67,7 +67,7 @@ HERE DUP ORIGIN!
0D6 ALLOT
\ Bootlabel
," VOLKSFORTH-83 3.8 py65 15july2020 CS"
," VolksForth-83 3.8.1 py65 02aug2020 CS"
@ -172,7 +172,7 @@ USER UDP \ POINTS TO NEXT FREE ADDR IN USER
\ *** Block No. 9, Hexblock 9
\ MANIPULATE SYSTEM POINTERS 29JAN85BP)
\ MANIPULATE SYSTEM POINTERS 29JAN85BP) cas 02aug2020
CODE SP@ ( -- ADDR)
SP LDA N STA SP 1+ LDA N 1+ STA
@ -628,12 +628,12 @@ CODE U< ( U1 U2 -- FLAG)
\ *** Block No. 33, Hexblock 21
\ COMPARISION WORDS 24DEC83KS)
\ COMPARISION WORDS 24DEC83KS) cas 02aug2020
| : 0< 8000 AND 0<> ;
: > ( N1 N2 -- FLAG) SWAP < ;
: 0> ( N -- FLAG) NEGATE 0< ;
: 0> ( N -- FLAG) DUP 0< SWAP 0= OR NOT ;
: 0<> ( N -- FLAG) 0= NOT ;
: U> ( U1 U2 -- FLAG) SWAP U< ;
: = ( N1 N2 -- FLAG) - 0= ;
@ -2300,7 +2300,7 @@ HOST TARGET
\ *** Block No. 121, Hexblock 79
\ 'COLD 07JUN85BP) cas 15juli2020
\ 'COLD 07JUN85BP) cas 02aug2020
| : INIT-VOCABULARYS VOC-LINK @
BEGIN DUP 2- @ OVER 4 - ! @ ?DUP 0= UNTIL ;
@ -2309,7 +2309,7 @@ HOST TARGET
DEFER 'COLD ' NOOP IS 'COLD
| : (COLD INIT-VOCABULARYS INIT-BUFFERS PAGE 'COLD ONLYFORTH
." volksFORTH-83 3.8 py65 202007" CR RESTART ; -2 ALLOT
." volksFORTH-83 3.8.1 py65 202008" CR RESTART ; -2 ALLOT
DEFER 'RESTART ' NOOP IS 'RESTART
| : (RESTART ['] (QUIT IS 'QUIT

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
\\ Transinient Assembler 11Nov86 Dieses File enthaelt Befehle, die den Assembler vollstaendig in den Heap laden, so dass er schliesslich mit clear wieder vergessen werden kann. Dadurch ist es nicht notwendig in einer Anwendung den ganzen Assembler im Speicher lassen zu muessen, nur weil einige primitive Worte in Assembler geschrieben sind. \ Internal Assembler UH 22Oct86 Onlyforth here $C00 hallot heap dp ! include ass8080.scr dp !

File diff suppressed because one or more lines are too long

1
8080/AmstradCPC/COPY.SCR Normal file
View File

@ -0,0 +1 @@
\ Copy und Convey 19Nov87 Dieses File enthaelt Definitionen, die urspruenglich im Kern enthalten waren. Sie sind jetzt ausgelagert worden, um den Kern klein zu halten. copy kopiert einen Screen convey kopiert einen Bereich von Screens \ moving blocks 20Oct86 19Nov87| : full? ( -- flag ) prev BEGIN @ dup @ 0= UNTIL 6 + @ 0< ; | : fromblock ( blk -- adr ) fromfile @ (block ; | : (copy ( from to -- ) dup isfile@ core? IF prev @ emptybuf THEN full? IF save-buffers THEN offset @ + isfile@ rot fromblock 6 - 2! update ; | : blkmove ( from to quan --) save-buffers >r over r@ + over u> >r 2dup u< r> and IF r@ r@ d+ r> 0 ?DO -1 -2 d+ 2dup (copy LOOP ELSE r> 0 ?DO 2dup (copy 1 1 d+ LOOP THEN save-buffers 2drop ; : copy ( from to --) 1 blkmove ; : convey ( [blk1 blk2] [to.blk --) swap 1+ 2 pick - dup 0> not Abort" Nein !" blkmove ;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
\\ Double words 11Nov86 Dieses File enthaelt Worte fuer 32-Bit Objekte. Im Kern bereits enthalten sind: 2@ 2! 2dup 2drop 2swap dnegate d+ Hier werden definiert: 2Variable 2Constant 2over d* \ 2over 2@ 2! 2Variable 2Constant UH 30Oct86 : 2Variable Variable 2 allot ; : 2Constant Create , , does> 2@ ; Code 2over ( 32b1 32b2 -- 32b1 32b2 32b1 ) 7 H lxi SP dad M D mov H dcx M E mov D push H dcx M D mov H dcx M E mov D push Next end-code --> \\ Code 2@ ( addr -- 32b ) H pop H push H inx H inx M E mov H inx M D mov H pop D push M E mov H inx M D mov D push Next end-code Code 2! ( 32b addr -- ) H pop D pop E M mov H inx D M mov H inx D pop E M mov H inx D M mov Next end-code \ d* d- 29Jun86 : d* ( d1 d2 -- d1*d2 ) rot 2over rot um* 2swap um* d+ 2swap um* d+ ; : d- ( d1 d2 -- d1-d2 ) dnegate d+ ;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

BIN
8080/AmstradCPC/KERNEL.COM Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
\ Mathematics calculating sin & cos nach FD IV 1 6UH 03Dec86 Dieses File enthaelt Definitionen zur Berechnung von Integer-Sinus und -Cosinus. Sie werden z.B. von der Turtle-Grafik benutzt. \ Mathematics calculating sin & cos nach FD IV 1 6 05Sep86 Create sintab decimal 0000 , 0175 , 0349 , 0523 , 0698 , 0872 , 1045 , 1219 , 1392 , 1564 , 1736 , 1908 , 2079 , 2250 , 2419 , 2588 , 2756 , 2924 , 3090 , 3256 , 3420 , 3584 , 3746 , 3907 , 4067 , 4226 , 4384 , 4540 , 4695 , 4848 , 5000 , 5150 , 5299 , 5446 , 5592 , 5736 , 5878 , 6018 , 6157 , 6293 , 6428 , 6561 , 6691 , 6820 , 6947 , 7071 , 7193 , 7314 , 7431 , 7547 , 7660 , 7771 , 7880 , 7986 , 8090 , 8192 , 8290 , 8387 , 8480 , 8572 , 8660 , 8746 , 8829 , 8910 , 8988 , 9063 , 9135 , 9205 , 9272 , 9336 , 9397 , 9455 , 9511 , 9563 , 9613 , 9659 , 9703 , 9744 , 9781 , 9816 , 9848 , 9877 , 9903 , 9925 , 9945 , 9962 , 9976 , 9986 , 9994 , 9998 , 10000 , : sintable ( deg -- sine*10000 ) 2* sintab + @ ; --> \ sin 05Sep86 : s180 ( deg -- sine*10000 ) dup 90 > IF 180 swap - ( reflect ) THEN sintable ; : sin ( deg -- sine*10000 ) 360 mod dup 180 > IF 180 - s180 negate exit THEN s180 ; : cos ( deg -- cosine*10000 ) 90 + sin ; hex

View File

@ -0,0 +1 @@
\ 8080-Portzugriff UH 11Nov86 Dieses File enthaelt Definitionen um die 8080-Ports ueber 8-Bit Adressen anzusprechen. Der Code ist leider selbstmodifizierend, da beim 8080 die Portadresse im Code ausdruecklich angegeben werden muss. Sollte dies unerwuenscht sein und ein Z80-Komputer vorliegen, kann auch das File portz80.scr benutzt werden, indem die Z80-IO-Befehle (16Bit-Adressen) benutzt werden. \ 8080-Portzugriff pc@, pc! 15Jul86 ' 0 | Alias patch Code pc@ ( addr -- c ) H pop L A mov here 4 + sta patch in 0 H mvi A L mov Hpush jmp end-code Code pc! ( c addr -- ) H pop L A Mov here 6 + sta H pop L A mov patch out Next end-code

View File

@ -0,0 +1 @@
\ Z80-Portzugriff UH 05Nov86 Dieses File enthaelt Definitionen um die Z80-Ports ueber 16-Bit Adressen anzusprechen. Einige Komputer, so die der Schneider Serie dekodieren ihre Ports etwas unkonventionell, sodass sie unbedingt ueber 16-Bit Adressen angesprochen werden muessen. Im allgemeinen sollte es ausreichen 8-Bit Adressen zu benutzen. \ Z80-Portaccess Extending 8080-Assembler UH 05Nov86 Assembler definitions | : Z80-io ( base -- ) \ define special Z80-io instruction Create c, Does> ( reg -- ) $ED c, c@ swap 8 * + c, ; $40 Z80-io (c)in $41 Z80-io (c)out Forth definitions --> \ store and fetch values with 16-bit port-adresses UH 05Nov86 Code pc@ ( 16b -- 8b ) \ fetch 8-bit value from 16-bit port-addr H pop IP push H B mvx L (c)in 0 H mvi IP pop hpush jmp end-code Code pc! ( 8b 16b -- ) \ store 8-bit value to 16-bit port-addr H pop D pop IP push H B mvx E (c)out IP pop Next end-code

View File

@ -0,0 +1 @@
\\ Primitivst Editor zur Installation UH 17Nov86 Da zur Installationszeit der Full-Screen Editor noch nicht funtionsfaehig ist, muessen die zu aendernden Screens auf eine andere Weise ge{nder werden: mit dem primitivst Editor PRIMED, der nur ein Benutzer wort enthaelt: Benutzung: Mit "nn LIST" Screen nn zum editieren Anwaehlen, dann mit "ll NEW" den Screen aendern. Es koennen immer nur ganze Zeilen neu geschrieben werden. ll gibt an, ab welcher Zeilennummer neue Zeilen eingeben werden sollen. Die Eingabe einer leeren Zeile (nur RETURN) bewirkt den Abruch von NEW. Nach jeder Eingabe von RETURN wird die eingegebene Zeile in den Screen uebernommen, und der ganze Screen zur Kontrolle nocheinmal ausgegeben. \ primitivst Editor PRIMED UH 17Nov86 | : !line ( adr count line# -- ) scr @ block swap c/l * + dup c/l bl fill swap cmove update ; : new ( n -- ) l/s 1+ swap ?DO cr I . pad c/l expect span @ 0= IF leave THEN pad span @ I !line cr scr @ list LOOP ; \ PRIMED Demo-Screen Dieser Text entstand durch: "2 LIST 4 NEW" mit anschliessender Eingabe dieses Textes Die Kopfzeile (Zeile 0) wurde spaeter durch Verlassen von new durch Eingabe einer leeren Zeile (nur RETURN) und Neustart mit "0 NEW" erzeugt. Ulrich Hoffmann

File diff suppressed because one or more lines are too long

123
8080/AmstradCPC/READ.ME Normal file
View File

@ -0,0 +1,123 @@
[nderungen im CP/M-volksFORTH von Version 3.80 zu Version 3.80a UH 04M{r88
=============================================================================
Die Unvertr{glichkeit des urspr}nglichen CP/M-volksFORTHs mit CP/M+ und die
damit verbundene Vielzahl von unterschiedlichen Versionen hat eine allgmeine
]berarbeitung des CP/M-volksFORTHs notwendig gemacht.
Bei dieser Gelegenheit wurden gleich einige Fehler beseitigt und einige
neue Funktionen eingef}hrt.
1. [nderungen im Kern (SOURCE.SCR)
- Die Terminal-Ein- und Ausgabe wurde auf ein Mindestma~ begrenzt,
soda~ auch unmittelbar mit dem Kern gearbeitet werden kann.
Es gibt keinen Zeileneditor f}r die Eingabezeile mehr, dieser wurde
zusammen mit der "Terminal:" Funktion in das File XINOUT.SCR ausgelagert.
- Der Kern enth{lt kein Fileinterface mehr, sondern arbeitet nur in dem
File, da~ bei Aufruf in der Kommandozeile mit angegeben wird (default-
file). Typischerweise wird mit diesem Mechanismus zuerst das
File-Interface geladen.
- Direkter Diskettezugriff wird im Kern nicht mehr unterst}tzt, da er
unter CP/M+ nicht problemlos zu implementieren ist. Au~erdem kann
in Ermangelung eines CP/M+ Systems der Code hier nicht getestet werden.
Diskettenzugriff findet nur noch }ber das BDOS statt.
- Zahlreiche Funktionen des Kerns wurden neu }berarbeitet und in Code
geschrieben, als wichtige neue Funktion des Kerns ist "search hinzu-
gekommen, das eine schnelle Suche mit Ber}cksichtigung der Gro~/Klein-
schreibung erm|glicht.
- Die Funktion CAPITALIZE ist durch die {hnliche Funktion UPPER ersetzt
worden. Das EXIT in NAME verschiebt sich dadurch.
- Der Kern gibt beim Verlassen eine Gr|~enangabe in (256 Byte)-Seiten aus.
Diese Angabe kann direkt benutzt werden, um mit dem CP/M SAVE Kommando
das System auf Diskette zu schreiben. (Forth: SAVE nicht vergessen! )
- SAVE-BUFFERS ist um ein defered Wort SAVE-DOS-BUFFERS erweitert worden.
Damit sollte der l{stige CP/M+ Fehler ausgeschaltet sein.
- Das defered Wort POSTLUDE regelt die letzte Handlung des Systems vor dem
CP/M Warmstart (Cursor anschalten, Bildschirm l|schen oder Systemgr|~e
ausgeben...)
- Die Kommandozeile des Aufrufs wird in den TIB kopiert und kann dort
interpretiert werden. Das \ffnen des default-Files l|scht allerdings den
TIB wieder, soda~ diese Funktion erst ausgenutzt werden kann, wenn das
Fileinterface geladen ist. (DRVINIT |ffnet nicht mehr das default-File.)
- Die Interpret-Loop wurde }berarbeitet und um das Wort PROMPT erweitert.
Das Sonderwort >INTERPRET ist weggefallen. Seine Funktion uebernimmt
jetzt das (normale) defered Wort PARSER.
- Die Kontrollstruktur-Anweisungen (IF, WHILE ... ) sind jetzt auch inter-
aktiv verwendbar.
- Diverse kleinere [nderungen haben stattgefunden.
2. [nderungen im Editor (EDITOR.SCR, STRING.SCR)
- Das Markieren der Screens wurde korrigiert und geschieht jetzt auch
beim Suchen/Ersetzen und bei showload richtig.
- VIEW wurde ge{ndert und sucht nun nach dem in Blanks eingerahmten Wort.
- Es wird nun zus{tzlich das Associative File angezeigt.
- Beim Suchen/Ersetzen wird die Screennummer hochgez{hlt, um eine Kontrolle
}ber das Suchen zu geben.
- Die Textsuche ist nun schon im Kern definiert, die elementaren String-
funktionen sind mit in das EDITOR.SCR genommen worden. STRING.SCR ist
daher entfallen.
3. [nderungen im Multi-Tasker (TASKER.SCR)
- Das Wort TASK wurde ge{ndert: Die Konstante ist nun vor der Task
definiert. Man kann also nun mit FORGET <taskname> tats{chlich die Task
vergessen.
- Der PAUSE/WAKE/STOP-Mechanismus wurde ge{ndert. In der benutzung ergibt
sich daraus keine [nderung.
4. [nderungen im Fileinterface (FILEINT.SCR)
- Das Fileinterface wurde }berarbeitet und einige Fehler beseitigt.
Die Namen zahlreicher Worte haben sich ge{ndert, sind dadurch aber
systematischer geworden. Die Funktionen sind im Wesentlichen gleich
geblieben.
5. Terminal-Installation (Zusatz zu Anpassung von volksFORTH an den Computer)
- Da der Kern kein Fileinterface mehr enth{lt, mu~ dies noch vor
dem Primitivst-Editor geladen werden. Es ergibt sich also die Kommando-
sequenz:
A> kernel fileint.scr
1 load
use primed.scr 1 load
use terminal.scr
6. Erstellen eines Standard-Systems
- Mit folgender Kommandosequenz wird aus KERNEL.COM das File
VOLKS4TH.COM gemacht:
A> kernel fileint.scr
1 load
include startup.scr
7. Neue Files auf der Diskette
- READ.ME dieses File
- XINOUT.SCR Terminalfunktionen und Zeileneditor f}r Eingabe
- COPY.SCR Die Funktionen COPY und CONVEY (fr}her im Kern).
- STRING.SCR Entf{llt, da in EDITOR.SCR und SOURCE.SCR integriert.


View File

@ -0,0 +1 @@
\\ Relocate System 11Nov86 Dieses File enthaelt das Utility-Wort BUFFERS. Mit ihm ist es moeglich die Zahl der Disk-Buffers festzulegen, die volksFORTH benutzt. Voreingestellt sind 4 Buffer. Benutzung: nn BUFFERS \ Relocate a system 16Jul86 | : relocate-tasks ( mainup -- ) up@ dup BEGIN 2+ under @ 2dup - WHILE rot drop REPEAT 2drop ! ; | : relocate ( stacklen rstacklen -- ) 2dup + b/buf + 2+ limit origin - u> abort" kills all buffers" over pad $100 + origin - u< abort" cuts the dictionary" dup udp @ $40 + u< abort" a ticket to the moon with no return ..." flush empty over + origin + origin $0A + ! \ r0 origin + dup relocate-tasks \ multitasking link 6 - origin 8 + ! \ s0 cold ; --> \ bytes.more buffers 29Jun86 | : bytes.more ( n+- -- ) up@ origin - + r0 @ up@ - relocate ; : buffers ( +n -- ) b/buf * 4+ limit r0 @ - swap - bytes.more ;

View File

@ -0,0 +1 @@
\\ savesystem 11Nov86 Dieses File enthaelt das Utility-Wort SAVESYSTEM. Mit ihm kann man das gesamte System als File auf Disk schreiben. Achtung: Es wird SAVE ausgefuehrt, daher ist nach SAVESYSTEM der Heap geloescht! Benutzung: SAVESYSTEM <filename> \ savsystem 05Nov86 : savesystem \ filename save $100 here over - savefile ; \\ Einfaches savesystem 18Aug86 | : message ( -- ) base push decimal cr ." ready for SAVE " here 1- $100 / u. ." VOLKS4TH.COM" cr ; : savesystem ( -- ) save message bye ;

1
8080/AmstradCPC/SEE.SCR Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
\\ Simple Files 11Nov86 Wenn volksFORTH im Direktzugriff Disketten bearbeitet, ist es trotzdem wuenschenswert eine Art File-Struktur zu besitzen. Dieses File enthaelt eine einfache Implementation eines Filesystems. Der/die Programmierer/in muss selbst die Direktory auf dem laufenden halten: in ihr sind die Start-Bloecke des entsprechenden Diskettenteils gespeichert. Sogar eine Hierarchie von Direktories laesst sich so relisieren. Vorgestellt wurde dieses FileSystem von Georg Rehfeld und auch von ihm fuer volksFORTH implementiert (ultraFORTH auf dem C64). \ simple files 12feb86 \needs search .( search missing) \\ | Variable (dir : dir (dir @ ; : root 0 (dir ! ; root | : read" ( -- n) Ascii " word count dup >r dir block b/blk search 0= abort" not found" r> + >in push >in ! bl dir block b/blk (word number drop ; : load" read" dir + load ; : dir" read" (dir +! ; : list" read" dir + list ; \ 1 +load \ Only if file" is needed \ simple files 01feb86 | : snap ( n0 -- n1) $20 / 3 max $20 * ; : file" ( n --) Ascii " word count 2dup dir block b/blk search IF + nip ELSE drop dir block b/blk -trailing nip snap $20 + dup b/blk 1- > abort" directory full" 2dup + >r dir block + swap cmove r> THEN snap $18 + >r dir - extend under dabs <# # # # # base @ $0A = IF Ascii & ELSE Ascii $ THEN hold rot 0< IF Ascii - ELSE bl THEN hold #> r> dir block + swap cmove update ; \ dir load" 11feb86 \needs search .( search missing) \\ 0 Constant dir : load" ( -- ) Ascii " word count dup >r dir block b/blk search 0= abort" not found" r> + >in @ blk @ rot >in ! dir blk ! bl word number drop -rot blk ! >in ! load ;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
\\ Startup: Load Standard System UH 11Nov86 Dieses File enthaelt Befehle, die aus dem File KERNEL.COM ein vollstaendiges volksFORTH machen, das mit SAVESYSTEM als File (z.B. VOLKS4th.COM) auf Disk geschrieben werden kann. \ System LOAD-Screen fuer CP/M VolksForth ( 10.02.89/KK ) include ass8080.scr include xinout.scr \ Erweiterte Ein- u. Ausgabe include terminal.scr save \ Terminal include copy.scr cr .( copy und convey geladen.) cr include savesys.scr cr .( Savesystem geladen.) cr include editor.scr cr .( Editor geladen.) cr include tools.scr cr .( Tools geladen.) cr include see.scr cr .( Decompiler geladen.) cr include tasker.scr cr .( Multitasker geladen.) cr include printer.scr cr .( Printer Interface geladen.) cr include relocate.scr cr .( Relocating geladen. ) cr .( May the volksFORTH be with you ...) cr decimal caps on editor.scr scr off r# off ( savesystem volks4th.com ) \ UH 22Oct86

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
\\ Terminal-Anpassung 11Nov86 In diesem File wird volksFORTH an das benutzte Terminal angepasst. Ueber folgende Faehigkeiten muss das Terminal verfuegen, damit alle Moeglichkeiten von volksFORTH ausgenutzt werden koennen: curon, curoff \ Ein- bzw. Ausschalten des Cursors curleft, currite \ Cursor nach links bzw. rechts bewegen rvson, rvsoff \ Ein- bzw. Ausschalten der Inversedarstellungdark \ Loeschen des Bildschirms locate \ Positionieren des Cursors auf eine \ bestimmte Position auf dem Bildschirm \ Schneider CPC464-Terminal Anpassung UH 18Mar87 | : CPCcuron ( -- ) 3 con! ; | : CPCcuroff ( -- ) 2 con! ; | Variable reverse reverse off | : CPCrvson ( -- ) reverse @ ?exit reverse on $18 con! ; | : CPCrvsoff ( -- ) reverse @ 0= ?exit reverse off $18 con! ; | : CPCdark ( -- ) $0C con! ; | : CPClocate ( row col -- ) $1F con! 1+ con! &24 min 1+ con! ; Terminal: schneider CPCcuron CPCcuroff CPCrvson CPCrvsoff CPCdark CPClocate ; schneider page .( CPC-464 Terminal installiert. ) cr cr

View File

@ -0,0 +1 @@
\\ Times Often: interactive loops 11Nov86 Dieses File enthaelt die Definitionen der beiden Utility-Worte TIMES, OFTEN, die interaktiv benutzt werden koennen, was normalerweise mit BEGIN WHILE ... nicht moeglich ist. Benutzung: nur interaktiv! a b ... nn times \ Wiederhole die Befehlsfolge "a b ..." nn mal, \ oder bis eine Taste gedrueckt wird, oder \ bis ein Fehler auftritt, a b ... often \ Wiederhole die Befehlsfolge "a b ..." \ so oft, bis eine Taste gedrueckt wird, oder \ bis ein Fehler auftritt. \ Times, Often 02feb86 also Forth definitions : often stop? ?exit >in off ; | Variable #times #times off : times ( n --) ?dup IF #times @ 2+ u< stop? or IF #times off exit THEN 1 #times +! ELSE stop? ?exit THEN >in off ; toss definitions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
\\ Startup: Load Standard System UH 11Nov86 Dieses File enthaelt Befehle, die aus dem File KERNEL.COM ein vollstaendiges volksFORTH machen, das mit SAVESYSTEM als File (z.B. VOLKS4th.COM) auf Disk geschrieben werden kann. \ System LOAD-Screen fuer CP/M VolksForth UH 27Nov87include ass8080.fb include xinout.fb \ extended I/O include terminal.fb save \ Terminal include copy.fb cr .( copy and convey loaded) cr include savesys.fb cr .( Savesystem loaded) cr include editor.fb cr .( Editor loaded) cr include tools.fb cr .( Tools loaded) cr include see.fb cr .( Decompiler loaded) cr include tasker.fb cr .( Multitasker loaded) cr include printer.fb cr .( Printer Interface loaded) cr include relocate.fb cr .( Relocating loaded) cr .( May the volksFORTH be with you ...) cr decimal caps on scr off r# off savesystem volks4th.com UH 22Oct86
\\ Startup: Load Standard System UH 11Nov86 Dieses File enthaelt Befehle, die aus dem File KERNEL.COM ein vollstaendiges volksFORTH machen, das mit SAVESYSTEM als File (z.B. VOLKS4th.COM) auf Disk geschrieben werden kann. \ System LOAD-Screen fuer CP/M VolksForth UH 27Nov87include ass8080.fb include xinout.fb \ extended I/O \ include terminal.fb save \ Terminal include copy.fb cr .( copy and convey loaded) cr include savesys.fb cr .( Savesystem loaded) cr include editor.fb cr .( Editor loaded) cr include tools.fb cr .( Tools loaded) cr \ include see.fb cr .( Decompiler loaded) cr \ include tasker.fb cr .( Multitasker loaded) cr \ include printer.fb cr .( Printer Interface loaded) cr include relocate.fb cr .( Relocating loaded) cr .( May the volksFORTH be with you ...) cr decimal caps on scr off r# off savesystem volks4th.com UH 22Oct86

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,25 @@
TARGET = forth.com
BASE = ../..
BLKPACK = $(BASE)/tools/blkpack
BOOTPRG = ./bootdisk
.PHONY: all
all: $(TARGET)
%.fb: %.fth $(BLKPACK)
$(BLKPACK) < $< > $@
$(TARGET): kernel.fb meta.fb
emu2 $(BASE)/8086/pc-baremetal/volks4th.com "include kernel.fb bye"
.PHONY: floppy
floppy:
$(BOOTPRG)/mkimg144 -bs $(BOOTPRG)/flp144.bin -o floppy.img -us $(TARGET)
.PHONY: qemu
qemu:
qemu-system-i386 -curses -drive file=floppy.img,if=floppy,format=raw -monitor telnet:127.0.0.1:1234,server,nowait
.PHONY: clean
clean:
rm -f $(TARGET) meta.com *.fb floppy.img

View File

@ -0,0 +1,14 @@
TARGET = mkimg144 flp144.bin
.PHONY: all
all: $(TARGET)
flp144.bin: flp144.asm
nasm $< -f bin -o $@
mkimg144: mkimg144.c
$(CC) -o $@ $<
.PHONY: clean
clean:
rm -f $(TARGET)

View File

@ -0,0 +1,526 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; "BootProg" Loader v 1.5 by Alexey Frunze (c) 2000-2015 ;;
;; 2-clause BSD license. ;;
;; ;;
;; ;;
;; This is a version of boot12.asm fully ready for a 1.44MB 3"5 floppy. ;;
;; ;;
;; ;;
;; How to Compile: ;;
;; ~~~~~~~~~~~~~~~ ;;
;; nasm flp144.asm -f bin -o flp144.bin ;;
;; ;;
;; ;;
;; Features: ;;
;; ~~~~~~~~~ ;;
;; - FAT12 supported ;;
;; ;;
;; - Loads a 16-bit executable file in the MS-DOS .COM or .EXE format ;;
;; from the root directory of a disk and transfers control to it ;;
;; (the "ProgramName" variable holds the name of the file to be loaded) ;;
;; ;;
;; - Prints an error if the file isn't found or couldn't be read ;;
;; (the "RE" message stands for "Read Error", ;;
;; the "NF" message stands for "file Not Found") ;;
;; and waits for a key to be pressed, then executes the Int 19h ;;
;; instruction and lets the BIOS continue bootstrap. ;;
;; ;;
;; ;;
;; Known Limitations: ;;
;; ~~~~~~~~~~~~~~~~~~ ;;
;; - Works only on the 1st MBR partition which must be a PRI DOS partition ;;
;; with FAT12 (File System ID: 1) ;;
;; ;;
;; ;;
;; Known Bugs: ;;
;; ~~~~~~~~~~~ ;;
;; - All bugs are fixed as far as I know. The boot sector has been tested ;;
;; on the following types of diskettes: ;;
;; - 360KB 5"25 ;;
;; - 1.2MB 5"25 ;;
;; - 1.44MB 3"5 ;;
;; ;;
;; ;;
;; Memory Layout: ;;
;; ~~~~~~~~~~~~~~ ;;
;; The diagram below shows the typical memory layout. The actual location ;;
;; of the boot sector and its stack may be lower than A0000H if the BIOS ;;
;; reserves memory for its Extended BIOS Data Area just below A0000H and ;;
;; reports less than 640 KB of RAM via its Int 12H function. ;;
;; ;;
;; physical address ;;
;; +------------------------+ 00000H ;;
;; | Interrupt Vector Table | ;;
;; +------------------------+ 00400H ;;
;; | BIOS Data Area | ;;
;; +------------------------+ 00500H ;;
;; | PrtScr Status / Unused | ;;
;; +------------------------+ 00600H ;;
;; | Loaded Image | ;;
;; +------------------------+ nnnnnH ;;
;; | Available Memory | ;;
;; +------------------------+ A0000H - 512 - 2KB ;;
;; | 2KB Boot Stack | ;;
;; +------------------------+ A0000H - 512 ;;
;; | Boot Sector | ;;
;; +------------------------+ A0000H ;;
;; | Video RAM | ;;
;; ;;
;; ;;
;; Boot Image Startup (register values): ;;
;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;;
;; dl = BIOS boot drive number (e.g. 0, 80H) ;;
;; cs:ip = program entry point ;;
;; ss:sp = program stack (don't confuse with boot sector's stack) ;;
;; COM program defaults: cs = ds = es = ss = 50h, sp = 0, ip = 100h ;;
;; EXE program defaults: ds = es = 50h, other stuff depends on EXE header ;;
;; Magic numbers: ;;
;; si = 16381 (prime number 2**14-3) ;;
;; di = 32749 (prime number 2**15-19) ;;
;; bp = 65521 (prime number 2**16-15) ;;
;; The magic numbers let the program know whether it has been loaded by ;;
;; this boot sector or by MS-DOS, which may be handy for universal, bare- ;;
;; metal and MS-DOS programs. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[BITS 16]
;;? equ 0
ImageLoadSeg equ 60h ; <=07Fh because of "push byte ImageLoadSeg" instructions
[SECTION .text]
[ORG 0]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Boot sector starts here ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jmp short start ; MS-DOS/Windows checks for this jump
nop
bsOemName DB "BootProg" ; 0x03
;;;;;;;;;;;;;;;;;;;;;
;; BPB starts here ;;
;;;;;;;;;;;;;;;;;;;;;
bpbBytesPerSector DW 512 ; 0x0B
bpbSectorsPerCluster DB 1 ; 0x0D
bpbReservedSectors DW 1 ; 0x0E
bpbNumberOfFATs DB 2 ; 0x10
bpbRootEntries DW 224 ; 0x11
bpbTotalSectors DW 2880 ; 0x13
bpbMedia DB 0F0h ; 0x15
bpbSectorsPerFAT DW 9 ; 0x16
bpbSectorsPerTrack DW 18 ; 0x18
bpbHeadsPerCylinder DW 2 ; 0x1A
bpbHiddenSectors DD 0 ; 0x1C
bpbTotalSectorsBig DD 0 ; 0x20
;;;;;;;;;;;;;;;;;;;
;; BPB ends here ;;
;;;;;;;;;;;;;;;;;;;
bsDriveNumber DB 0 ; 0x24
bsUnused DB 0 ; 0x25
bsExtBootSignature DB 29H ; 0x26
bsSerialNumber DD 11223344h ; 0x27
bsVolumeLabel DB "NO NAME " ; 0x2B
bsFileSystem DB "FAT12 " ; 0x36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Boot sector code starts here ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
cld
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; How much RAM is there? ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
int 12h ; get conventional memory size (in KBs)
shl ax, 6 ; and convert it to 16-byte paragraphs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reserve memory for the boot sector and its stack ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub ax, 512 / 16 ; reserve 512 bytes for the boot sector code
mov es, ax ; es:0 -> top - 512
sub ax, 2048 / 16 ; reserve 2048 bytes for the stack
mov ss, ax ; ss:0 -> top - 512 - 2048
mov sp, 2048 ; 2048 bytes for the stack
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Copy ourselves to top of memory ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov cx, 256
mov si, 7C00h
xor di, di
mov ds, di
rep movsw
;;;;;;;;;;;;;;;;;;;;;;
;; Jump to the copy ;;
;;;;;;;;;;;;;;;;;;;;;;
push es
push byte main
retf
main:
push cs
pop ds
mov [bsDriveNumber], dl ; store BIOS boot drive number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reserve memory for the FAT12 image (6KB max) ;;
;; and load it in its entirety ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax, [bpbBytesPerSector]
shr ax, 4 ; ax = sector size in paragraphs
mov cx, [bpbSectorsPerFAT] ; cx = FAT size in sectors
mul cx ; ax = FAT size in paragraphs
mov di, ss
sub di, ax
mov es, di
xor bx, bx ; es:bx -> buffer for the FAT
mov ax, [bpbHiddenSectors]
mov dx, [bpbHiddenSectors+2]
add ax, [bpbReservedSectors]
adc dx, bx ; dx:ax = LBA
call ReadSector
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reserve memory for the root directory ;;
;; and load it in its entirety ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov bx, ax
mov di, dx ; save LBA to di:bx
mov ax, 32
mov si, [bpbRootEntries]
mul si
div word [bpbBytesPerSector]
mov cx, ax ; cx = root directory size in sectors
mov al, [bpbNumberOfFATs]
cbw
mul word [bpbSectorsPerFAT]
add ax, bx
adc dx, di ; dx:ax = LBA
push es ; push FAT segment (2nd parameter)
push byte ImageLoadSeg
pop es
xor bx, bx ; es:bx -> buffer for root directory
call ReadSector
add ax, cx
adc dx, bx ; adjust LBA for cluster data
push dx
push ax ; push LBA for data (1st parameter)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Look for the COM/EXE file to load and run ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov di, bx ; es:di -> root entries array
mov dx, si ; dx = number of root entries
mov si, ProgramName ; ds:si -> program name
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Looks for a file/dir by its name ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Input: DS:SI -> file name (11 chars) ;;
;; ES:DI -> root directory array ;;
;; DX = number of root entries ;;
;; Output: SI = cluster number ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FindName:
mov cx, 11
FindNameCycle:
cmp byte [es:di], ch
je FindNameFailed ; end of root directory
pusha
repe cmpsb
popa
je FindNameFound
add di, 32
dec dx
jnz FindNameCycle ; next root entry
FindNameFailed:
jmp ErrFind
FindNameFound:
mov si, [es:di+1Ah] ; si = cluster no.
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load the entire file ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadNextCluster:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reads a FAT12 cluster ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Inout: ES:BX -> buffer ;;
;; SI = cluster no ;;
;; Output: SI = next cluster ;;
;; ES:BX -> next addr ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadCluster:
mov bp, sp
lea ax, [si-2]
xor ch, ch
mov cl, [bpbSectorsPerCluster]
; cx = sector count
mul cx
add ax, [bp]
adc dx, [bp+1*2]
; dx:ax = LBA
call ReadSector
mov ax, [bpbBytesPerSector]
shr ax, 4 ; ax = paragraphs per sector
mul cx ; ax = paragraphs read
mov cx, es
add cx, ax
mov es, cx ; es:bx updated
mov ax, 3
mul si
shr ax, 1
xchg ax, si ; si = cluster * 3 / 2
push ds
mov ds, [bp+2*2] ; ds = FAT segment
mov si, [si] ; si = next cluster
pop ds
jnc ReadClusterEven
shr si, 4
ReadClusterEven:
and si, 0FFFh ; mask cluster value
ReadClusterDone:
cmp si, 0FF8h
jc ReadNextCluster ; if not End Of File
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Type detection, .COM or .EXE? ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push byte ImageLoadSeg
pop ds
mov ax, ds ; ax=ds=seg the file is loaded to
cmp word [0], 5A4Dh ; "MZ" signature?
je RelocateEXE ; yes, it's an EXE program
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Setup and run a .COM program ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub ax, 10h ; "org 100h" stuff :)
mov es, ax
mov ds, ax
mov ss, ax
xor sp, sp
push es
push word 100h
jmp short Run
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Relocate, setup and run a .EXE program ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RelocateEXE:
add ax, [08h] ; ax = image base
mov cx, [06h] ; cx = reloc items
mov bx, [18h] ; bx = reloc table pointer
jcxz RelocationDone
ReloCycle:
mov di, [bx] ; di = item ofs
mov dx, [bx+2] ; dx = item seg (rel)
add dx, ax ; dx = item seg (abs)
push ds
mov ds, dx ; ds = dx
add [di], ax ; fixup
pop ds
add bx, 4 ; point to next entry
loop ReloCycle
RelocationDone:
mov bx, ax
add bx, [0Eh]
mov ss, bx ; ss for EXE
mov sp, [10h] ; sp for EXE
add ax, [16h] ; cs
push ax
push word [14h] ; ip
Run:
mov dl, [cs:bsDriveNumber] ; pass the BIOS boot drive
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set the magic numbers so the program knows that it ;;
;; has been loaded by this bootsector and not by MS-DOS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov si, 16381 ; prime number 2**14-3
mov di, 32749 ; prime number 2**15-19
mov bp, 65521 ; prime number 2**16-15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; All done, transfer control to the program now ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
retf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reads a sector using BIOS Int 13h fn 2 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Input: DX:AX = LBA ;;
;; CX = sector count ;;
;; ES:BX -> buffer address ;;
;; Output: CF = 1 if error ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadSector:
pusha
ReadSectorNext:
mov di, 5 ; attempts to read
ReadSectorRetry:
pusha
div word [bpbSectorsPerTrack]
; ax = LBA / SPT
; dx = LBA % SPT = sector - 1
mov cx, dx
inc cx
; cx = sector no.
xor dx, dx
div word [bpbHeadsPerCylinder]
; ax = (LBA / SPT) / HPC = cylinder
; dx = (LBA / SPT) % HPC = head
mov ch, al
; ch = LSB 0...7 of cylinder no.
shl ah, 6
or cl, ah
; cl = MSB 8...9 of cylinder no. + sector no.
mov dh, dl
; dh = head no.
mov dl, [bsDriveNumber]
; dl = drive no.
mov ax, 201h
; al = sector count = 1
; ah = 2 = read function no.
int 13h ; read sectors
jnc ReadSectorDone ; CF = 0 if no error
xor ah, ah ; ah = 0 = reset function
int 13h ; reset drive
popa
dec di
jnz ReadSectorRetry ; extra attempt
jmp short ErrRead
ReadSectorDone:
popa
dec cx
jz ReadSectorDone2 ; last sector
add bx, [bpbBytesPerSector] ; adjust offset for next sector
add ax, 1
adc dx, 0 ; adjust LBA for next sector
jmp short ReadSectorNext
ReadSectorDone2:
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Error Messaging Code ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
ErrRead:
mov si, MsgErrRead
jmp short Error
ErrFind:
mov si, MsgErrFind
Error:
mov ah, 0Eh
mov bx, 7
lodsb
int 10h ; 1st char
lodsb
int 10h ; 2nd char
xor ah, ah
int 16h ; wait for a key...
mov dl, [bsDriveNumber] ; restore BIOS boot drive number
int 19h ; bootstrap
;;;;;;;;;;;;;;;;;;;;;;
;; String constants ;;
;;;;;;;;;;;;;;;;;;;;;;
MsgErrRead db "RE"
MsgErrFind db "NF"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Fill free space with zeroes ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times (512-13-($-$$)) db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Name of the file to load and run ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ProgramName db "FORTH COM" ; name and extension each must be
; padded with spaces (11 bytes total)
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; End of the sector ID ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
dw 0AA55h ; BIOS checks for this ID

Binary file not shown.

View File

@ -0,0 +1,26 @@
Copyright (c) 2000-2015, Alexey Frunze
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.

Binary file not shown.

View File

@ -0,0 +1,612 @@
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
typedef unsigned char uchar, uint8;
typedef unsigned short uint16;
#ifndef __SMALLER_C__
#if UINT_MAX >= 0xFFFFFFFF
typedef unsigned uint32;
#else
typedef unsigned long uint32;
#endif
#else
typedef unsigned long uint32;
#endif
typedef unsigned uint;
typedef unsigned long ulong;
#ifndef __SMALLER_C__
#define C_ASSERT(expr) extern char CAssertExtern[(expr)?1:-1]
C_ASSERT(CHAR_BIT == 8);
C_ASSERT(sizeof(uint16) == 2);
C_ASSERT(sizeof(uint32) == 4);
#endif
#pragma pack (push, 1)
typedef struct tFATBPB1
{
uint16 BytesPerSector;
uint8 SectorsPerCluster;
uint16 ReservedSectorsCount;
uint8 NumberOfFATs;
uint16 RootEntriesCount;
uint16 TotalSectorsCount16;
uint8 MediaType;
uint16 SectorsPerFAT1x;
uint16 SectorsPerTrack;
uint16 HeadsPerCylinder;
uint32 HiddenSectorsCount;
uint32 TotalSectorsCount32;
} tFATBPB1;
typedef union tFATBPB2
{
struct
{
uint8 DriveNumber;
uint8 reserved1;
uint8 ExtendedBootSignature;
uint32 VolumeSerialNumber;
char VolumeLabel[11];
char FileSystemName[8];
uchar aBootCode1x[0x1C];
} FAT1x;
struct
{
uint32 SectorsPerFAT32;
uint16 ExtendedFlags;
uint16 FSVersion;
uint32 RootDirectoryClusterNo;
uint16 FSInfoSectorNo;
uint16 BackupBootSectorNo;
uint8 reserved[12];
uint8 DriveNumber;
uint8 reserved1;
uint8 ExtendedBootSignature;
uint32 VolumeSerialNumber;
char VolumeLabel[11];
char FileSystemName[8];
} FAT32;
} tFATBPB2;
typedef struct tFATBPB
{
tFATBPB1 BPB1;
tFATBPB2 BPB2;
} tFATBPB;
typedef struct tFATBootSector
{
uchar aJump[3];
char OEMName[8];
tFATBPB BPB;
uchar aBootCode32[0x1A4];
uint16 Signature0xAA55;
} tFATBootSector;
typedef enum tFATDirEntryAttribute
{
dea_READ_ONLY = 0x01,
dea_HIDDEN = 0x02,
dea_SYSTEM = 0x04,
dea_VOLUME_ID = 0x08,
dea_DIRECTORY = 0x10,
dea_ARCHIVE = 0x20,
dea_LONG_NAME = dea_READ_ONLY|dea_HIDDEN|dea_SYSTEM|dea_VOLUME_ID
} tFATDirEntryAttribute;
typedef struct tFATDirectoryEntry
{
char Name[8];
char Extension[3];
uint8 Attribute;
uint8 WinNTreserved;
uint8 CreationTimeSecTenths;
uint16 CreationTime2Secs;
uint16 CreationDate;
uint16 LastAccessDate;
uint16 FirstClusterHiWord;
uint16 LastWriteTime;
uint16 LastWriteDate;
uint16 FirstClusterLoWord;
uint32 Size;
} tFATDirectoryEntry;
#define DELETED_DIR_ENTRY_MARKER 0xE5
#pragma pack (pop)
#ifndef __SMALLER_C_32__
C_ASSERT(sizeof(tFATBootSector) == 512);
C_ASSERT(sizeof(tFATDirectoryEntry) == 32);
#endif
#define FBUF_SIZE 1024
char* BootSectName;
char* OutName = "floppy.img";
int UniqueSerial;
FILE* fout;
tFATBootSector BootSector;
uint32 Fat1Lba;
uint32 SectorsPerFat;
uint32 Fats;
uint32 RootDirLba;
uint32 DirEntriesPerSector;
uint32 RootDirEntries;
uint32 RootDirSectors;
uint32 Cluster2Lba;
uint32 SectorsPerCluster;
uint32 ClusterSize;
uint32 DataSectors;
uint32 Clusters;
uint8 FatSector[512];
uint32 Cluster;
tFATDirectoryEntry RootDirSector[512 / sizeof(tFATDirectoryEntry)];
uint32 RootDirEntryIdx;
void error(char* format, ...)
{
#ifndef __SMALLER_C__
va_list vl;
va_start(vl, format);
#else
void* vl = &format + 1;
#endif
if (fout)
fclose(fout);
remove(OutName);
puts("");
vprintf(format, vl);
#ifndef __SMALLER_C__
va_end(vl);
#endif
exit(EXIT_FAILURE);
}
FILE* Fopen(const char* filename, const char* mode)
{
FILE* stream = fopen(filename, mode);
if (!stream)
error("Can't open/create file \"%s\"\n", filename);
return stream;
}
void Fclose(FILE* stream)
{
if (fclose(stream))
error("Can't close a file\n");
}
void Fseek(FILE* stream, long offset, int whence)
{
int r = fseek(stream, offset, whence);
if (r)
error("Can't seek a file\n");
}
void Fread(void* ptr, size_t size, FILE* stream)
{
size_t r = fread(ptr, 1, size, stream);
if (r != size)
error("Can't read a file\n");
}
void Fwrite(const void* ptr, size_t size, FILE* stream)
{
size_t r = fwrite(ptr, 1, size, stream);
if (r != size)
error("Can't write a file\n");
}
void FillWithByte(unsigned char byte, unsigned long size, FILE* stream)
{
static unsigned char buf[FBUF_SIZE];
memset(buf, byte, FBUF_SIZE);
while (size)
{
unsigned long csz = size;
if (csz > FBUF_SIZE)
csz = FBUF_SIZE;
Fwrite(buf, csz, stream);
size -= csz;
}
}
// Determines binary file size portably (when stat()/fstat() aren't available)
long fsize(FILE* binaryStream)
{
long ofs, ofs2;
int result;
if (fseek(binaryStream, 0, SEEK_SET) != 0 ||
fgetc(binaryStream) == EOF)
return 0;
ofs = 1;
while ((result = fseek(binaryStream, ofs, SEEK_SET)) == 0 &&
(result = (fgetc(binaryStream) == EOF)) == 0 &&
ofs <= LONG_MAX / 4 + 1)
ofs *= 2;
// If the last seek failed, back up to the last successfully seekable offset
if (result != 0)
ofs /= 2;
for (ofs2 = ofs / 2; ofs2 != 0; ofs2 /= 2)
if (fseek(binaryStream, ofs + ofs2, SEEK_SET) == 0 &&
fgetc(binaryStream) != EOF)
ofs += ofs2;
// Return -1 for files longer than LONG_MAX
if (ofs == LONG_MAX)
return -1;
return ofs + 1;
}
void FlushFatSector(void)
{
uint32 ofs = (Cluster * 3 / 2) & 511;
uint32 i;
if (ofs == 0 && (Cluster & 1) == 0)
return;
for (i = 0; i < Fats; i++)
{
uint32 ofs = Fat1Lba + i * SectorsPerFat;
ofs += (Cluster * 3 / 2) / 512;
Fseek(fout, ofs * 512, SEEK_SET);
Fwrite(FatSector, sizeof FatSector, fout);
}
memset(FatSector, 0, sizeof FatSector);
}
void ChainCluster(uint32 nextCluster)
{
uint32 ofs = (Cluster * 3 / 2) & 511;
if (Cluster & 1)
FatSector[ofs] |= nextCluster << 4;
else
FatSector[ofs] = nextCluster;
if (ofs == 511)
FlushFatSector();
ofs = (ofs + 1) & 511;
if (Cluster & 1)
FatSector[ofs] = nextCluster >> 4;
else
FatSector[ofs] = (nextCluster >> 8) & 0xF;
if (ofs == 511 && (Cluster & 1))
FlushFatSector();
Cluster++;
}
void FlushRootDirSector(void)
{
uint32 ofs;
if (RootDirEntryIdx % DirEntriesPerSector == 0)
return;
ofs = RootDirLba + RootDirEntryIdx / DirEntriesPerSector;
Fseek(fout, ofs * 512, SEEK_SET);
Fwrite(RootDirSector, sizeof RootDirSector, fout);
}
void AddRootDirEntry(tFATDirectoryEntry* de)
{
RootDirSector[RootDirEntryIdx % DirEntriesPerSector] = *de;
if ((RootDirEntryIdx + 1) % DirEntriesPerSector == 0)
FlushRootDirSector();
RootDirEntryIdx++;
}
void Init(void)
{
if (BootSectName)
{
FILE* fsect = Fopen(BootSectName, "rb");
Fread(&BootSector, sizeof BootSector, fsect);
Fclose(fsect);
}
else
{
memcpy(BootSector.OEMName, "BootProg", 8);
memcpy(BootSector.BPB.BPB2.FAT1x.VolumeLabel, "NO NAME ", 11);
memcpy(BootSector.BPB.BPB2.FAT1x.FileSystemName, "FAT12 ", 8);
BootSector.aJump[0] = 0xEB; // jmp short $+0x3E
BootSector.aJump[1] = 0x3C;
BootSector.aJump[2] = 0x90; // nop
// TBD??? replace the below with code to print an error message like "Not a system/bootable disk"?
BootSector.BPB.BPB2.FAT1x.aBootCode1x[0] = 0xF4; // hlt
BootSector.BPB.BPB2.FAT1x.aBootCode1x[1] = 0xEB; // jmp short $-1
BootSector.BPB.BPB2.FAT1x.aBootCode1x[2] = 0xFD;
}
fout = Fopen(OutName, "wb");
BootSector.BPB.BPB1.BytesPerSector = 512; // note, we're normally assuming 512 bytes per sector everywhere
BootSector.BPB.BPB1.SectorsPerCluster = 1;
BootSector.BPB.BPB1.ReservedSectorsCount = 1; // includes the boot sector
BootSector.BPB.BPB1.NumberOfFATs = 2;
BootSector.BPB.BPB1.RootEntriesCount = 224; // must be a multiple of 16 (16 32-byte entries in 512-byte sector)
BootSector.BPB.BPB1.TotalSectorsCount16 = 2880;
BootSector.BPB.BPB1.MediaType = 0xF0;
BootSector.BPB.BPB1.SectorsPerFAT1x = 9;
BootSector.BPB.BPB1.SectorsPerTrack = 18;
BootSector.BPB.BPB1.HeadsPerCylinder = 2;
BootSector.BPB.BPB1.HiddenSectorsCount = 0;
BootSector.BPB.BPB1.TotalSectorsCount32 = 0;
BootSector.BPB.BPB2.FAT1x.DriveNumber = 0;
BootSector.BPB.BPB2.FAT1x.reserved1 = 0;
BootSector.BPB.BPB2.FAT1x.ExtendedBootSignature = 0x29;
BootSector.BPB.BPB2.FAT1x.VolumeSerialNumber = 0x11223344;
if (UniqueSerial)
BootSector.BPB.BPB2.FAT1x.VolumeSerialNumber = time(NULL);
BootSector.Signature0xAA55 = 0xAA55;
// Write the boot sector
Fwrite(&BootSector, sizeof BootSector, fout);
// Zero out the rest of the image
FillWithByte(0, (BootSector.BPB.BPB1.TotalSectorsCount16 - 1) * 512UL, fout);
// FAT12's first two entries need special initialization
ChainCluster(0xF00 | BootSector.BPB.BPB1.MediaType);
ChainCluster(0xFFF);
// Helper variables
Fat1Lba = BootSector.BPB.BPB1.ReservedSectorsCount;
SectorsPerFat = BootSector.BPB.BPB1.SectorsPerFAT1x;
Fats = BootSector.BPB.BPB1.NumberOfFATs;
RootDirLba = Fat1Lba + SectorsPerFat * Fats;
DirEntriesPerSector = 512 / sizeof(tFATDirectoryEntry);
RootDirEntries = BootSector.BPB.BPB1.RootEntriesCount;
RootDirSectors = (RootDirEntries * sizeof(tFATDirectoryEntry) + 511) / 512;
Cluster2Lba = RootDirLba + RootDirSectors;
SectorsPerCluster = BootSector.BPB.BPB1.SectorsPerCluster;
ClusterSize = SectorsPerCluster * 512;
DataSectors = BootSector.BPB.BPB1.TotalSectorsCount16 -
BootSector.BPB.BPB1.ReservedSectorsCount - SectorsPerFat * Fats - RootDirSectors;
Clusters = DataSectors / SectorsPerCluster;
}
void Done(void)
{
FlushFatSector();
FlushRootDirSector();
Fclose(fout);
}
void NameTo8Dot3Name(const char* in, char out[8 + 3])
{
static const char aInvalid8Dot3NameChars[] = "\"*+,./:;<=>?[\\]|";
int i, j;
int namelen = 0, dots = 0, extlen = 0;
memset(out, ' ', 8 + 3);
if (*in == '\0' || *in == '.')
goto lerr;
for (j = i = 0; in[i]; i++)
{
int c = (unsigned char)in[i];
if (i >= 12) // at most 12 input chars can fit into an 8.3 name
goto lerr;
if (i == 0 && c == 0xE5)
{
// 0xE5 in the first character of the name is a marker for deleted files,
// it needs to be translated to 0x05
c = 0x05;
}
else if (c == '.')
{
if (dots++) // at most one dot allowed
goto lerr;
j = 8; // now writing extension
continue;
}
if (c <= 0x20 || strchr(aInvalid8Dot3NameChars, c) != NULL)
goto lerr;
if (dots)
{
if (++extlen > 3) // at most 3 chars in extension
goto lerr;
}
else
{
if (++namelen > 8) // at most 8 chars in name
goto lerr;
}
if (c >= 'a' && c <= 'z')
c -= 'a' - 'A';
out[j++] = c;
}
// TBD??? error out on the following reserved names: "COM1"-"COM9", "CON", "LPT1"-"LPT9", "NUL", "PRN"?
return;
lerr:
error("Can't convert \"%s\" to an 8.3 DOS name\n", in);
}
void AddFile(char* fname)
{
char* pslash = strrchr(fname, '/');
char* pbackslash = strrchr(fname, '\\');
char* pname;
char name8_3[8 + 3];
FILE* f;
long size;
tFATDirectoryEntry de;
uint32 ofs;
// First, find where the path ends in the file name, if any
// In DOS/Windows paths can contain either '\\' or '/' as a separator between directories,
// choose the right-most
if (pslash && pbackslash)
{
if (pslash < pbackslash)
pslash = pbackslash;
}
else if (!pslash)
{
pslash = pbackslash;
}
// If there's no slash, it could be "c:file"
if (!pslash && ((*fname >= 'A' && *fname <= 'Z') || (*fname >= 'a' && *fname <= 'z')) && fname[1] == ':')
pslash = fname + 1;
pname = pslash ? pslash + 1 : fname;
// Convert the name to 8.3
NameTo8Dot3Name(pname, name8_3);
// TBD!!! error out on duplicate files/names
// Copy the file
f = Fopen(fname, "rb");
// Prepare the directory entry
memset(&de, 0, sizeof de);
memcpy(de.Name, name8_3, 8 + 3);
de.Attribute = dea_ARCHIVE;
de.Size = size = fsize(f);
if (RootDirEntryIdx >= RootDirEntries ||
size < 0 || (unsigned long)size > Clusters * ClusterSize)
error("No space for file \"%s\"", fname);
if (size)
{
de.FirstClusterLoWord = Cluster;
de.FirstClusterHiWord = Cluster >> 16;
}
// TBD??? set file date/time to now?
de.LastWriteDate = ((1990 - 1980) << 9) | (1 << 5) | 1; // 1990/01/01
de.LastWriteTime = (12 << 11) | (0 << 5) | (0 >> 1); // 12(PM):00:00
// Seek both files
Fseek(f, 0, SEEK_SET);
ofs = Cluster2Lba + (Cluster - 2) * SectorsPerCluster;
Fseek(fout, ofs * 512, SEEK_SET);
// Copy data sectors
while (size)
{
uint8 sector[512];
long sz = (size > 512) ? 512 : size;
memset(sector, 0, 512); // pad with zeroes the last partial sector
Fread(sector, sz, f);
Fwrite(sector, 512, fout);
size -= sz;
}
// Allocate and chain clusters in the FAT
size = de.Size;
while (size)
{
if (size > (long)ClusterSize)
{
// There's at least one more cluster in the chain
ChainCluster(Cluster + 1);
size -= ClusterSize;
}
else
{
// No more clusters, this is the last one in the chain
ChainCluster(0xFF8);
size = 0;
}
Clusters--;
}
// Write the directory entry
AddRootDirEntry(&de);
Fclose(f);
}
int main(int argc, char* argv[])
{
int i;
for (i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "-o"))
{
if (i + 1 < argc)
{
argv[i++] = NULL;
OutName = argv[i];
argv[i] = NULL;
continue;
}
}
else if (!strcmp(argv[i], "-bs"))
{
if (i + 1 < argc)
{
argv[i++] = NULL;
BootSectName = argv[i];
argv[i] = NULL;
continue;
}
}
else if (!strcmp(argv[i], "-us"))
{
UniqueSerial = 1;
argv[i++] = NULL;
continue;
}
if (argv[i][0] == '-')
error("Invalid or unsupported command line option\n");
}
Init();
for (i = 1; i < argc; i++)
if (argv[i])
AddFile(argv[i]);
Done();
return 0;
}

View File

@ -0,0 +1,139 @@
The "BootProg" Boot Sector
What is BootProg?
BootProg is a collection of 512-byte boot sectors (for the x86 PC) capable of
loading and executing a program from a FAT12-formatted floppy or a FAT16/32-
formatted hard disk (bootable USB sticks and CDs can also be made with
BootProg).
BootProg understands programs in the MS-DOS .COM or .EXE format. This makes
it possible to use existing 16-bit compilers such as Borland/Turbo C/C++,
Sybase/Open Watcom C/C++ and Smaller C and a variety of assemblers such as
NASM, FASM, TASM and MASM among the others.
BootProg doesn't require that the program occupy a contiguous span of sectors
or FAT clusters or reside at a specific fixed location on the disk. BootProg
faithfully parses the root directory and the chain of FAT clusters in order to
locate the program contents. The only requirement is that the program be named
"STARTUP.BIN" (without quotes). This makes updating the program easy. You just
need to update the file and you can reboot and execute it immediately.
What can BootProg be used for?
You can make a boot loader for your OS. The program that BootProg loads can be
your 2nd stage boot loader. Or, if your OS is relatively small, STARTUP.BIN
could contain the entire OS.
You can write low-level utilities to work with your PC's hardware and load them
with BootProg without having to jump through the hoops with your Windows, Linux
or even DOS.
You can make cool graphics demos or games that run on bare hardware.
What can't BootProg be used for?
Many things. Most importantly, if you make a DOS program that uses any MS-DOS
service functions (e.g. int 21h) or data structures, it will not work when
loaded by BootProg. It must use either BIOS services (e.g. int 10h, int 16h,
int 13h and such) or access hardware directly or both.
However, it is possible to create universal/hybrid programs that would work
both in DOS and when loaded by BootProg. BootProg will set registers si, di and
bp to the values 16381, 32749 and 65521 respectively before transferring control
to your program. Your program can then check the values in these registers and
use DOS services in DOS or something else instead on bare hardware. You can also
choose to make the program run with reduced functionality if not on DOS or
vice versa.
How does it work?
Nothing special. It just finds STARTUP.BIN, loads it, performs any relocations
necessary for the .EXE type of programs, sets the magic numbers 16381, 32749
and 65521 in registers si, di and bp respectively and passes control to your
program.
If BootProg can't find STARTUP.BIN, it will print "NF" to the screen. If it
fails to load the file due to a read error, it will print "RE". This is how the
FAT12 and FAT16 versions of BootProg work. The FAT32 version has much less space
for these errors and so in both above cases it will simply print "E".
How do I put BootProg on my disk?
If you have a 1.44MB 3"5 floppy, just format it regularly with FAT12 in DOS or
Windows and then write flp144.bin to the very first sector of the floppy with
whatever tools you find/have for that. After that you can copy STARTUP.BIN to
the floppy and off you go.
If you want to create an image of a 1.44MB 3"5 floppy, it might be even easier.
Compile the mkimg144.c program contained here with your favorite C compiler
and use it:
mkimg144 [option(s)] [file(s)]
Options:
-bs <file> Specifies the boot sector to use, e.g. "-bs flp144.bin"
-o <file> Specifies the name of the output file ("floppy.img" is the
default, if this option isn't specified)
-us Uses the current time to set the volume ID of the FAT to a unique
value (the volume ID is used to distinguish between different
removable disks and detect disk change more accurately)
E.g: "mkimg144 -bs flp144.bin -o flp144.img -us startup.bin".
Btw, you can rename the supplied file "demo1.com" to "startup.bin" to try it
out.
For all other cases you'll need to become a little more familiar with FAT and
a little more intimate with disk tools and BootProg's source code.
You will need to populate the BPB's of boot16.asm and boot32.asm with the
values appropriate to the type and size of the file system that you already have
on a disk or that you intend to create on the disk.
See the source code, these places are marked with question marks, for example:
bpbBytesPerSector DW ? ; 0x0B
The best is to format your disk with some standard tools (e.g. FORMAT.COM in
DOS), extract the BPB values from the FAT-formatted disk, put them into BootProg
and then write thusly adjusted BootProg over the original boot sector.
You may find a disk editor handy when manipulating BPB values and/or
reading/writing boot sectors.
Limitations and implementation details
boot12.asm (flp144.asm) and boot16.asm require an i80186/i80188/i80286 or a
better CPU. boot32.asm naturally requires an i80386 or a better CPU.
boot12.asm (flp144.asm) was not tested on hard disks (but it might work as the
boot sector on FAT12 primary partitions (file system ID 1)).
boot16.asm was written for and tested on primary FAT16 partitions (file system
IDs 4 and 6). Its expected use is the boot sector of the partition and not the
MBR. The FAT16 version may allocate up to 128KB of RAM for the entire FAT16,
leaving less room for STARTUP.BIN. But ~400KB left should still be plenty of
space for its code, data and stack.
boot32.asm was written for and tested on primary FAT32 partitions (file system
IDs 0Bh and 0Ch) and for BIOSes supporting function 42h of int 13h (IOW, for
systems supporting HDDs larger than 8GB). Its expected use is the boot sector
of the partition and not the MBR.
BootProg does not check the size of STARTUP.BIN and reads into memory all of its
clusters, which means that up to 32767 extra bytes may be read from the disk
and written to the memory after the last byte of STARTUP.BIN (max cluster size
is 32KB). It also means that you may append data to your program and it will be
loaded. You may create oversized .COM-style STARTUP.BIN larger than ~64KB,
however, note that the stack will naturally overwrite its contents from offset
65535 of the program segment (offset 65279 of the file) downwards.
If your PC has the full 640KB of conventional/DOS memory, you should be able to
load program files of size of up to ~400KB.

1607
8086/pc-baremetal/kernel.fth Normal file

File diff suppressed because it is too large Load Diff

545
8086/pc-baremetal/meta.fth Normal file
View File

@ -0,0 +1,545 @@
( ----- 001 )
\ Target compiler loadscr ks cas 09jun20
Onlyforth \needs Assembler 2 loadfrom asm.fb
: c+! ( 8b addr -- ) dup c@ rot + swap c! ;
' find $22 + @ Alias found
: search ( string 'vocab -- acf n / string ff )
dup @ [ ' Forth @ ] Literal - Abort" no vocabulary"
>body (find IF found exit THEN false ;
3 &27 thru Onlyforth savesystem meta.com
cr .( Metacompiler saved as META.COM )
( ----- 002 )
\ Predefinitions loadscreen ks 30 apr 88
&28 load
cr .( Predefinitions geladen ...) cr
( ----- 003 )
\ Target header pointers ks 29 jun 87
Variable tfile tfile off \ handle of target file
Variable tdp tdp off \ target dp
Variable displace displace off \ diplacement of code
Variable ?thead ?thead off \ for headerless code
Variable tlast tlast off \ last name in target
Variable glast' glast' off \ acf of latest ghost
Variable tdoes> tdoes> off \ code addr of last does
Variable tdodo tdodo off \ location of dodo
Variable >in: >in: off \ last :-def
Variable tvoc tvoc off \
Variable tvoc-link tvoc-link off \ voc-link in target
Variable tnext-link tnext-link off \ link for tracer
( ----- 004 )
\ Target header pointers ks 10 okt 87
: there ( -- taddr ) tdp @ ;
: new pushfile makefile isfile@ tfile !
tvoc-link off tnext-link off
$100 tdp ! $100 displace ! ;
( ----- 005 )
\ Ghost-creating ks 07 dez 87
0 | Constant <forw> 0 | Constant <res>
| Create gname $21 allot
| : >heap ( from quan -- ) \ heap over - 1 and + \ align
dup hallot heap swap cmove ;
: symbolic ( string -- cfa.ghost )
count dup 1 $1F uwithin not Abort" invalid Gname"
gname place BL gname append align here >r makeview ,
state @ IF context ELSE current THEN @ @ dup @ ,
gname count under here place 1+ allot align
here r@ - <forw> , 0 , 0 , r@ here over - >heap
heap 2+ rot ! r> dp ! heap + ;
( ----- 006 )
\ ghost words ks 07 dez 87
: gfind ( string -- cfa tf / string ff )
>r 1 r@ c+! r@ find -1 r> c+! ;
: ghost ( -- cfa ) name gfind ?exit symbolic ;
: gdoes> ( cfa.ghost -- cfa.does )
4 + dup @ IF @ exit THEN
here <forw> , 0 , dup 4 >heap
dp ! heap swap ! heap ;
( ----- 007 )
\ ghost utilities ks 29 jun 87
: g' ( -- acf ) name gfind 0= Abort" ?T?" ;
: '. g' dup @ <forw> case?
IF ." forw" ELSE <res> - Abort" ??" ." res" THEN
2+ dup @ 5 u.r 2+ @ ?dup
IF dup @ <forw> case?
IF ." fdef" ELSE <res> - Abort" ??" ." rdef" THEN
2+ @ 5 u.r THEN ;
' ' Alias h'
( ----- 008 )
\ .unresolved ks 29 jun 87
| : forward? ( cfa -- cfa / exit&true )
dup @ <forw> = 0=exit dup 2+ @ 0=exit drop true rdrop ;
| : unresolved? ( addr -- f ) 2+
dup count $1F and + 1- c@ bl =
IF name> forward? 4+ @ dup IF forward? THEN
THEN drop false ;
| : unresolved-words ( thread -- )
BEGIN @ ?dup WHILE dup unresolved?
IF dup 2+ .name ?cr THEN REPEAT ;
: .unresolved voc-link @
BEGIN dup 4 - unresolved-words @ ?dup 0= UNTIL ;
( ----- 009 )
\ Extending Vocabularys for Target-Compilation ks 29 jun 87
Vocabulary Ttools
Vocabulary Defining
: Vocabulary Vocabulary 0 , here tvoc @ , tvoc ! ;
Vocabulary Transient tvoc off
Root definitions
: T Transient ; immediate
: H Forth ; immediate
: D Defining ; immediate
Forth definitions
( ----- 010 )
\ Image and byteorder ks 02 jul 87
| Code >byte ( 16b -- 8b- 8b+ ) A A xor
D- A- xchg D+ D- xchg A push Next end-code
| Code byte> ( 8b- 8b+ -- 16b )
A pop D- D+ mov A- D- xchg Next end-code
| : >target ( addr1 -- daddr fcb ) displace @ - 0 tfile @ ;
Transient definitions
: c@ ( addr -- 8b ) [ Dos ]
>target file@ dup 0< Abort" nie abgespeichert" ;
: c! ( 8b addr -- ) [ Dos ] >target file! ;
( ----- 011 )
\ Transient primitives ks 09 jul 87
: @ ( addr -- n ) H dup T c@ swap 1+ c@ byte> ;
: ! ( n addr -- ) H >r >byte r@ 1+ T c! r> c! H ;
: cmove ( from.mem to.target quan -- ) [ Dos ]
>r >target fseek ds@ swap r> tfile @ lfputs ;
\ bounds ?DO dup c@ I T c! H 1+ LOOP drop ;
: here ( -- taddr ) H tdp @ ;
: here! ( taddr -- ) H tdp ! ;
: allot ( n -- ) H tdp +! ;
: c, ( 8b -- ) T here c! 1 allot H ;
: , ( 16b -- ) T here ! 2 allot H ;
: align ( -- ) H ; immediate
: even ( addr1 -- addr2 ) H ; immediate
: halign H ; immediate
( ----- 012 )
\ Transient primitives ks 29 jun 87
: count ( addr1 -- addr2 len ) H dup 1+ swap T c@ H ;
: ," H here ," here over dp !
over - T here swap dup allot cmove H ;
: fill ( addr quan 8b -- ) H
-rot bounds ?DO dup I T c! H LOOP drop ;
: erase ( addr quan -- ) H 0 T fill H ;
: blank ( addr quan -- ) H bl T fill H ;
: move-threads H tvoc @ tvoc-link @
BEGIN over ?dup
WHILE 2- @ over 2- T ! @ H swap @ swap REPEAT
Error" some undef. Target-Vocs left" drop ;
( ----- 013 )
\ Resolving ks 29 jun 87
Forth definitions
: resolve ( cfa.ghost cfa.target -- ) over dup @ <res> =
IF space dup >name .name ." exists " ?cr
2+ ! drop exit THEN >r >r 2+ @ ?dup
IF BEGIN dup T @ H 2dup = Abort" resolve loop"
r@ rot T ! H ?dup 0= UNTIL
THEN r> r> <res> over ! 2+ ! ;
: resdoes> ( acf.ghost acf.target -- ) swap gdoes>
dup @ <res> = IF 2+ ! exit THEN swap resolve ;
here 2+ 0 ] Does> dup @ there rot ! T , H ; ' <forw> >body !
here 2+ 0 ] Does> @ T , H ; ' <res> >body !
( ----- 014 )
\ compiling names into targ. ks 10 okt 87
| : tlatest ( -- addr ) current @ 6 + ;
: (theader ?thead @ IF 1 ?thead +! exit THEN
>in @ bl word swap >in ! dup count upper
dup c@ 1 $20 uwithin not Abort" inval. Tname"
blk @ $8400 or T align , H
there tlatest @ T , H tlatest ! there tlast !
there over c@ 1+ dup T allot cmove align H ;
: theader tlast off
(theader ghost dup glast' ! there resolve ;
( ----- 015 )
\ prebuild defining words ks 29 jun 87
| : (prebuild >in @ Create >in !
r> dup 2+ >r @ here 2- ! ;
| : tpfa, there , ;
: prebuild ( addr check# -- check# ) 0 ?pairs
dup IF compile (prebuild dup , THEN
compile theader ghost gdoes> ,
IF compile tpfa, THEN 0 ; immediate
: dummy 0 ;
: DO> [compile] Does> here 3 - compile @ 0 ] ;
( ----- 016 )
\ Constructing defining words in Host kks 07 dez 87
| : defcomp ( string -- ) dup ['] Defining search ?dup
IF 0> IF nip execute exit THEN drop dup THEN
find ?dup IF 0< IF nip , exit THEN THEN
drop ['] Forth search ?dup
IF 0< IF , exit THEN execute exit THEN
number? ?dup 0= Abort" ?"
0> IF swap [compile] Literal THEN [compile] Literal ;
| : definter ( string -- ) dup ['] Defining search ?dup
IF 0< IF nip execute exit THEN THEN drop
find ?dup IF 1 and 0= Abort" compile only" execute exit
THEN number? 0= Error" ?" ;
( ----- 017 )
\ Constructing defining words in Host ks 22 dez 87
| : (;tcode r> @ tlast @ T count + ! H ;
Defining definitions
: ] H ] ['] defcomp Is parser ;
: [ H [compile] [ ['] definter Is parser ; immediate
: ; H [compile] ; [compile] \\ ; immediate
: Does> H compile (;tcode tdoes> @ ,
[compile] ; -2 allot [compile] \\ ; immediate
D ' Does> Alias ;Code immediate H
( ----- 018 )
\ reinterpreting defining words ks 22 dez 87
Forth definitions
: ?reinterpret ( f -- ) 0=exit
state @ >r >in @ >r adr parser @ >r
>in: @ >in ! : D ] H interpret
r> Is parser r> >in ! r> state ! ;
: undefined? ( -- f ) glast' @ 4+ @ 0= ;
| : flag! ( 8b -- ) tlast @ ?dup 0= IF drop exit THEN
dup T c@ rot or swap c! H ;
| : nfa? ( acf alf -- anf / acf ff )
BEGIN dup WHILE 2dup 2+ T count $1F and + even H =
IF 2+ nip exit THEN T @ H REPEAT ;
( ----- 019 )
\ the 8086 Assembler ks 29 jun 87
| Create relocate ] T c, , here ! c! H [
Transient definitions
: Assembler H [ Assembler ] relocate >codes ! Assembler ;
: >label ( 16b -- ) H >in @ name gfind rot >in !
IF over resolve dup THEN drop Constant ;
: Label T here >label Assembler H ;
: Code H theader T here 2+ , Assembler H ;
( ----- 020 )
( Transient primitives ks 17 dec 83 )
' exit Alias exit ' load Alias load
' / Alias / ' thru Alias thru
' swap Alias swap ' * Alias *
' dup Alias dup ' drop Alias drop
' /mod Alias /mod ' rot Alias rot
' -rot Alias -rot ' over Alias over
' 2* Alias 2* ' + Alias +
' - Alias - ' 1+ Alias 1+
' 2+ Alias 2+ ' 1- Alias 1-
' 2- Alias 2- ' negate Alias negate
' 2swap Alias 2swap ' 2dup Alias 2dup
( ----- 021 )
\ Transient primitives kks 29 jun 87
' also Alias also ' words Alias words
' definitions Alias definitions ' hex Alias hex
' decimal Alias decimal ' ( Alias ( immediate
' \ Alias \ immediate ' \\ Alias \\ immediate
' .( Alias .( immediate ' [ Alias [ immediate
' cr Alias cr
' end-code Alias end-code ' Transient Alias Transient
' +thru Alias +thru ' +load Alias +load
' .s Alias .s
Tools ' trace Alias trace immediate
( ----- 022 )
\ immediate words and branch primitives ks 29 jun 87
: >mark ( -- addr ) T here 0 , H ;
: >resolve ( addr -- ) T here over - swap ! H ;
: <mark ( -- addr ) H there ;
: <resolve ( addr -- ) T here - , H ;
: immediate H $40 flag! ;
: restrict H $80 flag! ;
: | H ?thead @ ?exit ?thead on ;
: internal H 1 ?thead ! ;
: external H ?thead off ;
( ----- 023 )
\ ' | compile Alias >name ks 29 jun 87
: ' ( -- acf ) H g' dup @ <res> -
IF Error" undefined" THEN 2+ @ ;
: compile H ghost , ; immediate restrict
: >name ( acf -- anf / ff ) H tvoc
BEGIN @ dup WHILE under 2- @ nfa? ?dup IF nip exit THEN
swap REPEAT nip ;
( ----- 024 )
\ >name Alias ks 29 jun 87
: >body ( acf -- apf ) H 2+ ;
: Alias ( n -- ) H tlast off
(theader ghost over resolve T , H $20 flag! ;
: on ( addr -- ) H true swap T ! H ;
: off ( addr -- ) H false swap T ! H ;
( ----- 025 )
\ Target tools ks 9 sep 86
Onlyforth
| : .tfield ( taddr len quan -) >r under Pad swap
bounds ?DO dup T c@ I H c! 1+ LOOP drop
Pad over type r> swap - 0 max spaces ;
' view Alias hview
Ttools also definitions
| : ?: ( addr -- addr ) dup 4 u.r ." :" ;
| : @? ( addr -- addr ) dup T @ H 6 u.r ;
| : c? ( addr -- addr ) dup T c@ H 3 .r ;
( ----- 026 )
\ Ttools for decompiling ks 9 sep 86
: s ( addr -- addr+ ) ?: space c? 4 spaces
T count 2dup + even -rot 18 .tfield ;
: n ( addr -- addr+2 ) ?: @? 2 spaces dup T @ >name H
?dup IF T count H ELSE 0 0 THEN
$1F and $18 .tfield 2+ ;
: d ( addr n -- addr+n ) 2dup swap ?: 3 spaces
swap 0 DO c? 1+ LOOP 4 spaces -rot dup .tfield ;
: l ( addr -- addr+2 ) ?: 6 spaces @? 2+ 14 spaces ;
: c ( addr -- addr+1 ) 1 d 15 spaces ;
( ----- 027 )
\ Tools for decompiling ks 29 jun 87
: b ( addr -- addr+2 ) ?: @? dup T @ H
over + 6 u.r 2+ 14 spaces ;
: dump ( addr n -- )
bounds ?DO cr I 10 d drop stop? IF LEAVE THEN 10 +LOOP ;
: view T ' >name H ?dup 0=exit 4 - T @ H ?dup 0=exit edit ;
( ----- 028 )
\ Predefinitions loadscreen ks 29 jun 87
Onlyforth
: clear H true Abort" There are ghosts" ;
1 $B +thru
( ----- 029 )
\ Literal ['] ?" ." " ks 29 jun 87
Transient definitions Forth
: Literal ( n -- ) H dup $FF00 and
IF T compile lit , H exit THEN T compile clit c, H ;
immediate
: char H bl word 1+ c@ ;
: [char] H char T [compile] Literal H ; immediate
: ['] T compile lit H ; immediate
: ." T compile (." ," align H ; immediate
: " T compile (" ," align H ; immediate
( ----- 030 )
\ Target compilation ] ks 07 dez 87
Forth definitions
| : tcompile ( string -- ) dup find ?dup
IF 0> IF nip execute exit THEN THEN
drop gfind IF execute exit THEN number? ?dup
IF 0> IF swap T [compile] Literal THEN
[compile] Literal H exit THEN
symbolic execute ;
Transient definitions
: ] H ] ['] tcompile Is parser ;
( ----- 031 )
\ Target conditionals ks 10 sep 86
: IF T compile ?branch >mark H 1 ; immediate restrict
: THEN abs 1 ?pairs T >resolve H ; immediate restrict
: ELSE 1 ?pairs T compile branch >mark
swap >resolve H -1 ; immediate restrict
: BEGIN T <mark H 2 ; immediate restrict
: WHILE 2 ?pairs 2 T compile ?branch >mark H -2 2swap ;
immediate restrict
| : (repeat 2 ?pairs T <resolve H
BEGIN dup -2 = WHILE drop T >resolve H REPEAT ;
: UNTIL T compile ?branch (repeat H ; immediate restrict
: REPEAT T compile branch (repeat H ; immediate restrict
( ----- 032 )
\ Target conditionals Abort" etc. ks 09 feb 88
: DO T compile (do >mark H 3 ; immediate restrict
: ?DO T compile (?do >mark H 3 ; immediate restrict
: LOOP 3 ?pairs T compile (loop
compile endloop >resolve H ; immediate restrict
: +LOOP 3 ?pairs T compile (+loop
compile endloop >resolve H ; immediate restrict
: Abort" T compile (abort" ," align H ; immediate restrict
: Error" T compile (error" ," align H ; immediate restrict
( ----- 033 )
\ Target does> ;code ks 29 jun 87
| : dodoes> T compile (;code
H glast' @ there resdoes> there tdoes> ! ;
: Does> H undefined? T dodoes>
$E9 c, H tdodo @ there - 2- T ,
H ?reinterpret ; immediate restrict
: ;Code H 0 ?pairs undefined? T dodoes> H ?reinterpret
T [compile] [ Assembler H ; immediate restrict
( ----- 034 )
\ User ks 09 jul 87
Forth definitions
Variable torigin torigin off \ cold boot vector
Variable tudp tudp off \ user variable counter
: >user ( addr1 -- addr2 ) T c@ H torigin @ + ;
Transient definitions Forth
: origin! ( taddr -- ) H torigin ! tudp off ;
: uallot ( n -- offset ) H tudp @ swap tudp +! ;
DO> >user ;
: User T prebuild User 2 uallot c, H ;
( ----- 035 )
\ Variable Constant Create ks 01 okt 87
DO> ;
: Variable T prebuild Create 2 allot H ;
DO> T @ H ;
: Constant T prebuild Constant , H ;
DO> ;
: Create T prebuild Create H ;
: Create: T Create ] H end-code 0 ;
( ----- 036 )
\ Defer Is Vocabulary ks 29 jun 87
DO> ;
: Defer T prebuild Defer 2 allot ;
: Is T ' >body H state @
IF T compile (is , H exit THEN T ! H ; immediate
dummy
: Vocabulary H >in @ Vocabulary >in !
T prebuild Vocabulary 0 , 0 ,
H there tvoc-link @ T , H tvoc-link ! ;
( ----- 037 )
\ File ks 19 m„r 88
Forth definitions
Variable tfile-link tfile-link off
Variable tfileno tfileno off
&45 Constant tb/fcb
Transient definitions Forth
dummy
: File T prebuild File here tb/fcb 0 fill
here H tfile-link @ T , H tfile-link !
1 tfileno +! tfileno @ T c, 0 , 0 , 0 , 0 , 0 ,
here dup >r 1+ tb/fcb &13 - allot H tlast @
T count dup r> c!
H bounds ?DO I T c@ over c! H 1+ LOOP drop ;
( ----- 038 )
\ : ; compile Host [compile] ks 29 jun 87
dummy
: : H >in @ >in: ! T prebuild : ] H end-code 0 ;
: ; 0 ?pairs T compile unnest
[compile] [ H ; immediate restrict
: compile T compile compile H ; immediate restrict
: Host H Onlyforth ;
: Compiler H Onlyforth Transient also definitions ;
: [compile] H ghost execute ; immediate restrict
( ----- 039 )
\ Target ks 29 jun 87
Onlyforth
: Target H vp off Transient also definitions ;
Transient definitions
ghost c, drop

View File

@ -0,0 +1,18 @@
: .flags ( cntf -- )
dup $80 and if [char] R emit else space then
dup $40 and if [char] I emit else space then
$20 and if [char] N emit else space then ;
: vlist ( -- ) base @ cr
." Word" &25 spaces ." Flags CFA Length" cr
[compile] char capital >r context @
BEGIN @ dup stop? 0= and
WHILE ?cr dup 2+ r@ bl = over 1+ c@ r@ = or
IF dup .name
dup c@ $F and &20 swap - spaces ( Name )
dup c@ .flags space ( Count Field )
dup name> hex u. space ( CFA )
2- 2- @ decimal 3 u.r space ( Block )
cr
ELSE drop THEN
REPEAT drop rdrop base ! ;

Binary file not shown.

View File

@ -4,427 +4,441 @@
Comparison of user visible words in each target base kernel image
| Word | C64/C16 | CP/M | MS-DOS | Atari ST | Atari 8bit | Apple 1/2 | PET | py65 | |
|---------------+---------+------+--------+----------+------------+-----------+-----+------+---|
| ASSEMBLER | core | | | | | | | core | |
| FORTH-83 | core | | | | | | | core | |
| (R/W | | | | | | | | core | |
| DRVINIT | core | | | | | | | core | |
| DRV? | core | | | | | | | core | |
| >DRIVE | core | | | | | | | core | |
| DRIVE | core | | | | | | | core | |
| BLK/DRV | core | | | | | | | core | |
| B/BLK | core | | | | | | | core | |
| DISPLAY | core | | | | | | | core | |
| KEYBOARD | core | | | | | | | core | |
| 65TYPE | | | | | | | | | |
| 65AT? | | | | | | | | | |
| 65AT | | | | | | | | | |
| 65PAGE | | | | | | | | | |
| 65DEL | | | | | | | | | |
| 65CR | | | | | | | | | |
| 65EMIT | | | | | | | | | |
| (EMIT | | | | | | | | | |
| 65EXPECT | | | | | | | | | |
| 65DECODE | | | | | | | | | |
| #LF | | | | | | | | core | |
| #ESC | | | | | | | | core | |
| #CR | core | | | | | | | core | |
| #BS | core | | | | | | | core | |
| 65KEY | | | | | | | | | |
| CUROFF | core | | | | | | | core | |
| CURON | core | | | | | | | core | |
| GETKEY | core | | | | | | | core | |
| 65KEY? | | | | | | | | | |
| RESTART | core | | | | | | | core | |
| COLD | core | | | | | | | core | |
| 'RESTART | core | | | | | | | core | |
| 'COLD | core | | | | | | | core | |
| EXPECT | core | | | | | | | core | |
| DECODE | core | | | | | | | core | |
| KEY? | core | | | | | | | core | |
| KEY | core | | | | | | | core | |
| INPUT: | core | | | | | | | core | |
| COL | core | | | | | | | core | |
| ROW | core | | | | | | | core | |
| AT? | core | | | | | | | core | |
| AT | core | | | | | | | core | |
| PAGE | core | | | | | | | core | |
| DEL | core | | | | | | | core | |
| TYPE | core | | | | | | | core | |
| CR | core | | | | | | | core | |
| EMIT | core | | | | | | | core | |
| OUTPUT: | core | | | | | | | core | |
| ?CR | core | | | | | | | core | |
| STOP? | core | | | | | | | core | |
| BYE | core | | | | | | | core | |
| SAVE | core | | | | | | | core | |
| EMPTY | core | | | | | | | core | |
| FORGET | core | | | | | | | core | |
| (FORGET | core | | | | | | | core | |
| CLEAR | core | | | | | | | core | |
| ALL-BUFFERS | core | | | | | | | core | |
| FREEBUFFER | core | | | | | | | core | |
| ALLOTBUFFER | core | | | | | | | core | |
| FIRST | core | | | | | | | core | |
| LIMIT | core | | | | | | | core | |
| CONVEY | core | | | | | | | core | |
| COPY | core | | | | | | | core | |
| BLKMOVE | core | | | | | | | | |
| (COPY | core | | | | | | | | |
| FLUSH | core | | | | | | | core | |
| EMPTY-BUFFERS | core | | | | | | | core | |
| SAVE-BUFFERS | core | | | | | | | core | |
| UPDATE | core | | | | | | | core | |
| BLOCK | core | | | | | | | core | |
| BUFFER | core | | | | | | | core | |
| (BLOCK | core | | | | | | | core | |
| (BUFFER | core | | | | | | | core | |
| CORE? | core | | | | | | | core | |
| R/W | core | | | | | | | core | |
| DISKERR | core | | | | | | | core | |
| (DISKERR | core | | | | | | | core | |
| B/BUF | core | | | | | | | core | |
| BUFFERS | core | | | | | | | | |
| PREV | core | | | | | | | core | |
| FILE | core | | | | | | | core | |
| UNLOCK | core | | | | | | | core | |
| LOCK | core | | | | | | | core | |
| PAUSE | core | | | | | | | core | |
| LIST | core | | | | | | | core | |
| L/S | core | | | | | | | core | |
| C/L | core | | | | | | | core | |
| .S | core | | | | | | | core | |
| U. | core | | | | | | | core | |
| . | core | | | | | | | core | |
| D. | core | | | | | | | core | |
| U.R | core | | | | | | | core | |
| .R | core | | | | | | | core | |
| D.R | core | | | | | | | core | |
| #S | core | | | | | | | core | |
| # | core | | | | | | | core | |
| SIGN | core | | | | | | | core | |
| #> | core | | | | | | | core | |
| <# | core | | | | | | | core | |
| HOLD | core | | | | | | | core | |
| SPACES | core | | | | | | | core | |
| SPACE | core | | | | | | | core | |
| -TRAILING | core | | | | | | | core | |
| BL | core | | | | | | | core | |
| ERROR" | core | | | | | | | core | |
| ABORT" | core | | | | | | | core | |
| (ABORT" | core | | | | | | | core | |
| (ERROR | core | | | | | | | core | |
| R# | core | | | | | | | core | |
| SCR | core | | | | | | | core | |
| ABORT | core | | | | | | | core | |
| 'ABORT | core | | | | | | | core | |
| STANDARDI/O | core | | | | | | | core | |
| QUIT | core | | | | | | | core | |
| 'QUIT | core | | | | | | | core | |
| (QUIT | core | | | | | | | core | |
| DEPTH | core | | | | | | | core | |
| RDEPTH | core | | | | | | | core | |
| --> | core | | | | | | | core | |
| +THRU | core | | | | | | | core | |
| THRU | core | | | | | | | core | |
| +LOAD | core | | | | | | | core | |
| LOAD | core | | | | | | | core | |
| PUSH | core | | | | | | | core | |
| .STATUS | core | | | | | | | core | |
| ?STACK | core | | | | | | | core | |
| IS | core | | | | | | | core | |
| (IS | core | | | | | | | core | |
| DEFER | core | | | | | | | core | |
| ] | core | | | | | | | core | |
| [ | core | | | | | | | core | |
| INTERPRET | core | | | | | | | core | |
| NO.EXTENSIONS | core | | | | | | | core | |
| NOTFOUND | core | | | | | | | core | |
| >INTERPRET | core | | | | | | | core | |
| NULLSTRING? | core | | | | | | | core | |
| ['] | core | | | | | | | core | |
| [COMPILE] | core | | | | | | | core | |
| ' | core | | | | | | | core | |
| FIND | core | | | | | | | core | |
| (FIND | core | | | | | | | core | |
| WORDS | core | | | | | | | core | |
| ORDER | core | | | | | | | core | |
| DEFINITIONS | core | | | | | | | core | |
| ONLYFORTH | core | | | | | | | core | |
| ONLY | core | | | | | | | core | |
| FORTH | core | | | | | | | core | |
| VOCABULARY | core | | | | | | | core | |
| TOSS | core | | | | | | | core | |
| ALSO | core | | | | | | | core | |
| CONTEXT | core | | | | | | | core | |
| CURRENT | core | | | | | | | core | |
| VP | core | | | | | | | core | |
| ALIAS | core | | | | | | | core | |
| USER | core | | | | | | | core | |
| UALLOT | core | | | | | | | core | |
| VARIABLE | core | | | | | | | core | |
| CONSTANT | core | | | | | | | core | |
| ; | core | | | | | | | core | |
| : | core | | | | | | | core | |
| CREATE: | core | | | | | | | | |
| .NAME | core | | | | | | | core | |
| >BODY | core | | | | | | | core | |
| NAME> | core | | | | | | | core | |
| >NAME | core | | | | | | | core | |
| NFA? | core | | | | | | | | |
| CREATE | core | | | | | | | core | |
| WARNING | core | | | | | | | core | |
| \vert | core | | | | | | | core | |
| ?HEAD | core | | | | | | | core | |
| DOES> | core | | | | | | | core | |
| HEAP? | core | | | | | | | core | |
| HEAP | core | | | | | | | core | |
| HALLOT | core | | | | | | | core | |
| CLEARSTACK | core | | | | | | | core | |
| RESTRICT | core | | | | | | | core | |
| IMMEDIATE | core | | | | | | | core | |
| RECURSIVE | core | | | | | | | core | |
| REVEAL | core | | | | | | | core | |
| HIDE | core | | | | | | | core | |
| LAST | core | | | | | | | core | |
| NUMBER | core | | | | | | | core | |
| 'NUMBER? | core | | | | | | | | |
| NUMBER? | core | | | | | | | core | |
| DPL | core | | | | | | | core | |
| PREVIOUS | core | | | | | | | | |
| CHAR | core | | | | | | | | |
| END? | core | | | | | | | | |
| CONVERT | core | | | | | | | core | |
| ACCUMULATE | core | | | | | | | core | |
| DIGIT? | core | | | | | | | core | |
| DECIMAL | core | | | | | | | core | |
| HEX | core | | | | | | | core | |
| \NEEDS | core | | | | | | | core | |
| \\ | core | | | | | | | core | |
| \ | core | | | | | | | core | |
| .( | core | | | | | | | core | |
| ( | core | | | | | | | core | |
| ." | core | | | | | | | core | |
| (." | core | | | | | | | core | |
| " | core | | | | | | | core | |
| (" | core | | | | | | | core | |
| "LIT | core | | | | | | | core | |
| ," | core | | | | | | | core | |
| ASCII | core | | | | | | | core | |
| STATE | core | | | | | | | core | |
| NAME | core | | | | | | | core | |
| PARSE | core | | | | | | | core | |
| WORD | core | | | | | | | core | |
| SOURCE | core | | | | | | | core | |
| CAPITALIZE | core | | | | | | | core | |
| CAPITAL | core | | | | | | | core | |
| /STRING | core | | | | | | | core | |
| SKIP | core | | | | | | | core | |
| SCAN | core | | | | | | | core | |
| QUERY | core | | | | | | | core | |
| TIB | core | | | | | | | core | |
| SPAN | core | | | | | | | core | |
| BLK | core | | | | | | | core | |
| >IN | core | | | | | | | core | |
| >TIB | core | | | | | | | core | |
| #TIB | core | | | | | | | core | |
| COMPILE | core | | | | | | | core | |
| C, | core | | | | | | | core | |
| , | core | | | | | | | core | |
| ALLOT | core | | | | | | | core | |
| PAD | core | | | | | | | core | |
| HERE | core | | | | | | | core | |
| FILL | core | | | | | | | core | |
| ERASE | core | | | | | | | core | |
| COUNT | core | | | | | | | core | |
| PLACE | core | | | | | | | core | |
| MOVE | core | | | | | | | core | |
| CMOVE> | core | | | | | | | core | |
| CMOVE | core | | | | | | | core | |
| UD/MOD | core | | | | | | | core | |
| U/MOD | core | | | | | | | core | |
| */ | core | | | | | | | core | |
| */MOD | core | | | | | | | core | |
| MOD | core | | | | | | | core | |
| / | core | | | | | | | core | |
| /MOD | core | | | | | | | core | |
| 2/ | core | | | | | | | core | |
| M/MOD | core | | | | | | | core | |
| UM/MOD | core | | | | | | | core | |
| 2* | core | | | | | | | core | |
| * | core | | | | | | | core | |
| M* | core | | | | | | | core | |
| UM* | core | | | | | | | core | |
| UNLOOP | core | | | | | | | | |
| LEAVE | core | | | | | | | core | |
| +LOOP | core | | | | | | | core | |
| LOOP | core | | | | | | | core | |
| ?DO | core | | | | | | | core | |
| DO | core | | | | | | | core | |
| UNTIL | core | | | | | | | core | |
| REPEAT | core | | | | | | | core | |
| WHILE | core | | | | | | | core | |
| BEGIN | core | | | | | | | core | |
| ELSE | core | | | | | | | core | |
| THEN | core | | | | | | | core | |
| IF | core | | | | | | | core | |
| CASE? | core | | | | | | | core | |
| ?PAIRS | core | | | | | | | core | |
| <RESOLVE | core | | | | | | | core | |
| <MARK | core | | | | | | | core | |
| >RESOLVE | core | | | | | | | core | |
| >MARK | core | | | | | | | core | |
| ?BRANCH | core | | | | | | | core | |
| BRANCH | core | | | | | | | core | |
| J | core | | | | | | | core | |
| I | core | | | | | | | core | |
| (+LOOP | core | | | | | | | core | |
| (LOOP | core | | | | | | | core | |
| ENDLOOP | core | | | | | | | core | |
| BOUNDS | core | | | | | | | core | |
| (?DO | core | | | | | | | core | |
| (DO | core | | | | | | | core | |
| ABS | core | | | | | | | core | |
| DBAS | core | | | | | | | core | |
| EXTEND | core | | | | | | | core | |
| UMIN | core | | | | | | | core | |
| UMAX | core | | | | | | | core | |
| MAX | core | | | | | | | core | |
| MIN | core | | | | | | | core | |
| D< | core | | | | | | | core | |
| D= | core | | | | | | | core | |
| D0= | core | | | | | | | core | |
| = | core | | | | | | | core | |
| U> | core | | | | | | | core | |
| 0<> | core | | | | | | | core | |
| 0> | core | | | | | | | core | |
| > | core | | | | | | | core | |
| U< | core | | | | | | | core | |
| < | core | | | | | | | core | |
| UWITHIN | core | | | | | | | core | |
| 0= | core | | | | | | | core | |
| 0< | core | | | | | | | core | |
| LITERAL | core | | | | | | | core | |
| LIT | core | | | | | | | core | |
| CLIT | core | | | | | | | core | |
| OFF | core | | | | | | | core | |
| ON | core | | | | | | | core | |
| 4 | core | | | | | | | core | |
| 3 | core | | | | | | | core | |
| 2 | core | | | | | | | core | |
| 1 | core | | | | | | | core | |
| 0 | core | | | | | | | core | |
| -1 | core | | | | | | | core | |
| FALSE | core | | | | | | | core | |
| TRUE | core | | | | | | | core | |
| 2- | core | | | | | | | core | |
| 1- | core | | | | | | | core | |
| 4+ | core | | | | | | | | |
| 3+ | core | | | | | | | core | |
| 2+ | core | | | | | | | core | |
| 1+ | core | | | | | | | core | |
| D+ | core | | | | | | | core | |
| DNEGATE | core | | | | | | | core | |
| NEGATE | core | | | | | | | core | |
| NOT | core | | | | | | | core | |
| - | core | | | | | | | core | |
| XOR | core | | | | | | | core | |
| AND | core | | | | | | | core | |
| OR | core | | | | | | | core | |
| + | core | | | | | | | core | |
| 2DUP | core | | | | | | | core | |
| 2DROP | core | | | | | | | core | |
| 2SWAP | core | | | | | | | core | |
| ROLL | core | | | | | | | core | |
| PICK | core | | | | | | | core | |
| UNDER | core | | | | | | | core | |
| NIP | core | | | | | | | core | |
| ROT | core | | | | | | | core | |
| -ROT | core | | | | | | | core | |
| OVER | core | | | | | | | core | |
| ?DUP | core | | | | | | | core | |
| DUP | core | | | | | | | core | |
| SWAP | core | | | | | | | core | |
| DROP | core | | | | | | | core | |
| +! | core | | | | | | | core | |
| ! | core | | | | | | | core | |
| @ | core | | | | | | | core | |
| CTOGGLE | core | | | | | | | core | |
| C! | core | | | | | | | core | |
| C@ | core | | | | | | | core | |
| PERFORM | core | | | | | | | core | |
| EXECUTE | core | | | | | | | core | |
| ?EXIT | core | | | | | | | core | |
| UNNEST | core | | | | | | | | |
| EXIT | core | | | | | | | core | |
| RDROP | core | | | | | | | core | |
| R@ | core | | | | | | | core | |
| R> | core | | | | | | | core | |
| >R | core | | | | | | | core | |
| RP! | core | | | | | | | core | |
| RP@ | core | | | | | | | core | |
| UP! | core | | | | | | | core | |
| UP@ | core | | | | | | | core | |
| SP! | core | | | | | | | core | |
| SP@ | core | | | | | | | core | |
| UDP | core | | | | | | | core | |
| VOC-LINK | core | | | | | | | core | |
| ERRORHANDLER | core | | | | | | | core | |
| INPUT | core | | | | | | | core | |
| OUTPUT | core | | | | | | | core | |
| BASE | core | | | | | | | core | |
| OFFSET | core | | | | | | | core | |
| DP | core | | | | | | | core | |
| R0 | core | | | | | | | core | |
| S0 | core | | | | | | | core | |
| ORIGIN | core | | | | | | | core | |
| NOOP | core | | | | | | | core | |
| RECOVER | core | | | | | | | core | |
| END-TRACE | core | | | | | | | core | |
| LOGO | core | | | | | | | | |
| (64 | core | | | | | | | | |
| C) | core | | | | | | | | |
| (16 | core | | | | | | | | |
| C64INIT | core | | | | | | | | |
| INIT-SYSTEM | core | | | | | | | | |
| INK-POT | core | | | | | | | | |
| FINDEX | core | | | | | | | | |
| INDEX | core | | | | | | | | |
| 1541RW | core | | | | | | | | |
| DISKCLOSE | core | | | | | | | | |
| DISKOPEN | core | | | | | | | | |
| WRITESECTOR | core | | | | | | | | |
| READSECTOR | core | | | | | | | | |
| DERROR? | core | | | | | | | | |
| I/O-STATUS? | core | | | | | | | | |
| BUSINPUT | core | | | | | | | | |
| BUS@ | core | | | | | | | | |
| BUSTYPE | core | | | | | | | | |
| BUS! | core | | | | | | | | |
| BUSIN | core | | | | | | | | |
| (BUSIN | core | | | | | | | | |
| BUSCLOSE | core | | | | | | | | |
| BUSOPEN | core | | | | | | | | |
| BUSOUT | core | | | | | | | | |
| (BUSOUT | core | | | | | | | | |
| ?DEVICE | core | | | | | | | | |
| (?DEVICE | core | | | | | | | | |
| BUSOFF | core | | | | | | | | |
| I/O | core | | | | | | | | |
| (DRV | core | | | | | | | | |
| C64TYPE | core | | | | | | | | |
| C64AT? | core | | | | | | | | |
| C64AT | core | | | | | | | | |
| C64PAGE | core | | | | | | | | |
| C64DEL | core | | | | | | | | |
| C64CR | core | | | | | | | | |
| C64EMIT | core | | | | | | | | |
| PRINTABLE | core | | | | | | | | |
| CON! | core | | | | | | | | |
| C64EXPECT | core | | | | | | | | |
| C64DECODE | core | | | | | | | | |
| C64KEY | core | | | | | | | | |
| C64KEY? | core | | | | | | | | |
| CUSTOM-REMOVE | core | | | | | | | | |
| | | | | | | | | | |
| Word | C64/C16 | CP/M | MS-DOS | Atari ST | Atari 8bit | Apple 1/2 | PET | py65 | 8086bm | Forth2012 |
|---------------+---------+------+--------+----------+------------+-----------+-----+------+--------+-----------|
| ASSEMBLER | core | | | | | | | core | | |
| FORTH-83 | core | | | | | | | core | | |
| (R/W | | | | | | | | core | | |
| DRVINIT | core | | | | | | | core | | |
| DRV? | core | | | | | | | core | | |
| >DRIVE | core | | | | | | | core | | |
| DRIVE | core | | | | | | | core | | |
| BLK/DRV | core | | | | | | | core | | |
| B/BLK | core | | | | | | | core | | |
| DISPLAY | core | | | | | | | core | | |
| KEYBOARD | core | | | | | | | core | | |
| 65TYPE | | | | | | | | | | |
| 65AT? | | | | | | | | | | |
| 65AT | | | | | | | | | | |
| 65PAGE | | | | | | | | | | |
| 65DEL | | | | | | | | | | |
| 65CR | | | | | | | | | | |
| 65EMIT | | | | | | | | | | |
| (EMIT | | | | | | | | | | |
| 65EXPECT | | | | | | | | | | |
| 65DECODE | | | | | | | | | | |
| #LF | | | | | | | | core | | |
| #ESC | | | | | | | | core | | |
| #CR | core | | | | | | | core | | |
| #BS | core | | | | | | | core | | |
| 65KEY | | | | | | | | | | |
| CUROFF | core | | | | | | | core | | |
| CURON | core | | | | | | | core | | |
| GETKEY | core | | | | | | | core | | |
| 65KEY? | | | | | | | | | | |
| RESTART | core | | | | | | | core | | |
| COLD | core | | | | | | | core | | |
| 'RESTART | core | | | | | | | core | | |
| 'COLD | core | | | | | | | core | | |
| EXPECT | core | | | | | | | core | | |
| DECODE | core | | | | | | | core | | |
| KEY? | core | | | | | | | core | | |
| KEY | core | | | | | | | core | | |
| INPUT: | core | | | | | | | core | | |
| COL | core | | | | | | | core | | |
| ROW | core | | | | | | | core | | |
| AT? | core | | | | | | | core | | |
| AT | core | | | | | | | core | | |
| PAGE | core | | | | | | | core | | |
| DEL | core | | | | | | | core | | |
| TYPE | core | | | | | | | core | | |
| CR | core | | | | | | | core | | core |
| EMIT | core | | | | | | | core | | |
| OUTPUT: | core | | | | | | | core | | |
| ?CR | core | | | | | | | core | | |
| STOP? | core | | | | | | | core | | |
| BYE | core | | | | | | | core | | |
| SAVE | core | | | | | | | core | | |
| EMPTY | core | | | | | | | core | | |
| FORGET | core | | | | | | | core | | |
| (FORGET | core | | | | | | | core | | |
| CLEAR | core | | | | | | | core | | |
| ALL-BUFFERS | core | | | | | | | core | | |
| FREEBUFFER | core | | | | | | | core | | |
| ALLOTBUFFER | core | | | | | | | core | | |
| FIRST | core | | | | | | | core | | |
| LIMIT | core | | | | | | | core | | |
| CONVEY | core | | | | | | | core | | |
| COPY | core | | | | | | | core | | |
| BLKMOVE | core | | | | | | | | | |
| (COPY | core | | | | | | | | | |
| FLUSH | core | | | | | | | core | | |
| EMPTY-BUFFERS | core | | | | | | | core | | |
| SAVE-BUFFERS | core | | | | | | | core | | |
| UPDATE | core | | | | | | | core | | |
| BLOCK | core | | | | | | | core | | |
| BUFFER | core | | | | | | | core | | |
| (BLOCK | core | | | | | | | core | | |
| (BUFFER | core | | | | | | | core | | |
| CORE? | core | | | | | | | core | | |
| R/W | core | | | | | | | core | | |
| DISKERR | core | | | | | | | core | | |
| (DISKERR | core | | | | | | | core | | |
| B/BUF | core | | | | | | | core | | |
| BUFFERS | core | | | | | | | | | |
| PREV | core | | | | | | | core | | |
| FILE | core | | | | | | | core | | |
| UNLOCK | core | | | | | | | core | | |
| LOCK | core | | | | | | | core | | |
| PAUSE | core | | | | | | | core | | |
| LIST | core | | | | | | | core | | |
| L/S | core | | | | | | | core | | |
| C/L | core | | | | | | | core | | |
| .S | core | | | | | | | core | | |
| U. | core | | | | | | | core | | |
| . | core | | | | | | | core | | |
| D. | core | | | | | | | core | | |
| U.R | core | | | | | | | core | | |
| .R | core | | | | | | | core | | |
| D.R | core | | | | | | | core | | |
| #S | core | | | | | | | core | | |
| # | core | | | | | | | core | | |
| SIGN | core | | | | | | | core | | |
| #> | core | | | | | | | core | | |
| <# | core | | | | | | | core | | |
| HOLD | core | | | | | | | core | | |
| SPACES | core | | | | | | | core | | |
| SPACE | core | | | | | | | core | | |
| -TRAILING | core | | | | | | | core | | |
| BL | core | | | | | | | core | | core |
| ERROR" | core | | | | | | | core | | |
| ABORT" | core | | | | | | | core | | core |
| (ABORT" | core | | | | | | | core | | |
| (ERROR | core | | | | | | | core | | |
| R# | core | | | | | | | core | | |
| SCR | core | | | | | | | core | | |
| ABORT | core | | | | | | | core | | core |
| 'ABORT | core | | | | | | | core | | |
| STANDARDI/O | core | | | | | | | core | | |
| QUIT | core | | | | | | | core | | |
| 'QUIT | core | | | | | | | core | | |
| (QUIT | core | | | | | | | core | | |
| DEPTH | core | | | | | | | core | | |
| RDEPTH | core | | | | | | | core | | |
| --> | core | | | | | | | core | | |
| +THRU | core | | | | | | | core | | |
| THRU | core | | | | | | | core | | |
| +LOAD | core | | | | | | | core | | |
| LOAD | core | | | | | | | core | | |
| PUSH | core | | | | | | | core | | |
| .STATUS | core | | | | | | | core | | |
| ?STACK | core | | | | | | | core | | |
| IS | core | | | | | | | core | | |
| (IS | core | | | | | | | core | | |
| DEFER | core | | | | | | | core | | |
| ] | core | | | | | | | core | | |
| [ | core | | | | | | | core | | core |
| INTERPRET | core | | | | | | | core | | |
| NO.EXTENSIONS | core | | | | | | | core | | |
| NOTFOUND | core | | | | | | | core | | |
| >INTERPRET | core | | | | | | | core | | |
| NULLSTRING? | core | | | | | | | core | | |
| ['] | core | | | | | | | core | | core |
| [COMPILE] | core | | | | | | | core | | core |
| ' | core | | | | | | | core | | |
| FIND | core | | | | | | | core | | |
| (FIND | core | | | | | | | core | | |
| WORDS | core | | | | | | | core | | |
| ORDER | core | | | | | | | core | | |
| DEFINITIONS | core | | | | | | | core | | |
| ONLYFORTH | core | | | | | | | core | | |
| ONLY | core | | | | | | | core | | |
| FORTH | core | | | | | | | core | | |
| VOCABULARY | core | | | | | | | core | | |
| TOSS | core | | | | | | | core | | |
| ALSO | core | | | | | | | core | | |
| CONTEXT | core | | | | | | | core | | |
| CURRENT | core | | | | | | | core | | |
| VP | core | | | | | | | core | | |
| ALIAS | core | | | | | | | core | | |
| USER | core | | | | | | | core | | |
| UALLOT | core | | | | | | | core | | |
| VARIABLE | core | | | | | | | core | | |
| CONSTANT | core | | | | | | | core | | core |
| ; | core | | | | | | | core | | |
| : | core | | | | | | | core | | |
| CREATE: | core | | | | | | | | | |
| .NAME | core | | | | | | | core | | |
| >BODY | core | | | | | | | core | | |
| NAME> | core | | | | | | | core | | |
| >NAME | core | | | | | | | core | | |
| NFA? | core | | | | | | | | | |
| CREATE | core | | | | | | | core | | core |
| WARNING | core | | | | | | | core | | |
| \vert | core | | | | | | | core | | |
| ?HEAD | core | | | | | | | core | | |
| DOES> | core | | | | | | | core | | |
| HEAP? | core | | | | | | | core | | |
| HEAP | core | | | | | | | core | | |
| HALLOT | core | | | | | | | core | | |
| CLEARSTACK | core | | | | | | | core | | |
| RESTRICT | core | | | | | | | core | | |
| IMMEDIATE | core | | | | | | | core | | |
| RECURSIVE | core | | | | | | | core | | |
| REVEAL | core | | | | | | | core | | |
| HIDE | core | | | | | | | core | | |
| LAST | core | | | | | | | core | | |
| NUMBER | core | | | | | | | core | | |
| 'NUMBER? | core | | | | | | | | | |
| NUMBER? | core | | | | | | | core | | |
| DPL | core | | | | | | | core | | |
| PREVIOUS | core | | | | | | | | | |
| CHAR | core | | | | | | | | | |
| END? | core | | | | | | | | | |
| CONVERT | core | | | | | | | core | | |
| ACCUMULATE | core | | | | | | | core | | |
| DIGIT? | core | | | | | | | core | | |
| DECIMAL | core | | | | | | | core | | |
| HEX | core | | | | | | | core | | |
| \NEEDS | core | | | | | | | core | | |
| \\ | core | | | | | | | core | | |
| \ | core | | | | | | | core | | |
| .( | core | | | | | | | core | | |
| ( | core | | | | | | | core | | |
| ." | core | | | | | | | core | | |
| (." | core | | | | | | | core | | |
| " | core | | | | | | | core | | |
| (" | core | | | | | | | core | | |
| "LIT | core | | | | | | | core | | |
| ," | core | | | | | | | core | | |
| ASCII | core | | | | | | | core | | |
| STATE | core | | | | | | | core | | |
| NAME | core | | | | | | | core | | |
| PARSE | core | | | | | | | core | | |
| WORD | core | | | | | | | core | | |
| SOURCE | core | | | | | | | core | | |
| CAPITALIZE | core | | | | | | | core | | |
| CAPITAL | core | | | | | | | core | | |
| /STRING | core | | | | | | | core | | |
| SKIP | core | | | | | | | core | | |
| SCAN | core | | | | | | | core | | |
| QUERY | core | | | | | | | core | | |
| TIB | core | | | | | | | core | | |
| SPAN | core | | | | | | | core | | |
| BLK | core | | | | | | | core | | |
| >IN | core | | | | | | | core | | |
| >TIB | core | | | | | | | core | | |
| #TIB | core | | | | | | | core | | |
| COMPILE | core | | | | | | | core | | |
| C, | core | | | | | | | core | | core |
| , | core | | | | | | | core | | |
| ALLOT | core | | | | | | | core | | core |
| PAD | core | | | | | | | core | | |
| HERE | core | | | | | | | core | | |
| FILL | core | | | | | | | core | | |
| ERASE | core | | | | | | | core | | |
| COUNT | core | | | | | | | core | | core |
| PLACE | core | | | | | | | core | | |
| MOVE | core | | | | | | | core | | |
| CMOVE> | core | | | | | | | core | | |
| CMOVE | core | | | | | | | core | | |
| UD/MOD | core | | | | | | | core | | |
| U/MOD | core | | | | | | | core | | |
| */ | core | | | | | | | core | | |
| */MOD | core | | | | | | | core | | |
| MOD | core | | | | | | | core | | |
| / | core | | | | | | | core | | |
| /MOD | core | | | | | | | core | | |
| 2/ | core | | | | | | | core | | |
| M/MOD | core | | | | | | | core | | |
| UM/MOD | core | | | | | | | core | | |
| 2* | core | | | | | | | core | | |
| * | core | | | | | | | core | | |
| M* | core | | | | | | | core | | |
| UM* | core | | | | | | | core | | |
| UNLOOP | core | | | | | | | | | |
| LEAVE | core | | | | | | | core | | |
| +LOOP | core | | | | | | | core | | |
| LOOP | core | | | | | | | core | | |
| ?DO | core | | | | | | | core | | |
| DO | core | | | | | | | core | | |
| UNTIL | core | | | | | | | core | | |
| REPEAT | core | | | | | | | core | | |
| WHILE | core | | | | | | | core | | |
| BEGIN | core | | | | | | | core | | core |
| ELSE | core | | | | | | | core | | |
| THEN | core | | | | | | | core | | |
| IF | core | | | | | | | core | | |
| CASE? | core | | | | | | | core | | |
| ?PAIRS | core | | | | | | | core | | |
| <RESOLVE | core | | | | | | | core | | |
| <MARK | core | | | | | | | core | | |
| >RESOLVE | core | | | | | | | core | | |
| >MARK | core | | | | | | | core | | |
| ?BRANCH | core | | | | | | | core | | |
| BRANCH | core | | | | | | | core | | |
| J | core | | | | | | | core | | |
| I | core | | | | | | | core | | |
| (+LOOP | core | | | | | | | core | | |
| (LOOP | core | | | | | | | core | | |
| ENDLOOP | core | | | | | | | core | | |
| BOUNDS | core | | | | | | | core | | |
| (?DO | core | | | | | | | core | | |
| (DO | core | | | | | | | core | | |
| ABS | core | | | | | | | core | | core |
| DBAS | core | | | | | | | core | | |
| EXTEND | core | | | | | | | core | | |
| UMIN | core | | | | | | | core | | |
| UMAX | core | | | | | | | core | | |
| MAX | core | | | | | | | core | | |
| MIN | core | | | | | | | core | | |
| D< | core | | | | | | | core | | |
| D= | core | | | | | | | core | | |
| D0= | core | | | | | | | core | | |
| = | core | | | | | | | core | | |
| U> | core | | | | | | | core | | |
| 0<> | core | | | | | | | core | | |
| 0> | core | | | | | | | core | | |
| > | core | | | | | | | core | | |
| U< | core | | | | | | | core | | |
| < | core | | | | | | | core | | |
| UWITHIN | core | | | | | | | core | | |
| 0= | core | | | | | | | core | | |
| 0< | core | | | | | | | core | | |
| LITERAL | core | | | | | | | core | | |
| LIT | core | | | | | | | core | | |
| CLIT | core | | | | | | | core | | |
| OFF | core | | | | | | | core | | |
| ON | core | | | | | | | core | | |
| 4 | core | | | | | | | core | | |
| 3 | core | | | | | | | core | | |
| 2 | core | | | | | | | core | | |
| 1 | core | | | | | | | core | | |
| 0 | core | | | | | | | core | | |
| -1 | core | | | | | | | core | | |
| FALSE | core | | | | | | | core | | |
| TRUE | core | | | | | | | core | | |
| 2- | core | | | | | | | core | | |
| 1- | core | | | | | | | core | | |
| 4+ | core | | | | | | | | | |
| 3+ | core | | | | | | | core | | |
| 2+ | core | | | | | | | core | | |
| 1+ | core | | | | | | | core | | |
| D+ | core | | | | | | | core | | |
| DNEGATE | core | | | | | | | core | | |
| NEGATE | core | | | | | | | core | | |
| NOT | core | | | | | | | core | | |
| - | core | | | | | | | core | | |
| XOR | core | | | | | | | core | | |
| AND | core | | | | | | | core | | core |
| OR | core | | | | | | | core | | |
| + | core | | | | | | | core | | |
| 2DUP | core | | | | | | | core | | |
| 2DROP | core | | | | | | | core | | |
| 2SWAP | core | | | | | | | core | | |
| ROLL | core | | | | | | | core | | |
| PICK | core | | | | | | | core | | |
| UNDER | core | | | | | | | core | | |
| NIP | core | | | | | | | core | | |
| ROT | core | | | | | | | core | | |
| -ROT | core | | | | | | | core | | |
| OVER | core | | | | | | | core | | |
| ?DUP | core | | | | | | | core | | |
| DUP | core | | | | | | | core | | |
| SWAP | core | | | | | | | core | | |
| DROP | core | | | | | | | core | | |
| +! | core | | | | | | | core | | |
| ! | core | | | | | | | core | | |
| @ | core | | | | | | | core | | |
| CTOGGLE | core | | | | | | | core | | |
| C! | core | | | | | | | core | | core |
| C@ | core | | | | | | | core | | core |
| PERFORM | core | | | | | | | core | | |
| EXECUTE | core | | | | | | | core | | |
| ?EXIT | core | | | | | | | core | | |
| UNNEST | core | | | | | | | | | |
| EXIT | core | | | | | | | core | | |
| RDROP | core | | | | | | | core | | |
| R@ | core | | | | | | | core | | |
| R> | core | | | | | | | core | | |
| >R | core | | | | | | | core | | |
| RP! | core | | | | | | | core | | |
| RP@ | core | | | | | | | core | | |
| UP! | core | | | | | | | core | | |
| UP@ | core | | | | | | | core | | |
| SP! | core | | | | | | | core | | |
| SP@ | core | | | | | | | core | | |
| UDP | core | | | | | | | core | | |
| VOC-LINK | core | | | | | | | core | | |
| ERRORHANDLER | core | | | | | | | core | | |
| INPUT | core | | | | | | | core | | |
| OUTPUT | core | | | | | | | core | | |
| BASE | core | | | | | | | core | | core |
| OFFSET | core | | | | | | | core | | |
| DP | core | | | | | | | core | | |
| R0 | core | | | | | | | core | | |
| S0 | core | | | | | | | core | | |
| ORIGIN | core | | | | | | | core | | |
| NOOP | core | | | | | | | core | | |
| RECOVER | core | | | | | | | core | | |
| END-TRACE | core | | | | | | | core | | |
| LOGO | core | | | | | | | | | |
| (64 | core | | | | | | | | | |
| C) | core | | | | | | | | | |
| (16 | core | | | | | | | | | |
| C64INIT | core | | | | | | | | | |
| INIT-SYSTEM | core | | | | | | | | | |
| INK-POT | core | | | | | | | | | |
| FINDEX | core | | | | | | | | | |
| INDEX | core | | | | | | | | | |
| 1541RW | core | | | | | | | | | |
| DISKCLOSE | core | | | | | | | | | |
| DISKOPEN | core | | | | | | | | | |
| WRITESECTOR | core | | | | | | | | | |
| READSECTOR | core | | | | | | | | | |
| DERROR? | core | | | | | | | | | |
| I/O-STATUS? | core | | | | | | | | | |
| BUSINPUT | core | | | | | | | | | |
| BUS@ | core | | | | | | | | | |
| BUSTYPE | core | | | | | | | | | |
| BUS! | core | | | | | | | | | |
| BUSIN | core | | | | | | | | | |
| (BUSIN | core | | | | | | | | | |
| BUSCLOSE | core | | | | | | | | | |
| BUSOPEN | core | | | | | | | | | |
| BUSOUT | core | | | | | | | | | |
| (BUSOUT | core | | | | | | | | | |
| ?DEVICE | core | | | | | | | | | |
| (?DEVICE | core | | | | | | | | | |
| BUSOFF | core | | | | | | | | | |
| I/O | core | | | | | | | | | |
| (DRV | core | | | | | | | | | |
| C64TYPE | core | | | | | | | | | |
| C64AT? | core | | | | | | | | | |
| C64AT | core | | | | | | | | | |
| C64PAGE | core | | | | | | | | | |
| C64DEL | core | | | | | | | | | |
| C64CR | core | | | | | | | | | |
| C64EMIT | core | | | | | | | | | |
| PRINTABLE | core | | | | | | | | | |
| CON! | core | | | | | | | | | |
| C64EXPECT | core | | | | | | | | | |
| C64DECODE | core | | | | | | | | | |
| C64KEY | core | | | | | | | | | |
| C64KEY? | core | | | | | | | | | |
| CUSTOM-REMOVE | core | | | | | | | | | |
| ACCEPT | | | | | | | | | | core |
| ACTION-OF | | | | | | | | | | core |
| AGAIN | | | | | | | | | | core |
| ALIGN | | | | | | | | | | core |
| ALIGNED | | | | | | | | | | core |
| BUFFER: | | | | | | | | | | core |
| [char] | | | | | | | | | core | core |
| char | | | | | | | | | core | core |
| case | | | | | | | | | | core |
| CELL+ | | | | | | | | | | core |
| CELLS | | | | | | | | | | core |
| CHAR+ | | | | | | | | | | core |
| CHARS | | | | | | | | | | core |
| compile, | | | | | | | | | | core |
| | | | | | | | | | | |

35
sources/generic/csb.fth Normal file
View File

@ -0,0 +1,35 @@
( ----- 000 )
\\ Circular String Buffer cas 27jul20
Wil Baden, Costa Mesa, California
Forth Dimensions July 1996
( ----- 001 )
\ CSB load screen cas 27jul20
1 3 +thru
.( Circular Ring Buffer loaded. )
( ----- 002 )
\ Get-Buf >PAD cas 27jul20
1000 CONSTANT /CSB
CREATE CSB 0 , /CSB ALLOT
: GET-BUF ( n -- c_addr )
DUP CSB @ > IF /CSB CSB ! THEN
NEGATE CSB +!
CSB 2+ CSB @ + ;
: >PAD ( a u -- 'a u )
DUP GET-BUF SWAP
2DUP >R >R MOVE R> R> ;
( ----- 003 )
\ S" cas 27jul20
: S" ( "ccc<quote>" -- | c_addr u )
ASCII " PARSE
STATE @ IF
POSTPONE SLITERAL
ELSE
>PAD
THEN ; IMMEDIATE

18
tools/Makefile Normal file
View File

@ -0,0 +1,18 @@
BLKPACK_TGT = blkpack
BLKUNPACK_TGT = blkunpack
TARGETS = $(BLKUNPACK_TGT) $(BLKPACK_TGT)
all: $(TARGETS)
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
$(BLKPACK_TGT): $(BLKPACK_TGT).c
$(BLKUNPACK_TGT): $(BLKUNPACK_TGT).c
$(TARGETS):
$(CC) $(CFLAGS) $@.c -o $@
.PHONY: clean
clean:
rm -f $(TARGETS) $(OBJS)

97
tools/blkpack.c Normal file
View File

@ -0,0 +1,97 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
static int lineno;
static void emptylines(int n)
{
for (int i=0; i<64*n; i++) putchar(0x20);
}
static int getmarker(char *line) // returns -1 on error, blkid otherwise
{
int blkid;
int r = sscanf(line, "( ----- %d )\n", &blkid);
if (r == 1) {
return blkid;
} else {
return -1;
}
}
static int expectmarker(char *line)
{
int blkid = getmarker(line);
if (blkid < 0) { // could not scan
fprintf(
stderr, "Error at line %d: expecting block marker\n", lineno);
}
return blkid;
}
static void usage()
{
fprintf(stderr, "Usage: blkpack < blk.fs > blkfs\n");
}
int main(int argc, char *argv[])
{
int prevblkid = -1;
int blkid;
char *line = NULL;
if (argc != 1) {
usage();
return 1;
}
lineno = 1;
size_t n = 0;
ssize_t cnt = getline(&line, &n, stdin);
if (cnt <= 0) {
fprintf(stderr, "No input\n");
return 1;
}
while (1) {
blkid = expectmarker(line);
if (blkid < 0) return 1;
if (blkid <= prevblkid) {
fprintf(
stderr,
"Wrong blkid (%d) at line %d: blocks must be ordered\n",
blkid, lineno);
return 1;
}
emptylines((blkid-prevblkid-1)*16);
int blkline;
for (blkline=0; blkline<16; blkline++) {
lineno++;
cnt = getline(&line, &n, stdin);
if (cnt <= 0) break; // EOF
if (cnt > 65) {
fprintf(stderr, "Line %d too long (blk %d)\n", lineno, blkid);
return 1;
}
if (getmarker(line) >= 0) break; // we have a marker early
line[cnt-1] = '\0'; // remove newline
printf("%s", line);
// pad line to 64 chars
for (int i=cnt-1; i<64; i++) putchar(0x20);
}
if (blkline == 16) {
lineno++;
cnt = getline(&line, &n, stdin);
} else {
// fill to 16 lines
emptylines(16-blkline);
}
if (cnt <= 0) break; // EOF
prevblkid = blkid;
}
free(line);
return 0;
}

64
tools/blkunpack.c Normal file
View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
/* Unpacks blkfs into its source form.
*
* If numerical "startat" is specified, blkno start at this number.
*
* Whitespaces at the right of every line are trimmed.
*/
void usage()
{
fprintf(stderr, "Usage: blkunpack [startat] < blkfs > blk.fs\n");
}
int main(int argc, char *argv[])
{
char buf[1024];
int blkid = 0;
if (argc > 2) {
usage();
return 1;
}
if (argc == 2) {
blkid = strtol(argv[1], NULL, 10);
}
while (fread(buf, 1024, 1, stdin) == 1) {
int linecnt = 0 ;
for (int i=1023; i>=0; i--) {
if (buf[i] > ' ') {
linecnt = (i / 64) + 1;
break;
}
}
if (linecnt) {
// not an empty block
printf("( ----- %03d )\n", blkid);
for (int i=0; i<linecnt; i++) {
char *line = &buf[i*64];
// line length is *not* strlen()! it's the position of the
// first non-WS, starting from the right. Then, we normalize
// nulls to space.
int j;
for (j=63; j>=0; j--) {
if (line[j] > ' ') {
break;
}
}
int len = j+1;
if (len) {
for (; j>=0; j--) {
if (line[j] == '\0') {
line[j] = ' ';
}
}
fwrite(line, len, 1, stdout);
}
fputc('\n', stdout);
}
}
blkid++;
}
return 0;
}