# Camel99 Forth Information goes here

Camel99 Forth Concatentive Programming ANS Forth

283 replies to this topic

### #201 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Wed Nov 14, 2018 9:23 PM

Trying to make Forth system that complies with the ANS/ISO Standard is not easy for a mediocre programmer like me.

While doing some work on creating a library file for "double" (32 bit) integers I had to check the definition of "M*/"

It means "mixed multiply and divide". It can be using for scaling large numbers.

Online I found this:

M*/

( d1 n1 +n2 -- d2 )

Multiply d1 by n1 producing the triple-cell intermediate result t. Divide t by +n2 giving the double-cell quotient d2.

An ambiguous condition exists if +n2 is zero or negative, or the quotient lies outside of the range of a double-precision signed integer.

LOL!  I could tell that might take me some time so... I opened GNU Forth and ran the decompiler "SEE" on "M*/" and am I GLAD I did!

```Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
SEE M*/
: m*/
>r s>d >r abs -rot s>d r> xor r> swap >r >r dabs rot tuck um* 2swap um* swap
>r 0 d+ r> -rot i um/mod -rot r> um/mod -rot r>
IF     IF     1 0 d+
THEN
dnegate
ELSE   drop
THEN ; ok
```

That is the longest definition of a Forth math operator I have ever seen! .

They would have found me dead at the keyboard trying to solve that one.

The good news is I only had to replace the 'i' in the code with R@, convert to upper case and it worked.

"Standards are great!  Everybody should have one"

Chuck Moore

P.S.  804 bytes is the compile size of the library

#### Attached Files

Edited by TheBF, Wed Nov 14, 2018 9:24 PM.

### #202 RickyDeanOFFLINE

RickyDean

Stargunner

• 1,081 posts

Posted Thu Nov 15, 2018 7:13 AM

Yep.. I like to see this worked through, I too though I am older, really just getting into programming (c#, JS, and so forth) like to see how you work though the problems to get this to work. After I get some more stuff done around the house and yard and get my hardware functioning again, can set aside time to do it, want to get into learning forth, so this is of benefit to me.

### #203 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Fri Nov 16, 2018 9:18 AM

I reference compiling times with CAMEL99 Forth in another post.

http://atariage.com/...kage/?p=4158546

Here is a video showing the process using some tools that measure elapsed time and printing the no. of lines compiled.

(The Forth elapsed timer adds a few hundred milli-seconds to the real time, but it's pretty close)

#### Attached Files

Edited by TheBF, Fri Nov 16, 2018 9:21 AM.

### #204 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Tue Nov 20, 2018 10:30 PM

One of the cool things that I see TI-99 programs written by experienced people is the use of custom fonts.

I downloaded the gif file library of fonts by Sometimes99er and it is amazing.

I brought some of those into Magellan to look at them and then exported some of them out as BASIC DATA.

This was not a perfect format for my Forth graphics wordset,  so I wrote a Forth word that would work a little better with that data requiring a little text search and replace.

I called it … wait for it …

CALLCHAR.     What would you call it?

It uses some stuff I made that CHOPS a string quickly and then I use the ANS Forth word >NUMBER  to convert  each 8 character HEX string into a 32 bit integer.

A font source code file using CALLCHAR looks like this:

```CR .( FONT277 for 32 column mode only)
NEEDS CALLCHAR FROM DSK2.CALLCHAR
\ character data
DECIMAL
33 S" 0010101010001000" CALLCHAR
34 S" 0024240000000000" CALLCHAR
35 S" 00247E24247E2400" CALLCHAR
36 S" 00083E283E0A3E08" CALLCHAR
37 S" 0062640810264600" CALLCHAR
( ETC...)```

CALLCHAR lets me INTERPRET a file of character definitions for the entire character set in about 10 seconds. (ASCII 33..127)

Remember that is reading a text file and interpreting it line by line in "normal" TI-99 speed. It uses no program memory permanently to do the job. Data goes directly into VDP RAM.

However 10 seconds is a long time.

Armed with my new DSRLINK courtesy the great people on Atariage, I thought I would try using the LOAD and SAVE functions of the file system.

This is an example of where Forth shows it's colours.  Because I had done all the work to define a little language to work with the PABs and call the DSRLINK here is all it took to make routines to LOAD and save directly to VDP memory from files.

Edit: fixed late night mistakes

```\ loadfile savefile utilties
HEX
0B CONSTANT W/O100  \ output, internal, relative, fixed 100
0D CONSTANT R/O100  \ input,  internal, relative, fixed 100

: SETPAB   ( VDPaddr count file\$ len mode -- ) (common factor for both routines)
[PAB FLG] VC!       \ set file access mode byte
[PAB FNAME] VPLACE  \ set file name
0 [PAB RECLEN] VC!    \ set rec. length to 0
[PAB REC#]  V!      \ set #bytes to save (int)
[PAB FBUFF] V! ;    \ set start address in VDP Ram (int)

: SAVE-FILE ( VDPaddr count file\$ len mode -- ior) (*ior: I/O response)
PSHPAB SETPAB  6 FILEOP ?FILERR  POPPAB ;

PSHPAB SETPAB  5 FILEOP ?FILERR  POPPAB ;
```

Using these commands I will create SAVE-FONT  LOAD-FONT commands like this:

```: SAVE-FONT ( file\$ len --)  800 400  2SWAP W/O100 SAVE-FILE ;
: LOAD-FONT ( file\$ len --)  800 400  2SWAP R/O100 LOAD-FILE ; \ edited the last typo
```

Where 800 is the pattern descriptor table and 400 is the 1K bytes, from character 0 to character 128 ASCII.

In testing the process loading a font is virtually instant, so I can include a font file in the Forth START file that loads when Forth boots up.

Now I have to decide which font to load... That might be harder for me to decide than writing the code!

Note:

The process will be to create source code files with help from Magellan, compile the files to VDP memory, then SAVE-FONT to a TI-99 binary file.

Edited by TheBF, Wed Nov 21, 2018 9:16 AM.

### #205 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Wed Nov 21, 2018 4:51 PM

Yep.. I like to see this worked through, I too though I am older, really just getting into programming (c#, JS, and so forth) like to see how you work though the problems to get this to work. After I get some more stuff done around the house and yard and get my hardware functioning again, can set aside time to do it, want to get into learning forth, so this is of benefit to me.

Hey Ricky Dean I re-read your post here and realized that if you download my instruction manual it might give you some insights in how I created this system.

If gives you some comparisons of the differences between programming Basic and programming in Forth.

https://github.com/b...ree/master/DOCS

But the best way to learn is to play with it while you read.

Let me know if you have any questions.

Brian

### #206 Lee StewartOFFLINE

Lee Stewart

River Patroller

• 3,946 posts
• Location:Silver Run, Maryland

Posted Wed Nov 21, 2018 6:08 PM

You should be able to use my fbForth font files (FBFONT, CHARA1FBF, CHAR@1FBF).  They are 1 KiB (128 chars) or 2 KiB (256 chars), with char 0 as the first byte.  If you find typical TI font files you can load them into the fbForth 2.0 font editor ( FONTED ), shift the frame offset for proper view and save them out in fbForth (Camel99) format.  Of course, you can edit individual characters, as well.

...lee

### #207 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Wed Nov 21, 2018 6:40 PM

You should be able to use my fbForth font files (FBFONT, CHARA1FBF, CHAR@1FBF).  They are 1 KiB (128 chars) or 2 KiB (256 chars), with char 0 as the first byte.  If you find typical TI font files you can load them into the fbForth 2.0 font editor ( FONTED ), shift the frame offset for proper view and save them out in fbForth (Camel99) format.  Of course, you can edit individual characters, as well.

...lee

Cool!  I didn't know you had that feature.  I have been editing up Asm data files exported from Magellan to get a some candidate fonts for general use.

It's a new world for me with the TI.

### #208 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Wed Nov 21, 2018 7:33 PM

Here is how the source code compiles and saves a Font file.

It's pretty convenient. This is FONT0230, but I tweaked the 'f',@ and '*" characters.

Spoiler

### #209 Lee StewartOFFLINE

Lee Stewart

River Patroller

• 3,946 posts
• Location:Silver Run, Maryland

Posted Wed Nov 21, 2018 9:41 PM

Here is how the source code compiles and saves a Font file.

It's pretty convenient. This is FONT0230, but I tweaked the 'f',@ and '*" characters.

Spoiler

Here are the character codes using fbForth 2.0’s CHAR :

Spoiler

After running the above code, I invoked the Font Editor with FONTED , but, alas, the Font Editor initializes by unconditionally changing to Graphics mode, which reloads the current, default font, overwriting the just changed character codes.  I should change the initializing code to not invoke Graphics mode if it is already there.  That way codes could be changed with the above Forth code and output to a font file from the Font Editor.

On second thought, it would be easy enough to write a word like yours that saves a font.  The Font Editor is, after all, for editing existing fonts.    There is already a way to change the current font by loading a font file, viz., “ USEFFL DSKn.<fontfile> ” followed by FNT .  And, if you only want to edit a font, it can be loaded into the Font Editor without changing the current, default font.  But, I digress...

...lee

### #210 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Thu Nov 22, 2018 7:41 AM

Here are the character codes using fbForth 2.0’s CHAR :

Spoiler

After running the above code, I invoked the Font Editor with FONTED , but, alas, the Font Editor initializes by unconditionally changing to Graphics mode, which reloads the current, default font, overwriting the just changed character codes.  I should change the initializing code to not invoke Graphics mode if it is already there.  That way codes could be changed with the above Forth code and output to a font file from the Font Editor.

On second thought, it would be easy enough to write a word like yours that saves a font.  The Font Editor is, after all, for editing existing fonts.  |   There is already a way to change the current font by loading a font file, viz., “ USEFFL DSKn.<fontfile> ” followed by FNT .  And, if you only want to edit a font, it can be loaded into the Font Editor without changing the current, default font.  But, I digress...

...lee

Ah well... If nothing else it keeps us thinking about system enhancements.  I am happy something I did struck a  little chord. :-)

I am always amazed at how difficult it is to keep all the assumptions we make in some kind of sensible balance. (regarding selecting graphics mode which  reloaded the font)

I have tried to for years to keep the Forth philosophy in mind and make words do something simple so I can re-combine them in different ways later, but it's still a challenge. It really flies in the face of current software trends but I think Chucks thinking has merit.

I attribute the conflict between the two camps to the fact that you can't "concatenate" (spelling checked) code together in conventional languages, like we can in Forth, so it's simpler to wrap things up in a big function and select code with input parameters.

But now I digress...

### #211 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Thu Nov 29, 2018 9:47 AM

I managed to get most of my Direct threaded Forth code to run.  I had made a lot of changes over the past year to the primary code base so it took a bit of work.

The only outstanding bug is CREATE DOES> which I don't think I had working before either.

The point of this post is to show the biggest difference between the two threading mechanisms.

CAMEL99 Forth has the 9901 internal timer running continuously without interrupts so your can grab a time stamp anytime you want with TMR@.

The good thing about this is that the timer can measure things with a 21.3 micro-second resolution.

The downside is that you can only measure things that happen in less than 325mS.

I used the timer to measure the speed of the "inner" interpreter in both Forth systems simply by compiling a word that calls the timer twice.

By subtracting the two values we get the speed it took for Forth to get from one Forth word to the next one.

The screen captures tell the story nicely.: ITC= 3 ticks or about 64 uS   vs  DTC= 2 ticks or about  43uS.

The direct threading mechanism is only 2 instructions vs 3 for indirect threading.

The good news about direct threading is that every CODE word created with Forth Assembler uses 2 LESS bytes.

The bad news about direct threading is that every Forth word uses 4 MORE bytes in the definition.

The net speed-up of empty loops is about 25% however with real applications it seems closer to 10%.

In a memory constrained system like TI-99  ITC is probably a better choice for most applications.

### #212 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Thu Nov 29, 2018 10:29 PM

I found a little benchmark program called BENCHIE.  I replaced the VALUE in the original with a variable to make it simpler to use across multiple Forth systems.

Here is code.  It iterates 65536 times from what I can understand.   or not :-)

```5 CONSTANT FIVE
VARIABLE VAR
HEX
: BENCHIE
DO
1
BEGIN
DUP SWAP DUP ROT DROP 1 AND
IF FIVE +
ELSE 1-
THEN VAR !
UNTIL
DROP
LOOP ;
```

Here are some results:

FB Forth          :47.2

Turbo Forth     :26.9

Camel99 ITC  : 28.3

Camel99 DTC :25.3

You can see the benefit of all those stack primitives living in scratch-pad RAM in Turbo Forth.

I believe FB Forth is slower because of the legacy threading mechanism used in Forth Interest Group (FIG) Forth.

Here is the published result for the only CPU from a similar era as 9900.

>  8051 ANS Forth (12 MHz 80C535): 126 bytes 15,8 sec

This makes the 9900 look pretty good, running 1/2 speed with 1/4 the clock speed!

Edited by TheBF, Thu Nov 29, 2018 10:31 PM.

### #213 Lee StewartOFFLINE

Lee Stewart

River Patroller

• 3,946 posts
• Location:Silver Run, Maryland

Posted Fri Nov 30, 2018 6:26 AM

I believe FB Forth is slower because of the legacy threading mechanism used in Forth Interest Group (FIG) Forth.

I would bet fbForth 2.0's slower performance will be improved by disabling its ISR.  It is not necessary unless speech or sound is to be processed.  The ISR can be disabled with

```HEX 0 83C4!
```

I probably should have disabled the ISR as the startup default. Oh, well.

...lee

### #214 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Fri Nov 30, 2018 7:27 AM

I would bet fbForth 2.0's slower performance will be improved by disabling its ISR.  It is not necessary unless speech or sound is to be processed.  The ISR can be disabled with

```HEX 0 83C4!
```

I probably should have disabled the ISR as the startup default. Oh, well.

...lee

I will try it, but I keep interrupts running all the time as well.

I forget the details but I remember reading a long time ago about the way FIG-FORTH does the entry routines for colon, variable, constant and user  have extra overhead.

For example here are my definitions for the various data "creators".  The runtime address  is compiled inline.

I believe that is different in FIG implementations.

```: CONSTANT  ( n --)  HEADER  COMPILE DOCON     , ;
: USER      ( n --)  HEADER  COMPILE DOUSER    , ;
: CREATE    ( -- )   HEADER  COMPILE DOVAR       ;
: VARIABLE  ( -- )   CREATE                  0 , ;
```

Edited by TheBF, Fri Nov 30, 2018 7:29 AM.

### #215 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Fri Nov 30, 2018 9:46 AM

Nov 30, 2018 V2.1.F  Camel99 Forth Update

• COMPILER CHANGE: To handle ITC and DTC versions the cross-compiler "word creators"
are kept in separate files and are included in the Forth system source code as required.
Documentation is forth coming.  See:  compiler/ITCTYPES.HSF  and compiler/DTCTYPES.HSF

• Source file CAMEL99F.HSF now has a compiler switch: SMALLER
• Uses more Forth words to save space when set to TRUE
• Uses more CODE words if SMALLER is set to FALSE. SMALLER saves ~46 bytes, but runs a little slower.

information into binary font files that load into VDP ram in 1 second.

• Font file source code examples are in FONTS folder. Compiled binary versions are in DSK3.

*Note* CREATE DOES> is not functional in the DTC version at this time.

Edited by TheBF, Fri Nov 30, 2018 9:47 AM.

### #216 WillsyOFFLINE

Willsy

River Patroller

• 3,100 posts
• Location:Uzbekistan (no, really!)

Posted Fri Nov 30, 2018 3:04 PM

Here are some results:

FB Forth          :47.2
Turbo Forth     :26.9
Camel99 ITC  : 28.3
Camel99 DTC :25.3

You can see the benefit of all those stack primitives living in scratch-pad RAM in Turbo Forth.
I believe FB Forth is slower because of the legacy threading mechanism used in Forth Interest Group (FIG) Forth.

Here is the published result for the only CPU from a similar era as 9900.
>  8051 ANS Forth (12 MHz 80C535): 126 bytes 15,8 sec

This makes the 9900 look pretty good, running 1/2 speed with 1/4 the clock speed!

Yay! Go TurboForth. You're correct of course. This particular routine is performing a fair amount of stackrobatics in the loop, which TF will benefit from. If this were a demo of something like... Oh I dunno, calculating PI using fixed point (for example) then all bets are off!

While I'm here, I'd like to apologise for my lack of input to Atariage. I'm still lurking here almost every day, however my life has entered a particulalry busy stage at the moment. I'm (happily) married with two young children still at home, and I work away during the week, so weekends are all about the wife and children. They're only little once and I want to enjoy it. I'm also undertaking a Masters degree with the University of Liverpool (Software Engineering) and it's very demanding as you can imagine. I don't have a lot of head-space for hobby things right now, more's the pity. However, please rest assured I'm still lurking, especially the Forth threads, which is my main area of interest now on the TI, and on CLF.

Cheers

Mark

### #217 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Fri Nov 30, 2018 7:43 PM

"I'm also undertaking a Masters degree with the University of Liverpool (Software Engineering) and it's very demanding as you can imagine. "

Hey Mark,

Does your thesis have anything to do with Forth or stack machines?

B

Edited by TheBF, Fri Nov 30, 2018 7:43 PM.

### #218 WillsyOFFLINE

Willsy

River Patroller

• 3,100 posts
• Location:Uzbekistan (no, really!)

Posted Sat Dec 1, 2018 10:24 AM

He he! Im only just past the first module so I have a ways to go before I have to worry about that; but yes - Id like to work on something with a Forthy flavour. Forth for mission-critical systems is of particular appeal.

Mark

### #219 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Sat Dec 1, 2018 2:07 PM

I saw an blank spot on Rosetta code for the Magic8ball program in Forth so I took up the challenge using a variation of a fast case statement/vector table invented by the late James T. Kalihan the author of HsForth.

It works a little like ONGOTO in BASIC but instead of line numbers it use the ** "execution token" of a Forth word and "EXECUTEs" it.

** (a memory address in CAMEL99 Forth)

I love the simplicity of it.

Here is the CAMEL99 Forth version.

```\ magic eight ball Rosetta Code

INCLUDE DSK1.RANDOM

\ for GFORTH
\ INCLUDE RANDOM.FS

DECIMAL
: CASE:  ( -- -7)   CREATE   ;
: ;CASE   ( n -- )  DOES>  SWAP CELLS +  @ EXECUTE ;

: VECTORS  0  DO  , LOOP ;

:NONAME   ." It is certain" ;
:NONAME   ." It is decidedly so" ;
:NONAME   ." Without a doubt" ;
:NONAME   ." Yes, definitely" ;
:NONAME   ." You may rely on it" ;
:NONAME   ." As I see it, yes." ;
:NONAME   ." Most likely" ;
:NONAME   ." Outlook good" ;
:NONAME   ." Signs point to yes." ;
:NONAME   ." Yes." ;
:NONAME   ." Reply hazy, try again" ;
:NONAME   ." Ask again later" ;
:NONAME   ." Better not tell you now" ;
:NONAME   ." Cannot predict now" ;
:NONAME   ." Concentrate and ask again" ;
:NONAME   ." Don't bet on it" ;
:NONAME   ." My reply is no"  ;
:NONAME   ." My sources say no" ;
:NONAME   ." Outlook not so good" ;
:NONAME   ." Very doubtful" ;

CASE: MAGIC8BALL  20 VECTORS  ;CASE

: GO
CR ." Please enter your question or a blank line to quit."
BEGIN CR ." ? :" PAD 80 ACCEPT 0>
WHILE CR 19 RND MAGIC8BALL CR
REPEAT ;
```

#### Attached Files

Edited by TheBF, Sat Dec 1, 2018 2:19 PM.

### #220 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Thu Dec 6, 2018 9:39 PM

A Better Elapsed Timer

I was looking at an old copy of  **"STARTING FORTH" the seminal training text book to study to get acquainted with Forth. It demonstrated  a time formatting number that used BASE 60 to compute the correct digits for minutes and hours.

Huh!  I had not remembered that from 1985 when I bought the book

If you compare the code here: http://atariage.com/...here/?p=3935777

You can see the simplification with this version.

The input parameter is an integer in hundredths of a second.

After formatting  hundredths and tenths as DECIMAL digits, we switch to SEXTAL math and the # routine computes the correct digits for minutes.

Amazing!

```HEX
83D6 CONSTANT TICKER   \ screen timeout counter increments by 2 /16mS
DECIMAL
: SEXTAL   60 BASE ! ;
: ':'     [CHAR] : HOLD ;
: '.'     [CHAR] . HOLD ;

: .TIME   ( n -- )
BASE @ >R    ( save the current number base on return stack)
0 <#  DECIMAL # # '.'  # # ':' SEXTAL # #   #> TYPE
R> BASE ! ;  (  restore the old number base from return stack)

: .ELAPSED ( -- )  CR ." Elapsed time =" TICKER @ 5 6 */ .TIME ;

: ELAPSE   ( -- <text> ) 1 PARSE  TICKER OFF  EVALUATE .ELAPSED ;
```

The secret lies in the Forth number formatting words which are so deceptively simple it's hard to believe they create arbitrary number formatting in about 120 bytes of code!

Rather than use patterning matching like most languages use (###.##)  Chuck Moore does it with simple code routines.

The one thing that puts people off is that the number is formatted from the smallest values to the largest which is right to left.

BUT the code runs from left to right so you have to think of the number backwards to understand the code format.  Hey,  "Forth though is this!"

For the very curious the spoiler has the formatting words with comments about these functions.

If you study them, they could be implemented in assembly language without much problem.

Spoiler

*** Edit fixed the book title Starting Forth, Leo Brodie

Edited by TheBF, Fri Dec 7, 2018 6:51 AM.

### #221 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Thu Dec 13, 2018 10:10 AM

Forced to drink my own Koolaid

I have a dream of running CAMEL Forth from my PC over the RS232 port.  I did this many years ago with TI Forth with a 2nd hand dumb terminal that I found at an electronics surplus store. At that time I didn't understand how to vector the I/O primitives so I wrote a lot more code than necessary but it was fun.

CAMEL99 Forth steals the top part of scratch pad for user variables. (task specific variables)

This means, from what I can read, that the RS232 DSR will not work. An in fact the RS232 DSR is not ideal for a multi-tasking Forth system.  I need primitives that will give up the system while they are waiting for I/O to complete.

No problem. I will just write my own 9902 chip driver thought I.

Doing that has forced me to develop on real hardware for the first time in a while.

What a shock!  Oh how I miss the built-in editor of TI-Forth.

In my initial thoughts on making a more modern Forth for TI-99 I believed that the "edit, load Forth, compile file, run code, loop" would be so much better than the Assembler process that it would be ok.  I forgot how slow the floppy disk really is.

(Note: I discovered that CAMEL99 Forth can compile a file from floppy disk in about the same time that EDIT1 takes to save that file to floppy disk.   It still sucks )

All that to say that I need to make an integrated editor for CAMEL99 Forth.  I am considering a few options:

1. Re-build EDIT40 as a binary "overlay" that I start from within Forth
2. Write a binary overly program in cross-compiled Forth
3. Write the editor in ANS Forth and have it compile into the system and stay resident.

I am leaning towards just writing it in ANS Forth.  I wrote a block editor 35 years ago for MVP Forth that I ported and added to

but I can see with new eyes that it is not great code so I think I start from scratch.

I have never written an editor for files and I can see there are some other considerations in a memory constrained system that I need to address. Forth BLOCKS are real virtual memory so it is much simpler.  However files offer advantages that I like.

So drinking my own Koolaid means I need to write an editor to be anywhere near as useful as the IDE provided by FBForth and TurboForth.

Such a humbling hobby is this...

### #222 Lee StewartOFFLINE

Lee Stewart

River Patroller

• 3,946 posts
• Location:Silver Run, Maryland

Posted Thu Dec 13, 2018 10:55 AM

Though it is a massive 2.3 KiB (in ROM space   ), you are certainly welcome to port the editor source code of fbForth 2.0 in fbForth105_Editor4080.a99.

...lee

### #223 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Thu Dec 13, 2018 12:16 PM

Though it is a massive 2.3 KiB (in ROM space   ), you are certainly welcome to port the editor source code of fbForth 2.0 in fbForth105_Editor4080.a99.

...lee

2.3Kb would not be unreasonable.

I am struggling with how to organize the different memory spaces for best use considering I want a resident editor and enough space to hold a reasonable file size.

Keeping the raw file data in VDP Ram is temping but I will have to do some tests with inserting variable lines lengths into VDP ram. That could be very slow.

The alternative is maintaining all the VDP text as linked lists which makes me weak in the knees.

I probably should just use low mem for the data and limit the file size to 6K bytes, keeping room there for an undo/copy/delete stack.

I have made a fast text file reader that moves the PAB file buffer through VDP ram depending on the length of the text line.

Probably the most innovative part of that is that I fill the VDP Ram with end-of-line delimiters, and then write over them.

This makes the data automatically delimited!

```HEX
0D CONSTANT ^M         \ carriage return
1A CONSTANT ^Z         \ end of Text file marker
1138 CONSTANT REC#1      \ Free VDP ram after pattern table
2500 CONSTANT MEM-SIZE   \ 9,472 bytes is largest file

VARIABLE ELINES     \ count editor lines

: READ-REC    ( -- ) 2 FILEOP ?FILERR ;
: NEXT-BUFFER ( -- )     \ advance buffer by rec. len+1
[PAB FBUFF]        \ current VDP buffer pointer
[PAB CHARS] VC@    \ fetch last line length
OVER V@ + 1+       \ calc. new buffer. 1+ makes room for ^M delimiter
SWAP V! ;          \ change the VDP buffer pointer

ELINES OFF
REC#1 MEM-SIZE ^M VFILL     \ fill space CR char
R/O OPEN-FILE ?FILERR  >R   \ file handle to rstack
REC#1 [PAB FBUFF] V!        \ set VDP buffer address
BEGIN
R@ EOF 0=
WHILE
ELINES 1+!
NEXT-BUFFER
REPEAT
R> CLOSE-FILE ;
```

### #224 TheBFOFFLINE

TheBF

Dragonstomper

• Topic Starter
• 960 posts
• Location:The Great White North

Posted Thu Dec 13, 2018 10:00 PM

Taming the TMS9902, FORTH Style

Many years ago I read an article in Forth Dimensions magazine called something like "Menu Driving the 8250 UART".

This really got under my skin because menus are not the way you do things with Forth.

In Forth you make WORDS to control the computer. Words are infinitely more useful than a menu driven program to setup a piece of hardware.

So I wrote a "counter-article" called "8250 UART Revisited.

In the article I detailed how to calculate the baud rate divisor for a given BAUD rate and showed words to configure the UART like this:

COM1: 9600 BAUD  8 BITS   EVEN PARITY  1 STOP-BITS

I think I have that working for 9902 now.  I shortened the name STOP-BITS to STOPS to save a few precious TI-99 bytes.

I further simplified the BAUD word by eliminating 110 BAUD and 300 BAUD.  I won't be using them,  however the programmer could manually set the BPS variable if that was needed.

The spoiler has the source for the entire RS232 driver. These will ultimately be used to create a TTY terminal task that will control the system from the comfort of my PC.

```HEX
1300 CONSTANT RS232    \ card address
RS232 40 + CONSTANT PORT1    \ 40= 9902#1,
RS232 80 + CONSTANT PORT2    \ 80= 9902#2

\ configuration variables
VARIABLE BPS         \ bits per sec
VARIABLE PROTOCOL    \ 8 BITS ODD PARITY
VARIABLE PORT

DECIMAL
: 499200. ( -- d) 40488 7 ;   \ double precision literal

: BAUD   ( n -- )
DUP 600 < ABORT" BAUD rate!"       \ 600..19200 only
499200. ROT UM/MOD NIP  BPS ! ;

: PROTOCOL! ( n -- ) PROTOCOL @ OR PROTOCOL ! ;

: STOPS  ( n -- ) \ bits 7 & 6
3 - ABS
2 OVER U< ABORT" stop bits!"
6 LSHIFT  PROTOCOL! ;

: BITS  ( n -- ) \ bits 1 & 0
5 -  4 OVER U< ABORT" data bits!"
PROTOCOL!  ;

2 BASE !
00010000 CONSTANT NO
00100000 CONSTANT EVEN
00110000 CONSTANT ODD

HEX
: PARITY  ( n -- ) \ bit 5 & 4
DUP NO ODD 1+ WITHIN 0= ABORT" Bad parity!"
PROTOCOL! ;
```
Spoiler

### #225 WillsyOFFLINE

Willsy

River Patroller

• 3,100 posts
• Location:Uzbekistan (no, really!)

Posted Fri Dec 14, 2018 6:44 AM

Phwoar! This is really cool. I never got a chance to look at serial. Do you mind if I use this this code (with attribution, of course) for TurboForth?

Would you mind posting some example outputs from BAUD (i.e the value that gets written into BPS) for some example baud rates? I need to check UM/MOD implementation in TF :-)

Also, can you post your code for MS if you don't mind? :-)

It'll give me something to look at over Christmas (along with Lee's recent work of CF7 and variants) now that uni has stopped until January.

Thanks

Mark

Edited by Willsy, Fri Dec 14, 2018 6:44 AM.

### Also tagged with one or more of these keywords: Camel99, Forth, Concatentive Programming, ANS Forth

#### 0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users