Jump to content

Photo

fbForth—TI Forth with File-based Block I/O [Post #1 UPDATED: 12/12/2018]

fbForth Forth TI Forth

1537 replies to this topic

#1526 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 963 posts
  • Location:The Great White North

Posted Wed Mar 6, 2019 7:45 AM

LOL.  That's a good analysis.  So you have put your finger on a proper partition.  I should begin thinking about overview and you can be the detail guy.

Where I have an idea on a detail you can evaluate if that's how you want to build it but we can leave those decisions to you.

 

I was feeling a little ill last night so I didn't get much accomplished but I noticed the use of ON GOSUB in the game.  Here is a fast Vector CASE statement that I saw in HsForth and is also used by others.  I tried to make it work with FBForth quickly bit it didn't work with <BUILDS  DOES>.

 

Perhaps because DOES> is used outside the original colon definition. ?

 

This might useful later after everything is working.  However I did play the game for a while last night and I think the speedups in Forth and the freedom to go beyond arrays will make it work well.

 

So my first overview request is let's:  "make it work, then make it better" Steve Jobs. 

 

Meaning nothing to fancy out of the gate , just use Forth, create some meta words to handle the complexity and on we go.

\ FAST vector table from HsForth, Jim Kalihan (RIP)
\ no speed difference versus  CASE OF ENDOF  etc.. for 2 items
\ improves greatly with long list of cases.

: CASE:  ( -- -7)   CREATE   ;
: |      ( <name> )  '  ,  ;
: ;CASE   ( n -- )  DOES>  OVER + + @ EXECUTE ;  \ !! no runtime error checking !!

\ example code:
\ : FOO   ." FOO" ;
\ : BAR   ." BAR" ;
\ : FIZZ  ." FIZZ" ;
\ : BUZZ  ." BUZZ" ;

\ CASE: CHOICE  ( n -- ) | FOO  | BAR | FIZZ | BUZZ  ;CASE
\ Usage:   3 CHOICE  ( executes BUZZ)

\ equivalent with Eaker CASE statement
\ : TEST
\         CASE
\           0 OF  FOO ENDOF
\           1 OF  BAR ENDOF
\           2 OF FIZZ ENDOF
\           3 OF BUZZ ENDOF
\         ENDCASE  ;


#1527 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 963 posts
  • Location:The Great White North

Posted Wed Mar 6, 2019 8:35 AM

"Also pondered how to handle restoring background when pieces are moved.  Thought of keeping a screen copy in RAM to grab those background pieces—only need 640 bytes.  There must be a way to simplify handling this 10x10 board with its 3x2 “squares”—even with its forbidden zones."

 

Yes you could even create a  screen stack in VDP ram using a single variable pointer and the BUFFER word for the transfers. 

It would let  you save/restore previous screens quickly.

\ untested idea (correct word names for FBForth names)
HEX 
2000 VARIABLE SCRSTK
 300 CONSTANT $300

: PUSHSCR    SCRTOP @ 79 BUFFER $300 VSBR 
             79 BUFFER SCRSTK $300 VSBW
             $300 SCRSTK +1 ;

: POPSCR     SCRSTK 79 BUFFER $300 VSBR
             79 BUFFER SCRTOP $300 VSBW  
             $300 MINUS SCRSTK +! ;             

To manage the screen and piece movement it would be nice to have a set of words that lets you abstract all that detail away for moving things around.

: PIECE: ( arg arg arg arg -- )
         <BUILDS  ....   \ build a data structure of a given piece with all fields
         DOES>  ( return my address ;

\ From Wikipedia
\ RANK          NAME      COUNT    FEATURE
\ ---------------------------------------------
\ B	        Bomb	   6     Immovable; defeats any attacking piece except Miner
\ 10 or 1	Marshal	   1     Can be captured by the Spy
\ 9 or 2	General	   1     	
\ 8 or 3	Colonel	   2     	
\ 7 or 4	Major	   3     	
\ 6 or 5	Captain    4	
\ 5 or 6	Lieutenant 4	
\ 4 or 7	Sergeant   4	
\ 3 or 8	Miner	   5	Can defuse bombs
\ 2 or 9	Scout	   8	Can move any distance in a straight line, without leaping over pieces / lakes
\ 1 or S	Spy	   1	Can defeat the Marshal, but only if the Spy makes the attack
\ F	        Flag	   1

: SHAPE:  ( n n n n n n -- ) <BUILDS , , , , , ,  DOES>  ;

HEX
A0 A1 A2 A3 A4 A5 A6 SHAPE: ABOMB
A7 A8 A9 AA AB AC AD SHAPE: AMARSHAL

\ piece type just return the correct args to make a piece 

\ rank1 rank2  motion special shape
\ ----- ----- ------- ------- -----
   B     B        0     0     ABOMB    PIECE: BOMB
   10    1        1     S     AMARSHAL PIECE: Marshal
   8     3        1     0     AGENEAL  PIECE: General
   7     4        1     0     AMAJOR   PIECE: Major

\ simple access to piece fields
: _RANK1   ( piece -- addr)  ;
: _RANK2   ( piece -- addr) 2+ ; 
: _MOTION  ( piece -- addr) 4 + ;
: _special ( piece -- addr) 6 + ;
: _shape   ( piece -- addr) 8 + ;

\ usage
BOMB _RANK1 @ .
Marshal MOTION @ . 

: DRAW-PIECE ( x y piece -- ) _SHAPE @ PLACE-PIECE ... ;
: MOVE-PIECE ( X Y piece -- ) ERASE-PIECE  _SHAPE @ DRAW-PIECE ... ;

\ etc...

Not fully thought out, but this is a way to make it more readable than using array indices.


Edited by TheBF, Wed Mar 6, 2019 8:42 AM.


#1528 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Wed Mar 6, 2019 11:00 AM

LOL.  That's a good analysis.  So you have put your finger on a proper partition.  I should begin thinking about overview and you can be the detail guy.

Where I have an idea on a detail you can evaluate if that's how you want to build it but we can leave those decisions to you.

 

I was feeling a little ill last night so I didn't get much accomplished but I noticed the use of ON GOSUB in the game.  Here is a fast Vector CASE statement that I saw in HsForth and is also used by others.  I tried to make it work with FBForth quickly bit it didn't work with <BUILDS  DOES>.

 

Perhaps because DOES> is used outside the original colon definition. ?

 

This might useful later after everything is working.  However I did play the game for a while last night and I think the speedups in Forth and the freedom to go beyond arrays will make it work well.

 

So my first overview request is let's:  "make it work, then make it better" Steve Jobs. 

 

Meaning nothing to fancy out of the gate , just use Forth, create some meta words to handle the complexity and on we go. 

 

<snip>

 

Sounds good to me.

 

Re <BUILDS DOES> , what you say about the split definition is, indeed, likely,  They “like” to be in the same word because DOES> compiles the address of an entry point into the inner interpreter that executes the cfa of the defining word.  CREATE also may not work the way you think it does.  However, one thing is definitely wrong:  In fbForth 2.0 (mostly figForth-based), tick ( ' ) yields the pfa (parameter field address) of a word not its cfa (code field address).  That said, tick looks for the word following it in the input stream, so you should probably use -FIND (works like BL WORD and is not immediate like tick) , the stack signature for which is ( -- false | [pfa len true] ).  Here are definitions that work in fbForth 2.0:

: CASE:  ( -- )  <BUILDS 0 , DOES> OVER + + @ EXECUTE ;

: |  ( -- )  (IS:<name> )
   -FIND IF
      DROP
   ELSE
      ' NOP
   THEN
   CFA ,  ;

: ;CASE  ( -- ) ;  <--does nothing but look pretty 

The execution of a word defined by CASE: requires the option number on the stack.  I could not figure out a useful function for ;CASE other than eye candy.

 

...lee



#1529 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Wed Mar 6, 2019 12:20 PM

Here is the STRATEGO blocks file with the splash screen followed by the startup screen before placement of random features:  Attached File  STRATEGOfbf_03.zip   2.05KB   0 downloads

 

If you put STRATEGO on DSK2, the following will start it:

USEBFL DSK2.STRATEGO
1 LOAD

...lee



#1530 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Wed Mar 6, 2019 1:46 PM

One more pass at the splash and opening screens:  Attached File  STRATEGOfbf_04.zip   10.07KB   2 downloads

 

You can compare four different ways of handling the splash screen.  The fastest is from files (be sure to point to the STRATEGO blocks file [see last post]):

1 LOAD

Compare this with loading from blocks:

6 LOAD 

Also from blocks, but not blanking the screen, with color table loaded first:

4 LOAD 

and with pattern table loaded first:

5 LOAD 

...lee



#1531 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 963 posts
  • Location:The Great White North

Posted Wed Mar 6, 2019 2:37 PM

I think we should use blocks throughout for V1.0 

Make it work.... (which you have done) 

 

I like the effect of blanking the screen until the image is ready to display.

 

Did any of my nonense about data structures resonate?  (I know none of it works as is)



#1532 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Wed Mar 6, 2019 3:51 PM

I think we should use blocks throughout for V1.0 

Make it work.... (which you have done) 

 

I like the effect of blanking the screen until the image is ready to display.

 

Did any of my nonense about data structures resonate?  (I know none of it works as is)

 

Indeed, it did.  I think that will eventually make it look like working on the 10x10 board it is—dealing with illegal moves. of course.

 

...lee



#1533 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 963 posts
  • Location:The Great White North

Posted Wed Mar 6, 2019 6:30 PM

 

Indeed, it did.  I think that will eventually make it look like working on the 10x10 board it is—dealing with illegal moves. of course.

 

...lee

 

Cool.  Yes we should be able to make it look very much like talking about the game in English. (Well maybe like Yoda speaks English) :-)



#1534 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 963 posts
  • Location:The Great White North

Posted Wed Mar 6, 2019 8:02 PM

Lee, 

 

Here is a working version of the faster case statement.  It seems to be about 2X faster than the Eaker CASE when selecting the 5th option.

Might help down the road.

 

Of course if we did the execution with DOES>ASM it would another 50% faster at least.

\ Vectored CASE for FbForth

: [']     -FIND SWAP DROP 0= IF ." ['] can't find" ABORT
          THEN CFA  ;
: |    [']  ,  ;

: CASE:  ( -- )  99 <BUILDS 0 ,  DOES> OVER + + @ EXECUTE ;
: ;CASE  ( -- ) 99 ?PAIRS ;

\ example code:
 : FOO   ." FOO" ;
 : BAR   ." BAR" ;
 : FIZZ  ." FIZZ" ;
 : BUZZ  ." BUZZ" ;

 CASE: CHOICE  ( n -- ) | FOO  | BAR | FIZZ | BUZZ | NOP ;CASE

\ Usage:   4 CHOICE  ( executes BUZZ)

\ equivalent with Eaker CASE statement
 : CHOICE2
         CASE
           1 OF  FOO ENDOF
           2 OF  BAR ENDOF
           3 OF FIZZ ENDOF
           4 OF BUZZ ENDOF
           5 OF NOP  ENDOF
         ENDCASE  ;
DECIMAL
: TEST1  10000 0 DO  5 CHOICE LOOP ;

: TEST2  10000 0 DO  5 CHOICE2 LOOP ;



#1535 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Wed Mar 6, 2019 9:01 PM

Brilliant!  Maybe we could use that first cell in the created word to store a choice limit.  I have not figured out yet how we would do that, but ....

 

Oh—and you can use ABORT" in ['] .

 

...lee



#1536 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Thu Mar 7, 2019 7:31 AM

Brilliant!  Maybe we could use that first cell in the created word to store a choice limit.  I have not figured out yet how we would do that, but ....

 

Oh—and you can use ABORT" in ['] .

 

...lee

 

OK...the following code, though a bit busy, stores a CASE: -defined word’s option count in its pfa and does runtime range checking:

\ Vectored CASE for fbForth with runtime error checking

: [']   -FIND SWAP DROP 0= ABORT" ['] can't find"  CFA  ;

: |   1 LATEST PFA +! ['] ,  ;

: CASE:  ( -- )  99 <BUILDS 0 ,  
   DOES> OVER OVER @ OVER < OVER 1 < OR ABORT" range!" + + @ EXECUTE ;

: ;CASE  ( -- )  99 ?PAIRS ;

...lee



#1537 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 963 posts
  • Location:The Great White North

Posted Thu Mar 7, 2019 7:38 PM

Not sure how far along you are with things but here is a way to do  PIECE:  SHAPE: that lets you build pieces and get the parts out them as well..

 

I also made CREATE: which works like ANS CREATE which can be handy for defining constant arrays at compile time.

The  "shapes" are actually byte counted strings  using BYTE,

So if there are other structures that work as counted string data you can 'CREATE:" those too.

\ PIECE array creation for Stratego in FbForth

: CREATE:   0 VARIABLE -2 ALLOT ;  \ works like ANS Create
: BOUNDS    OVER + SWAP ; \ handy for indexing through arrays in DO LOOPS

\ creates a byte counted string from stack data
: BYTES,  DUP C,  0 DO  C,  LOOP ;

: SHAPE:   CREATE:   6 BYTES, ;

\ 6 chars on stack
1 2 3 4 5 6 SHAPE: ABOMB

\ get ALL characters from a SHAPE
: _PARTS  ( piece -- c c c c c c) COUNT BOUNDS DO I C@ LOOP ; 


Edited by TheBF, Thu Mar 7, 2019 7:42 PM.


#1538 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

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

Posted Thu Mar 7, 2019 7:53 PM

I have done nothing but pitch horseshoes on the beach since my last post!

 

...lee







Also tagged with one or more of these keywords: fbForth, Forth, TI Forth

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users