![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() Editable LibreOffice version I want to translate it! It's a FORTH Editor, Interpteter and Compiler for the ATARI computers.
|
Version 0.3.2 (04/25/2022):
|
An interactive language: This language allows a direct mode, as on a calculator, but in witch you can create new words to enhance its capabilities. On the right, let's imagine that you want to reduce a set of prices by 20%. Each time, you have to compute 80% of it. The first example gives the new price of an item at $59, it's now only $47. Note that values are first pushed on a stack and then the operator works on those numbers, the period "." is the instruction to display the top of the stack. If you don't want to type again and again the same calculations, you create a new word reduc using the pair : ; and it is used to compute the new price for $70, the result is $56. You can even type a little program using here the structure list..dolist..lloop that is a loop whose indexes are an unsorted list of numbers. Inside the loop, the index i is displayed (the original price) then a space and then the reduced price (cr is a carriage return to jump to next line) system is the instruction to quit to the desktop. |
![]() Usage in direct mode |
![]() This word uses one signle variable! |
A program to code a message Let's write, step by step, a GEM program with a menu to code or decode a text message. First, the heart of the program... Let's code a word that will move each uppercase letter of the alphabet several positions ahead or back. To do this, only one variable is required: p a pointer that will go through the string and test every character.
|
Let's use our new word We will use a predefined string named pad that the Forth uses for some string results.
To decode a message without the key, we can just try the 25 differents shifts, that's done with the following structure 25 ndo..nloop.
|
![]() |
![]() Version usable within a program. |
Codage avec prompt Let's enhance a bit the system. I want the program to clearly ask for the key and the text. That is realised with the word code-decode.
|
Raw search Similarly, let's program the raw search with the 25 shifts when you don't know the key into the word multi-decode.
|
![]() |
![]() |
Let's create the menu !![]()
|
One last effort This little word to react to the Infos... entry of the menu. It's a simple alert box. |
![]() |
![]() |
The main loop! It's a classical loop to manage the AES events.
|
Auto-run or not I want that, when under the interpreter, the compilation doesn't run the program to be able to test some parts individually in interactive mode. On the other hand, when creating a standelone program with the compiler, I want the program to be run! That's again a conditional compilation using flag 13: this one is true under the interpreter and false under the compiler. Note: a stadonlone program removes the mouse at start, so v_show_c was added to get the pointer back. |
![]() |
![]() A message is coded and then a raw search is run. |
Our program in action ! When the program is run, it displays its menu and window. You can select the action and test it.. |
![]() Partial view of the raw search. |
![]() Versions 68030/68000, binaries and sources. ![]() With the kind permission of Pierre-Louis Lamballais and Eric Da Cunha. ![]() |
![]() |
Other examples in FORTH Link with the HP-41 using its serial interface. Menus, serial communication How to use the Forth instruction to drive the Supercharger as a coprocessor. Include PC assembly, Supercharger instructions Save and retore data on the BOSS-DR5 via MIDI. Menu, file, MIDI communication RTC Clock manager for the Apollo Vampire V4. Include assembly, dialog creation, dialog in a window |
![]() |
![]() |
Mixing Forth and Assembler You may want to replace code by an assembly routine. This is really simple:
|
Even better: all in one source! The assembly text code and the PRG generation can be driven directly from Forth. Here is how:
During compilation, you'll see the activity of your assembler: ![]() Note: the null argument before every directive can be used in conjunction with a flag to decide wether to execute or ignore those orders. For example, if you're working on the Forth part, you don't have to save an generate the same PRG at every compilation. |
![]() |
Variables definition | |||
---|---|---|---|
variable p \ RIM module variable t \ TRM module variable fichier \ address of file in memory variable total \ total size of file 256 string filename \ path+name 1536 allot constant PALs \ palette source 1536 allot constant PALd \ palette destination variable fhd \ file handle |
Every module is pointed at by a variable. The palettes are at their maximal size to receive 256 colors in VDI format: 256 colors × 3 components × 2-bytes word (0 to 1000) = 1536. |
||
Loading modules | |||
: main " d:\parx.sys\" 1 modset 0 t ! " parx252.trm" graphic_card negate t modload drop 0 p ! " rim\gif00.rim" -1 p modload drop |
|
||
GIF loading and decoding | |||
" F:\FORTH\GIPHY.GIF" filename $! filename 0 fopensize dup fhd ! 0> if total ! fhd @ total @ dup allot dup fichier ! fread drop fichier @ total @ filename fhd @ PALs 1 p dorim drop |
|
||
Dithering for current screen mode | |||
mfdbs mfdbd fillmfdb work_out 2- w@ mfdbd 12 + w! %b1100110 1 PALs PALd 3 t dotrm drop |
|
||
Blitting to screen | |||
mfdbd mfdbs fillmfdb PALs savevdipal PALd setvdipal 0 mfdbd ! 0 0 0 0 mfdbs 4 + w@ mfdbs 6 + w@ 3 vro_cpyfm key drop fhd @ fclose drop PALs setvdipal then p modunload t modunload ; |
|
||
If the program is compiled | |||
>comp -13 >ifflag fastopen drop main >endf |
|
Variables definitions | |||
---|---|---|---|
variable t \ TRM module variable fichier \ address of file in memory variable total \ total size of file 256 string filename 256 string chemin 32 string nom 1536 allot constant PALs 1536 allot constant PALd 20 allot constant MFDB variable fhd 100 array MODS \ the array of pointers to the modules variable nMODS \ the actual number of modules |
|
||
Selecting the image | |||
: main cls " \*.*" chemin $! " " nom $! chemin nom fsel_input chemin nom path filename $! cls |
|
||
Loading the modules | |||
" d:\parx.sys\" 1 modset ." Charment des modules..." cr 0 t ! ( " parx252.trm" graphic_card negate t ) modload drop 0 0 MODS ! ( " rim\*.rim" -1 0 MODS ) modmload .. nMODS ! ." modules chargés" cr |
|
||
Loading the image | |||
." Chargement du fichier..." cr filename 0 fopensize dup fhd ! 0> if total ! ( fhd @ total @ dup allot dup fichier ! ) fread drop |
Same as before, the whole file is loaded into memory. | ||
Finding the image type | |||
nMODS @ 0 do -1 mfdbs fillmfdb ( fichier @ total @ filename fhd @ PALs 1 i MODS ) dorim 0< ifloop |
|
||
Displaying the type | |||
dup nMODS @ = if drop ." Image non reconnue" cr else MODS modlname type cr key drop |
|
||
Displaying the image | |||
mfdbs mfdbd fillmfdb work_out 2- w@ mfdbd 12 + w! ( %b1100110 1 PALs PALd 3 t ) dotrm drop mfdbd mfdbs fillmfdb PALs savevdipal PALd setvdipal ( 0 mfdbd ! 0 0 0 0 mfdbs 4 + w@ mfdbs 6 + w@ 3 ) vro_cpyfm key drop PALs setvdipal then fhd @ fclose drop then 0 MODS nMODS @ modmunload t modunload ; >comp -13 >ifflag fastopen drop main >endf |
|
Variables definition | |||
---|---|---|---|
variable p \ WIM module variable t \ TRM module 1536 allot constant PALs \ palette source if needed 1536 allot constant PALd \ palette destination (unused in 16 bits) |
The same as before, each module requires its own variable.
Every palette has the maximum size for 256 colors. |
||
Loading modules | |||
: main absolute " d:\parx.sys\" 1 modset ." Loading modules..." cr 0 t ! " parx252.trm" graphic_card negate t modload if exit else ." TRM Ok" cr then 0 p ! " wim\tga_tc16.wim" 1 p modload if exit else ." WIM Ok" cr then remember |
|
||
Copying a screen block | |||
." Block 320x200 with palette" cr 0 mfdbs ! 0 320 200 work_out 2- w@ 0 mfdbd fillmfdb mfdbd imagesize allot mfdbd ! 0 0 0 0 320 200 3 vro_cpyfm PALs savevdipal mfdbd mfdbs fillmfdb |
|
||
In case of a graphic card | |||
( graphic_card work_out 2- w@ 4 8 <seg> ) and if ." Converting to VDI mode..." cr 1 mfdbd 10 + w! mfdbd imagesize allot mfdbd ! vr_trnfm mfdbd mfdbs fillmfdb then |
If the computer has a graphic card and the currunt mode has 4 or 8 planes, then we must turn the bloc
to the VDI independant format, else the TRM won't work.
With the TC modes (15, 16, 24 and 32 bits) it perfectly handles the blocks.
|
||
Turning the block to 16 bits | |||
." Converting to 16 bits..." cr 16 mfdbd 12 + w! %b0100011 1 PALs PALd 3 t dotrm if exit else ." Dotrm Ok" cr then mfdbd mfdbs fillmfdb |
|
||
Saving to TGA 16 bits | |||
." Saving TGA 16 bits..." cr " I:\AAA.TGA" PALd 1 p dowim if exit else ." Dowim Ok" cr then |
|
||
Cleaning memory | |||
restore t modunload p modunload relative ; |
|