Jump to content
IGNORED

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


Lee Stewart

Recommended Posts

I get it now. You are fixing a long standing non-compliance of TI-FORTH versus the Fig-Forth standard. 

 

From Fig-Forth Glossary

VOCABULARY                                    E,L
        A defining word used in the form:
                     VOCABULARY cccc
        to create a vocabulary definition cccc. Subsequent use of cccc will
        make it the CONTEXT vocabulary which is searched first by INTERPRET.
        The sequence "cccc DEFINITIONS" will also make cccc the CURRENT
        vocabulary into which new definitions are placed.

        In fig-FORTH, cccc will be so chained as to include all definitions
        of the vocabulary in which cccc is itself defined. All vocabularys
        ultimately chain to Forth. By convention, vocabulary names are to be
        declared IMMEDIATE. See VOC-LINK.
Link to comment
Share on other sites

4 minutes ago, TheBF said:

By convention, vocabulary names are to be declared IMMEDIATE . See VOC-LINK .

 

I actually got it from the TI Forth glossary, but that obviously came from your reference. While all vocabularies are declared IMMEDIATE , what I do not understand is why VOCABULARY itself is not IMMEDIATE in TI Forth (and fbForth by inheritance). Here is what Derrick and Baker’s FORTH Encyclopedia (figForth with Forth-79 comparisons) comments after presenting their definition of VOCABULARY and their IMMEDIATE declaration following it, VOCABULARY is a defining word and therefore must execute during compilation (Sequence 2) so that it can compile other definitions”. Do you think I should make VOCABULARY an immediate definition for fbForth 2.1?

 

...lee

  • Like 1
Link to comment
Share on other sites

26 minutes ago, Lee Stewart said:

 

Do you think I should make VOCABULARY an immediate definition for fbForth 2.1?

 

...lee

Probably, if only to be an accurate version of Fig-Forth. 

 

I am looking around for these discussions on the pros and cons and have not found anything.

 

It looks like FORTH79 broke with immediate vocabularies


https://www.complang.tuwien.ac.at/forth/fth79std/FORTH-79.TXT

VOCABULARY                                   208
     A defining word executed in the form:
          VOCABULARY  <name>
     to  create (in the CURRENT vocabulary) a dictionary entry  for
     <name>,   which   specifies  a  new  ordered  list   of   word
     definitions.   Subsequent execution of <name> will make it the
     CONTEXT   vocabulary.    When   <name>  becomes  the   CURRENT
     vocabulary (see DEFINITIONS), new definitions will be  created
     in that list.

     In lieu of any further specification, new vocabularies 'chain'
     to  FORTH.   That  is,  when  a dictionary  search  through  a
     vocabulary is exhausted, FORTH will be searched.
  • Like 1
Link to comment
Share on other sites

13 minutes ago, atrax27407 said:

I have your fbFORTH Vn 2.1 up and running on my MAME/HSGPL system. I still have some tweaks to do with it (like my customized menu) but otherwise it seems fine.  

 

How do you like the auto-repeat at the command line?

 

FYI (I don’t think I documented this yet), if you do not want the auto-repeat, store an odd number at DCT + 16:

901 DCT 16 + !

This initial start-repeat count gets stored in the repeat counter and is decremented by 2, so an odd number there will never reach 0 to repeat.

 

...lee

  • Like 2
Link to comment
Share on other sites

1 hour ago, atrax27407 said:

Auto-repeat works fine and I have the menu ported over. Since I'm using both Vn 2.0:13 and 2.1 in the same system, I renamed the new FBLOCKS to FBLOCKZ (they are on the same disk drive). I'll give it a thorough "shake down" in a day or so.

 

I have a lot more changes to make, but certainly, if you find a glitch, I want to know. :)

 

...lee

  • Like 1
Link to comment
Share on other sites

I have enough memory in the cartridge to add UDSQRT ( ud -- u ) [see post #1652ff], which I think I will do.

 

My question (asked before) is whether I should now change SPRDIST and SPRDISTXY to return actual distances rather than their squares. One argument in favor of the change is that all distances will be returned correctly rather than limited to 181. After all, on-screen distances can be as high as 220 and the maximum distance (including off-screen sprites) as high as 360. I will likely leave DXY as is, but I am really leaning to changing those other two definitions. Thoughts—especially in light of the fact that I no longer use the square of the distance for COINC or COINCXY ?

 

...lee

Link to comment
Share on other sites

1 hour ago, Willsy said:

Well, define 'distance'! Mean, one could determine the distance (in pixels) by simply subtracting the x and/or y coordinates from each other. Does it really need a dedicated word to do that? Unless I'm missing something.

 

Distance = √((x1x2)2 + (y1 - y2)2).

 

...lee

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

What is entailed in calling the FP routines in ROM directly from assembly code, rather than using XMLLNK? I would expect to have to place the appropriate arguments in FAC and ARG, set a workspace, BL to the start of the routine in ROM, restore the original workspace upon return to my code, then look for my result in FAC. 

 

for:

     BLWP @XMLLNK

     DATA >0800        (FMUL)

 

I substituted:

 

    LWPI  CALCWS      (workspace reserved for calculations)

    BL      @>0E88      (start of FMUL routine, per TI Intern)

    LWPI  MAINWS      (restore original workspace)


Doesn't seem to fly.  Am I missing something simple?  Or just being simple?  

 

Link to comment
Share on other sites

Not sure if this will help...

 

Disassembly of MINIMEMORY's XMLLNK:

 

Spoiler

---------------------------------------------
   *CONTEXT SWITCH VECTOR*

   601C  8020  *WS
         60C8  *ENTRY ADDRESS

---------------------------------------------
   *XMLLNK FROM MINIMEMORY

   60C8  C83E  mov  *R14+,@>83e2          
         83E2
   60CC  02E0  lwpi >83e0                 
         83E0
   60D0  C80B  mov  R11,@>70a8            
         70A8
   60D4  C081  mov  R1,R2                 
   60D6  0281  ci   R1,>8000              
         8000
   60DA  1B07  jh   >60ea                 
   60DC  09C1  srl  R1,12                 
   60DE  0A11  sla  R1,1                  
   60E0  0A42  sla  R2,4                  
   60E2  09B2  srl  R2,11                 
   60E4  A0A1  a    @>0cfa(R1),R2         
         0CFA
   60E8  C092  mov  *R2,R2                
   60EA  0692  bl   *R2                   
   60EC  02E0  lwpi >8020                 
         8020
   60F0  C80B  mov  R11,@>83f6            
         83F6
   60F4  0380  rtwp

-----------------------------------------------

 The XMLLNK table entry for FMULT seems to be located at >0D2A...

   0D1A  0000  data >0000                 
   0D1C  0F54  data >0f54                 
   0D1E  0FB2  data >0fb2                 
   0D20  0FA4  data >0fa4                 
   0D22  0FC2  data >0fc2                 
   0D24  0FCC  data >0fcc                 
   0D26  0D80  data >0d80                 
   0D28  0D7C  data >0d7c                 
   0D2A  0E88  data >0e88                 
   0D2C  0FF4  data >0ff4                 
   0D2E  0D3A  data >0d3a                 
   0D30  0D84  data >0d84                 
   0D32  0D74  data >0d74                 
   0D34  0E8C  data >0e8c                 
   0D36  0FF8  data >0ff8                 
   0D38  0D46  data >0d46                 

 

 

This might have the info you seek...

 

Floating point numbers calculations (From: The TI-99/4A Tech Pages):ponder:

Edited by HOME AUTOMATION
Link to comment
Share on other sites

3 hours ago, Tursi said:

I believe you need to load GPLWS - XMLLNK doesn't keep the BLWP workspace for long. Assuming you have the entry address right, seems like that's all that is needed from looking at the EA and XB XMLLNK...?

 

I've had success at least with the float to int routine this way. 

 

https://github.com/jedimatt42/fcmd/blob/04f5d2f32f5df70288e39b74cc47c326aadc6309/b2_tifloat.c#L57

  • Like 1
Link to comment
Share on other sites

BL with >83E0 set up as the WS works fine for addition, subtraction, multiplication and division (I haven't tested anything else). Unfortunately, the actual increase in speed is minimal - on the order of 2% or so. This in a routine using Newton's method to calculate square roots that doesn't do much more than iteratively call FP arithmetic operations. A positive way of saying that is that the relative cost of BWLP @XMLLNK is apparently minimal. (Still, the routine is faster than calling the GPL routine for square root.)

 

What I would really like is access to the Cortex Basic FP routines. On a 16-bit console running an algorithm with a lot of floating point, Cortex Basic (executing out of a FinalGrom) is actually much faster than the console routines called from assembler! Plus it includes equally fast transcendental routines. Sigh.  

Link to comment
Share on other sites

14 hours ago, Reciprocating Bill said:

What is entailed in calling the FP routines in ROM directly from assembly code, rather than using XMLLNK? I would expect to have to place the appropriate arguments in FAC and ARG, set a workspace, BL to the start of the routine in ROM, restore the original workspace upon return to my code, then look for my result in FAC. 

for:

     BLWP @XMLLNK

     DATA >0800        (FMUL)

I substituted:

    LWPI  CALCWS      (workspace reserved for calculations)

    BL      @>0E88      (start of FMUL routine, per TI Intern)

    LWPI  MAINWS      (restore original workspace)

Doesn't seem to fly.  Am I missing something simple?  Or just being simple?  

 

XMLLNK is used to compute the execution address of the desired routine. It figures out whether the address is in a vector table or is a direct address. If from a vector table, it grabs the execution address from the appropriate table and does a BL to it:

XMLLNK DATA UTILWS,XMLENT   ; Link to ROM routines
*
*  . . .
*
*== XMLENT -- Link to system XML utilities ==============
*
XMLENT MOV  *R14+,@GPLWS+2      Get argument
       LWPI GPLWS               Select GPL workspace
       MOV  R11,@UTILWS+22      Save GPL return address
       MOV  R1,R2               Make a copy of argument
       CI   R1,>8000            Direct address in ALC?
       JH   XML30               We have the address
       SRL  R1,12
       SLA  R1,1
       SLA  R2,4
       SRL  R2,11
       A    @XMLTAB(R1),R2
       MOV  *R2,R2
XML30  BL   *R2
       LWPI UTILWS              Get back to right WS
       MOV  R11,@GPLWS+22       Restore GPL return address
       RTWP

If you already know the execution address, you certainly can perform your own BL—after appropriate setup of FAC, ARG, ..., of course. You need to BL from the GPL workspace (GPLWS = >83E0) after saving the GPLWS R11 before executing the routine and restoring it upon return.

 

For example, FMUL can be executed as follows:

MYWS   BSS  32       put in available RAM
GPLWS  EQU  >83E0
FAC    EQU  >834A
ARG    EQU  >835C
FPERR  EQU  FAC+10
SAVRET EQU  >3000    change to available RAM
GPLRET EQU  >3002    change to available RAM
FMUL   EQU  >0E88    console address of FMUL routine
*
*  . . .
*
*== FMUL -- Console ROM FP Multiply ==============
*
*  Inputs:
*        FAC: Multiplier
*        ARG: Multiplicand
*  Outputs:
*        FAC: Product
*     FAC+10: Error (also can check GPL status byte at >837C)
*
FPMPY  LWPI GPLWS             select GPL workspace
       MOV  R11,@GPLRET       save GPL return address
       BL   @FMUL             branch to console FMUL
       MOV  @GPLRET,R11       restore GPL return address
       LWPI MYWS              get back to right WS
       RT                     return to caller

...lee

  • Like 1
Link to comment
Share on other sites

1 hour ago, Reciprocating Bill said:

BL with >83E0 set up as the WS works fine for addition, subtraction, multiplication and division (I haven't tested anything else). Unfortunately, the actual increase in speed is minimal - on the order of 2% or so. This in a routine using Newton's method to calculate square roots that doesn't do much more than iteratively call FP arithmetic operations. A positive way of saying that is that the relative cost of BWLP @XMLLNK is apparently minimal. (Still, the routine is faster than calling the GPL routine for square root.)

 

What I would really like is access to the Cortex Basic FP routines. On a 16-bit console running an algorithm with a lot of floating point, Cortex Basic (executing out of a FinalGrom) is actually much faster than the console routines called from assembler! Plus it includes equally fast transcendental routines. Sigh.  

Do we know what format Cortex FP uses?  TI-99 is a very big format with decimal coded numbers. 8 bytes long.

You can do very "adequate" FP with 16 bit mantissa and 16 bit exponent that could run much faster but of course not as accurate at TI-99's numbers.

Link to comment
Share on other sites

  • 3 weeks later...
On 3/15/2022 at 7:29 PM, Reciprocating Bill said:

1662753989_CortexFPformat.thumb.png.3668ca5520d141b6ccd83f641fd8eda2.png

 

This is 7 bits less precision than TI’s radix-100 representation and 10100 narrower range of numbers, i.e., the range of numbers is 16-65 < n < 1664 or about 10-80 < n < 1078, whereas the radix-100 range is 100-65 < n < 10064 or 10-130 < n < 10128.

 

...lee

  • Like 1
Link to comment
Share on other sites

I just realized that the definition for WLITERAL I posted in another thread is inefficient. Instead of

: WLITERAL  ( --- [] | [addr] )  ( IS: <blank-delimited string>)
   BL STATE @
   IF
      COMPILE SLIT TOKEN
   ELSE
      TOKEN
   THEN
;  IMMEDIATE

I should have written it as

: WLITERAL  ( --- [] | [addr] )  ( IS: <blank-delimited string>)
   BL STATE @
   IF
      COMPILE SLIT
   THEN
   TOKEN
;  IMMEDIATE

While I am working on fbForth 2.0, I should probably review all of the high-level Forth words in the kernel for similar inefficiencies.

 

...lee

Link to comment
Share on other sites

Dxforth author Ed, is always writing on the evils of ELSE. :) 

Not applicable with WLITERAL since you need the TOKEN to execute as well. 

 

He mostly uses the word END instead, which combines EXIT ( figForth ;S I think) and THEN .

 

 

I just tried Ed's END word like this on FbForth and it seems to work.


:  END   COMPILE ;S [COMPILE] THEN ; IMMEDIATE 


: TEST   IF  ." TRUE"  END  ." FALSE" ; 

The idea being I guess that the most often used choice can run and get out ASAP.

 

  • Like 2
Link to comment
Share on other sites

7 hours ago, Lee Stewart said:

This is 7 bits less precision than TI’s radix-100 representation and 10100 narrower range of numbers, i.e., the range of numbers is 16-65 < n < 1664 or about 10-80 < n < 1078, whereas the radix-100 range is 100-65 < n < 10064 or 10-130 < n < 10128.

It's speed versus range/precision. Depends on what's important to your application.

 

On the speed side, Cortex BASIC running out of a FinalGrom is 1.5x - 1.8x faster than TI BASIC performing addition, subtraction, multiplication and division (which is slightly faster than Extended BASCI for these operations). SQR(), SIN() and COS() in Cortex BASIC are 3-4x faster than those functions in TI Extended BASIC.

 

The occasion for all this for me was my implementation of a simple star cluster simulation described in a 1986 Scientific American article (Computer Recreations, Jan 1986). I wrote an assembler version that calls the console ROM for floating point arithmetic (and rolled my own SQR routine to avoid calling the slow GPL square root routine), but no matter how I slice it (including bypassing XMLLNK) the simulation runs/calculates much more quickly in Cortex BASIC than in assembly! Not something you see every day. So it would be cool if the Cortex FP routines were accessible for calls from assembly - or from Forth! 

 

(One caveat: the above numbers apply to a console with 16-bit memory, which speeds Cortex BASIC, even when running out of a FinalGrom, but doesn't much benefit the TI BASICs.)

 

Edited by Reciprocating Bill
Word salad
  • Like 4
Link to comment
Share on other sites

  • 2 weeks later...

Here is the next alpha of fbForth 2.1 (build #). In addition to the changes in build @, it adds the following:

  • The cursor used by KEY is now the inverse of the character under the cursor. This is most apparent in the 40/80 column editor.
  • Rewrote WLITERAL per discussion somewhere above.
  • Rewrote zero-compare words, 0= , 0< , 0> , for efficiency.

fbForth210_9.bin      fbForth210_8.bin     fbForth210.rpk

 

...lee

 

  • Like 2
  • Thanks 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...