Jump to content
IGNORED

fbForth—TI Forth with File-based Block I/O [Post #1 UPDATED: 06/09/2023]


Lee Stewart

Recommended Posts

5 hours ago, atrax27407 said:

Muchas gracias, Amigo! I have, however, found "a fly in the ointment". Blocks 70 and 71 BLK>file and FILE>BLK result in an error message and don't work properly.

 

My apologies! I actually have those working but forgot to compact and copy them to FBLOCKS. It will take me a little time to do that. In the meantime, here are the scripts:     b2fexp.fbf   f2bimp.fbf

 

...lee 

  • Like 1
Link to comment
Share on other sites

4 hours ago, Lee Stewart said:

And....  Here is the updated FBLOCKS:     FBLOCKS

 

...lee

I like having the 64 column editor drop down into the bottom window. Thanks!

I am having flashbacks to 1984. :)

I believe that editor was first developed by Dr. C. H. Ting, who passed away just last year.  It's a damned clever hack. 

  • Like 1
Link to comment
Share on other sites

Posted (edited)
5 hours ago, TheBF said:

I like having the 64 column editor drop down into the bottom window. Thanks!

 

The next version of FBLOCKS will also allow exiting the old way, but with CTRL+9:

 

Future exits from 64-column editor:

  • FCTN+9:  Exit editor to SPLIT2 SPLIT Text window
  • CTRL+9:  Exit editor to mode from which editor invoked

...lee

Edited by Lee Stewart
CORRECTION
  • Like 2
Link to comment
Share on other sites

I know I mentioned this before, but I am thinking seriously of booting up fbForth 3.0 without enabling the fbForth ISR. It is enabled in fbForth 2.0. Besides enabling execution of user ISRs, the only reason to have it enabled is to use the fbForth speech and sound engines. This does not affect the BEEP and HONK words. Of course, you can always do sound lists per the E/A manual, with or without the fbForth ISR. And, you can always re-enable the ISR by jamming the contents of user variable INTLNK into >83C4.

 

The fbForth ISR does not take a lot of time, but it is not nothing. If you don’t need it, it slows the system a touch. Of course, you can always disable it by storing 0 at >83C4.

 

What do you think?

 

...lee

Link to comment
Share on other sites

Over on comp.lang.forth sjack has been playing with Fig Forth and presented these little tools.

They seem to work perfectly on FbForth. 

 

Edit.  Fixed some case issues from the original text. 

\  by: sjack - Wed, 3 Apr 2024 03:59
\ Put aside all my extensions and explored using FigForth core
\ words only. Here are three of several things I found interesting:


Fig-Forth 1.0.A
( Example #1, Stash data stack items)


2 CONSTANT CELL

: XX S0 @ SP! ; 
: S0! S0 ! ; 
: !S0 TIB @ S0! ; 
: .S S0 @ BEGIN CELL - SP@ OVER < WHILE DUP ? REPEAT DROP ; 


( some stack items.............) 1 2 3 4 5 
.S 1 2 3 4 5
( stash them...................) SP@ S0! 
( use the stack................) 666 777 888 
.S 666 777 888 
( restore stashed items........) XX !s0
.S 1 2 3 4 5


( Example #2, Input counted string _directly_ into given storage area)


: CREATE: <BUILDS DOES> ; 
: := DP @ SWAP DP ! 1 WORD DP ! ; 


CREATE: FOO 64 ALLOT     ( storage area for counted string FOO)
FOO := Hello Chuck!
FOO COUNT CR TYPE  
Hello Chuck!

 

I didn't test this one.

** Be careful it will edit  disk block 60  which you don't want to do **


 

( Example #3, Easily edit block screen without editor)

0 60 (LINE) DROP 1024 BLANKS
0 60 (LINE) EXPECT ( FOO BAR ) 
1 60 (LINE) EXPECT : FOO ." foo " ; 
2 60 (LINE) EXPECT : BAR ." bar " ; 
UPDATE FLUSH
60 LIST 
SCR # 60
  0 ( FOO BAR )
  1 : FOO ." foo " ;
  2 : BAR ." bar " ;
  3 
  4 

 

  • Like 2
  • Confused 1
Link to comment
Share on other sites

7 hours ago, TheBF said:

Over on comp.lang.forth sjack has been playing with Fig Forth and presented these little tools.

They seem to work perfectly on FbForth. 

 

Edit.  Fixed some case issues from the original text. 

\  by: sjack - Wed, 3 Apr 2024 03:59
\ Put aside all my extensions and explored using FigForth core
\ words only. Here are three of several things I found interesting:


Fig-Forth 1.0.A
( Example #1, Stash data stack items)


2 CONSTANT CELL

: XX S0 @ SP! ; 
: S0! S0 ! ; 
: !S0 TIB @ S0! ; 
: .S S0 @ BEGIN CELL - SP@ OVER < WHILE DUP ? REPEAT DROP ; 


( some stack items.............) 1 2 3 4 5 
.S 1 2 3 4 5
( stash them...................) SP@ S0! 
( use the stack................) 666 777 888 
.S 666 777 888 
( restore stashed items........) XX !s0
.S 1 2 3 4 5


( Example #2, Input counted string _directly_ into given storage area)


: CREATE: <BUILDS DOES> ; 
: := DP @ SWAP DP ! 1 WORD DP ! ; 


CREATE: FOO 64 ALLOT     ( storage area for counted string FOO)
FOO := Hello Chuck!
FOO COUNT CR TYPE  
Hello Chuck!

 

I didn't test this one.

** Be careful it will edit  disk block 60  which you don't want to do **


 

( Example #3, Easily edit block screen without editor)

0 60 (LINE) DROP 1024 BLANKS
0 60 (LINE) EXPECT ( FOO BAR ) 
1 60 (LINE) EXPECT : FOO ." foo " ; 
2 60 (LINE) EXPECT : BAR ." bar " ; 
UPDATE FLUSH
60 LIST 
SCR # 60
  0 ( FOO BAR )
  1 : FOO ." foo " ;
  2 : BAR ." bar " ;
  3 
  4 

 

 

#1 works, but XX is superfluous. SP! is already defined to clear the stack by storing the contents of S0 in the stack pointer. XX pushes the contents of S0 and SP! wipes it out, i.e., does not use it—so no harm done. Also, .S , though not in figFORTH, is defined in fbForth (from TI Forth) and I like it better because it shows the stack as unsigned numbers. I do like your BEGIN...WHILE...REPEAT instead of the DO...LOOP of fbForth because it looks shorter.

 

#2 certainly works as written and, I must say, I like it a lot. I think, though, that I would define := as

: :=  DUP 1 WORD C@ 1+ + =CELLS DP !  ;

to make the string only as long as necessary. Of course, neither form is protected against a second invocation of := for the same string with a length beyond the original.

 

#3 does not work properly for 2 reasons: (1) EXPECT must be executed (last word on the line) before typing the text following it, i.e., nothing happens until <enter> is tapped at the end of the line, so the typed string is ignored while EXPECT awaits input. (2) EXPECT stores 2 nulls after the string is entered.

 

...lee

  • Like 1
Link to comment
Share on other sites

1 hour ago, Lee Stewart said:

I do like your BEGIN...WHILE...REPEAT instead of the DO...LOOP of fbForth because it looks shorter.

 

With a couple of changes ( CELL -   to   2-   and   ?   to   @ U. ), the following code is, indeed, shorter—16 bytes less!:

: .S  ( -- )
   CR ." | "  S0 @
   BEGIN
      2-  SP@ OVER <
   WHILE
      DUP @  U.
   REPEAT
   DROP  ;

 

...lee

  • Like 3
Link to comment
Share on other sites

10 hours ago, Lee Stewart said:

 

#1 works, but XX is superfluous. SP! is already defined to clear the stack by storing the contents of S0 in the stack pointer. XX pushes the contents of S0 and SP! wipes it out, i.e., does not use it—so no harm done. Also, .S , though not in figFORTH, is defined in fbForth (from TI Forth) and I like it better because it shows the stack as unsigned numbers. I do like your BEGIN...WHILE...REPEAT instead of the DO...LOOP of fbForth because it looks shorter.

 

#2 certainly works as written and, I must say, I like it a lot. I think, though, that I would define := as

: :=  DUP 1 WORD C@ 1+ + =CELLS DP !  ;

to make the string only as long as necessary. Of course, neither form is protected against a second invocation of := for the same string with a length beyond the original.

 

#3 does not work properly for 2 reasons: (1) EXPECT must be executed (last word on the line) before typing the text following it, i.e., nothing happens until <enter> is tapped at the end of the line, so the typed string is ignored while EXPECT awaits input. (2) EXPECT stores 2 nulls after the string is entered.

 

...lee

With number three you could make it work like the old "line" editing commands by adding a CR I think. 

: CLS    0 60 (LINE) DROP 1024 BLANKS ;
: P      ( n-- )  60 (LINE)  CR EXPECT ; 

 

Then edit away :) 

CLS
0 P
( THIS WILL GO TO THE TOP LINE ) 
2 P
: HELLO   CR ." HELLO WORLD" ;  ( tiniest editor ever) 

 

  • Like 2
Link to comment
Share on other sites

Regarding booting up fbForth with its ISR disabled, I will have PLAY , STREAM , SAY check for a cleared ISR hook (>83C4) and, upon seeing it cleared, exit the routine immediately. Do you think I should include a message such as, “ISR not active!” or just fail quietly?

 

...lee

Link to comment
Share on other sites

1 hour ago, Lee Stewart said:

Regarding booting up fbForth with its ISR disabled, I will have PLAY , STREAM , SAY check for a cleared ISR hook (>83C4) and, upon seeing it cleared, exit the routine immediately. Do you think I should include a message such as, “ISR not active!” or just fail quietly?

 

...lee

There is some S/W principle I have read that is something like "Do the expected thing". 

So I think a message is order since it will happen at run-time no? 

You could save a couple of bytes with "ISR missing" or "Bad ISR"  ?? 

  • Like 2
Link to comment
Share on other sites

5 hours ago, Lee Stewart said:

Regarding booting up fbForth with its ISR disabled, I will have PLAY , STREAM , SAY check for a cleared ISR hook (>83C4) and, upon seeing it cleared, exit the routine immediately. Do you think I should include a message such as, “ISR not active!” or just fail quietly?

 

...lee

 

4 hours ago, TheBF said:

There is some S/W principle I have read that is something like "Do the expected thing". 

So I think a message is order since it will happen at run-time no? 

You could save a couple of bytes with "ISR missing" or "Bad ISR"  ?? 

 

I added a routine to check for the ISR hook and, if not there, to call the fbForth ERROR word with the proper error message number to print “ISR?” after the usual “ERROR ?” and abort.

 

While adding the new message, I took the opportunity to shorten many of the messages. Now, even after adding the ISR checking routine to bank#0 and the code to call it to 3 words in the same bank, there are 256 bytes free! I should add that the free-space increase is due not only to message size reduction but also to some other changes such as the redefinition of .S and shortening of a handful of words to use newly added words.

 

There is still a little work before release. Here is the current state of the TODO list:   fbForth300_TODO.txt

 

...lee

  • Like 3
Link to comment
Share on other sites

One of my TODOs is to possibly change BRANCH and 0BRANCH to use absolute addresses (per @Willsy’s TurboForth) instead of an offset (per figFORTH/TI Forth/fbForth), but I really do not see the advantage except, possibly, at compile time, which does not seem that important. The difference at execution time is

       MOV  *IP,IP       <---IP is a register

versus

       A    *IP,IP       <---IP is a register

which take exactly the same amount of time, as far as I can tell. So, unless someone (@Willsy@Tursi? @matthew180? @jedimatt42? @apersson850? @TheBF? ??) can show me a significant difference in execution time, I am inclined to leave sleeping dogs lie—the mod would be significant!

 

...lee

  • Like 1
Link to comment
Share on other sites

12 hours ago, Lee Stewart said:

One of my TODOs is to possibly change BRANCH and 0BRANCH to use absolute addresses (per @Willsy’s TurboForth) instead of an offset (per figFORTH/TI Forth/fbForth), but I really do not see the advantage except, possibly, at compile time, which does not seem that important. The difference at execution time is

       MOV  *IP,IP       <---IP is a register

versus

       A    *IP,IP       <---IP is a register

which take exactly the same amount of time, as far as I can tell. So, unless someone (@Willsy@Tursi? @matthew180? @jedimatt42? @apersson850? @TheBF? ??) can show me a significant difference in execution time, I am inclined to leave sleeping dogs lie—the mod would be significant!

 

...lee

I did a similar study a while back and saw no advantage to changing to  absolute addresses and in fact if you wanted to relocate binary images of Forth code it's one less thing to worry about when you use relative branching. 

 

  • Thanks 2
Link to comment
Share on other sites

Been racking my brains to remember why I did it, but came up short. I *thought* I may have done it because it produced faster code, but as Lee has pointed out, it doesn't. Unless I did it under the mistaken assumption that the produced code was faster. The only other thing I can think of is perhaps it made the internal words that calculate jumps (that would be (IF) (THEN) and friends) a little bit shorter? I remember literally scouring the code base looking for ways to save single instructions here and there in order to fit some new word/feature into the 16K ROM space. :dunce:

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

3 hours ago, Willsy said:

Been racking my brains to remember why I did it, but came up short. I *thought* I may have done it because it produced faster code, but as Lee has pointed out, it doesn't. Unless I did it under the mistaken assumption that the produced code was faster. The only other thing I can think of is perhaps it made the internal words that calculate jumps (that would be (IF) (THEN) and friends) a little bit shorter? I remember literally scouring the code base looking for ways to save single instructions here and there in order to fit some new word/feature into the 16K ROM space. :dunce:

 

It does save 4 bytes where the jump calculation is performed in ENDIF and BACK , and obviates the need for BACK , which saves 18 bytes for a total savings in the resident dictionary of 26 bytes.

 

It also saves 2 trips through the inner interpreter in compiling LOOP +LOOP UNTIL AGAIN because  , replaces BACK (defined as  HERE - , ),  but time savings while compiling are not usually that important.

 

...lee

 

  • Like 1
Link to comment
Share on other sites

5 hours ago, Willsy said:

Been racking my brains to remember why I did it, but came up short. I *thought* I may have done it because it produced faster code, but as Lee has pointed out, it doesn't. Unless I did it under the mistaken assumption that the produced code was faster. The only other thing I can think of is perhaps it made the internal words that calculate jumps (that would be (IF) (THEN) and friends) a little bit shorter? I remember literally scouring the code base looking for ways to save single instructions here and there in order to fit some new word/feature into the 16K ROM space. :dunce:

Nice to see you back Mark. I suspect life has gotten in the way of the serious job of playing with Forth on a 40 year old machine. 

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...