Jump to content
IGNORED

Forth Tutorials


matthew180

Recommended Posts

One more thing to add to my last post that may be obvious but should probably be said:

 

A major difference between TI Forth (fig-Forth "compliant" [pre-Forth-79]) and TurboForth (Forth-83 compliant) is that words (same or similar) leaving a particular word's parameter field address (PFA) in TI Forth leave that word's code field address (CFA) in TurboForth.

 

...lee

Link to comment
Share on other sites

One more thing to add to my last post that may be obvious but should probably be said:

 

 

 

A major difference between TI Forth (fig-Forth "compliant" [pre-Forth-79]) and TurboForth (Forth-83 compliant) is that words (same or similar) leaving a particular word's parameter field address (PFA) in TI Forth leave that word's code field address (CFA) in TurboForth.

 

...lee

 

Good point, Lee. And I would just add, that while it's frustrating that TIF and TF have different ways of doing things, it's really the fault of neither language. Both implementations are correct pursuant to their respective standards: For TIF it's FIG Forth, and for TF it's Forth 83. Unfortunately, they have subtle differences from each other.

 

Mark

Link to comment
Share on other sites

Actually I did not know that. I use ' to get the pfa for string display purposes. Once I migrate to TF, I'll need to remember the difference because I assume ' will place the cfa on the stack then.

 

That is correct. In TIF, the definition of ' is

 

: ' ( -- pfa ) -FIND 0= 0 ?ERROR DROP LITERAL ; IMMEDIATE

 

It works on both the command line and in a colon definition because LITERAL does nothing in TIF in interpretive mode, contrary to what other compile-mode words do. In TF on the other hand, You should only use ' on the command line and ['] in a colon definition. They both push the found word's CFA to the stack.

 

In TIF, you can shorten the definition of RUN-WORD because ' issues its own error message:

 

 

: RUN-WORD ( -- )

CR ." Enter a word name:"

TIB @ 30 EXPECT

CR 0 IN !

[COMPILE] '
CFA EXECUTE

;

 

 

However, if you want to control the error message, you should use the definition with -FIND in it.

 

Note, too, that [COMPILE] must precede ' because otherwise the next word in the definition becomes the object of ' . This is due to the fact that ' has its precedence bit set so that it executes immediately during compilation and without the preceding [COMPILE] would search the dictionary for CFA !!

 

...lee

Link to comment
Share on other sites

Yes, for some reason Forth 83 has two versions of tick - one for immediate mode and one for use in a colon definition.

 

In the Forth 83 standard, ' is defined in the interpreter layer, and ['] in the compiler layer.

 

I've no idea what the reason for the change was. Possibly to avoid state-smart words, akin to COMPILE and [COMPILE].

Link to comment
Share on other sites

Yes, for some reason Forth 83 has two versions of tick - one for immediate mode and one for use in a colon definition.

 

In the Forth 83 standard, ' is defined in the interpreter layer, and ['] in the compiler layer.

 

I've no idea what the reason for the change was. Possibly to avoid state-smart words, akin to COMPILE and [COMPILE].

 

Yeah, this makes my last version of RUN-WORD in TIF even easier in TF precisely because of the two versions. In this case, you actually can use ' in the definition because it will execute when RUN-WORD is executed without the need for [COMPILE]. For this purpose, also, it's cleaner than the TIF version because it leaves only one value on the stack regardless of success (CFA) or failure (0), whereas the TIF version will issue a message (convenient) and leave two values for debugging purposes on the stack (most inconvenient) upon failure. Here is the TF version:

 

: RUN-WORD ( -- )

CR ." Enter a word name:"

TIB @ 30 EXPECT

CR 0 >IN !

'
?DUP IF

EXECUTE

THEN

;

 

?DUP is useful here because it only DUPs a non-zero value in TF, obviating the necessity to use ELSE DROP to remove an unused value. The same function in TIF is performed by -DUP .

 

...lee

Link to comment
Share on other sites

That is correct. In TIF, the definition of ' is

 

: ' ( -- pfa ) -FIND 0= 0 ?ERROR DROP LITERAL ; IMMEDIATE

 

It works on both the command line and in a colon definition because LITERAL does nothing in TIF in interpretive mode, contrary to what other compile-mode words do. In TF on the other hand, You should only use ' on the command line and ['] in a colon definition. They both push the found word's CFA to the stack.

 

In TIF, you can shorten the definition of RUN-WORD because ' issues its own error message:

 

 

: RUN-WORD ( -- )

CR ." Enter a word name:"

TIB @ 30 EXPECT

CR 0 IN !

[COMPILE] '
CFA EXECUTE

;

 

 

However, if you want to control the error message, you should use the definition with -FIND in it.

 

Note, too, that [COMPILE] must precede ' because otherwise the next word in the definition becomes the object of ' . This is due to the fact that ' has its precedence bit set so that it executes immediately during compilation and without the preceding [COMPILE] would search the dictionary for CFA !!

 

...lee

 

What I did was something like this:

 

S0 @ 10 EXPECT

0 IN !

INTERPRET

 

Aside from using S0 instead of TIB, the above works just fine. Why would I want to use the [COMPILE] and EXECUTE pair?

Edited by Vorticon
Link to comment
Share on other sites

What I did was something like this:

 

S0 @ 10 EXPECT

0 IN !

INTERPRET

 

Aside from using S0 instead of TIB, the above works just fine. Why would I want to use the [COMPILE] and EXECUTE pair?

 

Well, there are many ways to skin the cat to be sure. Your INTERPRET solution is simpler, but won't catch a number. It will push it to the stack. Also, both solutions in TIF, when the word is not found, will leave 2 debugging numbers on the stack in TIF: the byte offset into the input stream and the block it came from (0 means the TIB). If you are running a program that you wish to continue when a wrong word is typed, you may want to be able to handle the error without aborting. For that, you would need to use -FIND similar to how I did in post #250. That will not abort or leave anything on the stack you can't deal with.

 

...lee

Link to comment
Share on other sites

 

 

Yeah, this makes my last version of RUN-WORD in TIF even easier in TF precisely because of the two versions. In this case, you actually can use ' in the definition because it will execute when RUN-WORD is executed without the need for [COMPILE]. For this purpose, also, it's cleaner than the TIF version because it leaves only one value on the stack regardless of success (CFA) or failure (0), whereas the TIF version will issue a message (convenient) and leave two values for debugging purposes on the stack (most inconvenient) upon failure. Here is the TF version:

 

: RUN-WORD ( -- )

CR ." Enter a word name:"

TIB @ 30 EXPECT

CR 0 >IN !

'
?DUP IF

EXECUTE

THEN

;

 

?DUP is useful here because it only DUPs a non-zero value in TF, obviating the necessity to DROP an unused value after THEN . The same function in TIF is performed by -DUP .

 

...lee

 

Also, in TF you can use the word 0! So

 

0 >in !

 

becomes

 

>in 0!

 

(Tablet keyboard sucks for forth coding!)

Link to comment
Share on other sites

Well, there are many ways to skin the cat to be sure. Your INTERPRET solution is simpler, but won't catch a number. It will push it to the stack. Also, both solutions in TIF, when the word is not found, will leave 2 debugging numbers on the stack in TIF: the byte offset into the input stream and the block it came from (0 means the TIB). If you are running a program that you wish to continue when a wrong word is typed, you may want to be able to handle the error without aborting. For that, you would need to use -FIND similar to how I did in post #250. That will not abort or leave anything on the stack you can't deal with.

 

...lee

 

Makes sense. I will change my code accordingly.

By he way I should mention that the ['] word is actually described in Starting Forth, which is supposed to be based on Forth 79 and was published in 1981. So the origins of that word must predate the 84 standard...

Edited by Vorticon
Link to comment
Share on other sites

Makes sense. I will change my code accordingly.

By the way I should mention that the ['] word is actually described in Starting Forth, which is supposed to be based on Forth 79 and was published in 1981. So the origins of that word must predate the 84 standard...

 

You are, indeed, correct about the antiquity ;-) of ['] , but it even predates the Forth-79 standard. Forth-79 essentially removed it by making ' state smart and Forth-83 put it back, removing the state smarts of Forth-79's ' :roll:. TI Forth uses Forth-79's version (I suppose that could be older, as well), which is why I usually state TI Forth's compliance with fig-Forth in quotes. You are probably aware of this, but for the benefit of other readers, "Appendix C" of the TI Forth Instruction Manual catalogs by page number the differences between Brodie's Starting Forth (1st edition) and TI Forth. As I recall, it misses a few differences, but it has certainly been a useful reference over the years.

 

...lee

Link to comment
Share on other sites

Makes sense. I will change my code accordingly.

By he way I should mention that the ['] word is actually described in Starting Forth, which is supposed to be based on Forth 79 and was published in 1981. So the origins of that word must predate the 84 standard...

 

That's interesting. Yet when one consults the 79 standard, ['] is nowhere to be found. So it must have entered common use some time between the publication of the Forth 79 standard (October 1980) and the publishing of Starting Forth in 1981.

 

I'd put a small amount of money on the word originating with polyFORTH from Forth, Inc.

 

Forth, Inc. was the company founded by Chuck Moore (the inventor of Forth) and Elizabeth Rather, the worlds second Forth programmer (Chuck being the first!)

Link to comment
Share on other sites

You are, indeed, correct about the antiquity ;-) of ['] , but it even predates the Forth-79 standard. Forth-79 essentially removed it by making ' state smart and Forth-83 put it back, removing the state smarts of Forth-79's ' :roll:.

 

 

Aahhh! Interesting information!

Link to comment
Share on other sites

  • 2 weeks later...

Hi.

Is there a way to disable/enable interrupts outside of using assembly in TI Forth?

 

I could do the following, but it will require loading the -ASSEMBLER library which takes a lot of memory:

 

ASSEMBLER
CODE INT-OFF 2 LIMI, NEXT,
CODE INT-ON 0 LIMI, NEXT,
FORTH

Edited by Vorticon
Link to comment
Share on other sites

Since TIF does not have a function to generate sounds other than the 2 GPLLNK beep and honk, I'm trying to create a routine to generate a specified tone, and it's not working. Here's what I have done:

 

( SINGLE TONE GENERATION ROUTINE)
0 VARIABLE SNDLIST 6 ALLOT
ASSEMBLER
CODE INT-OFF 0 LIMI, NEXT, ( TURN INTERRUPTS OFF)
CODE INT-ON 2 LIMI, NEXT, ( TURN INTERRUPTS ON)
FORTH
HEX
: SNDPLAY
FF 50 35 87 03 5 0 DO SNDLIST I + C! LOOP ( SET UP SOUNDLIST)
SNDLIST 3880 5 VMBW ( LOAD SOUNDLIST IN VDP @ >3880)
INT-OFF ( TURN OFF INTERRUPTS)
38 83CC VSBW 80 83CD VSBW ( LOAD POINTER TO SOUNDLIST IN >83CC)
01 83FD VOR ( SET THE LSB OF >83FD TO INDICATE THAT SOUND LIST HAS BEEN LOADED IN VDP RAM)
01 83CE VSBW ( START THE SOUND GENERATOR)
INT-ON ( TURN INTERRUPTS ON) ;
DECIMAL

 

The code above loads without errors, but when I try to execute SNDPLAY, nothing happens and I get the ok:0 prompt back. Any idea where I might be going wrong here?

Edited by Vorticon
Link to comment
Share on other sites

Hi.

Is there a way to disable/enable interrupts outside of using assembly in TI Forth?

 

I could do the following, but it will require loading the -ASSEMBLER library which takes a lot of memory:

 

ASSEMBLER
CODE INT-OFF 2 LIMI, NEXT,
CODE INT-ON 0 LIMI, NEXT,
FORTH

 

You can load both -DUMP and -ASSEMBLER , code the words in TIF assembler, use tick ( ' ) to get each word's PFA, use LFA to get the word's LFA and DUMP enough memory from there to the screen to figure out what you need to CODE the words in machine code. You only need to ensure that -CODE is loaded to use CODE , which doesn't take much memory at all.

 

...lee

Link to comment
Share on other sites

You can load both -DUMP and -ASSEMBLER , code the words in TIF assembler, use tick ( ' ) to get each word's PFA, use LFA to get the word's LFA and DUMP enough memory from there to the screen to figure out what you need to CODE the words in machine code. You only need to ensure that -CODE is loaded to use CODE , which doesn't take much memory at all.

 

...lee

 

Ah! A little convoluted, but it should work. Thanks for the tip :)

Link to comment
Share on other sites

This should work just fine in TIF. Converted it from some very early TF code (see attached):

 

Supplementary Sound Words.pdf

 

HEX
: VOLUME ( ch# vol -- )
 F AND SWAP 2* 1+ 8 + 4 SLA OR 8400 C! ;

: TONE ( ch# tone -- )
 SWAP 2* 8 + 4 SLA SWAP DUP F AND ROT OR SWAP 4 SRL SWAP
 8400 C! 8400 C! ;

: NOISE ( n -- ) 7 AND E0 OR 8400 C! ;
DECIMAL

 

Hope this helps :)

Link to comment
Share on other sites

Mark, I'll try this code tonight. Can you however use C! on VDP RAM addresses?

 

No. But the code above is not referring to any VDP ram addresses. All the addresses in the above are CPU addresses. >8400 is the address of the sound chip, which is mapped into CPU address space.

 

Have a look at the PDF for example usage. IIRC it produces a laser sound very similar to Parsec. The code above does not use VDP memory or interrupts. It simply pokes the sound chip directly.

Link to comment
Share on other sites

The code above loads without errors, but when I try to execute SNDPLAY, nothing happens and I get the ok:0 prompt back. Any idea where I might be going wrong here?

 

Try adding a delay loop before your colon definition returns to the command line. It's possible that TIF disables interrupts when it returns to the command line? Just a guess. Also, this code is redundant:

 

FF 50 35 87 03 5 0 DO SNDLIST I + C! LOOP ( SET UP SOUNDLIST)

 

You're filling an array with constants from the stack at runtime. But you might as well populate the array at compile-time, since they're constants:

 

( SINGLE TONE GENERATION ROUTINE)

0 VARIABLE SNDLIST FF C, 50 C, 35 C, 87 C, 03 C,

ASSEMBLER

CODE INT-OFF 0 LIMI, NEXT, ( TURN INTERRUPTS OFF)

CODE INT-ON 2 LIMI, NEXT, ( TURN INTERRUPTS ON)

FORTH

HEX

: SNDPLAY

SNDLIST 2+ 3880 5 VMBW ( LOAD SOUNDLIST IN VDP @ >3880)

INT-OFF ( TURN OFF INTERRUPTS)

38 83CC VSBW 80 83CD VSBW ( LOAD POINTER TO SOUNDLIST IN >83CC)

01 83FD VOR ( SET THE LSB OF >83FD TO INDICATE THAT SOUND LIST HAS BEEN LOADED IN VDP RAM)

01 83CE VSBW ( START THE SOUND GENERATOR)

INT-ON ( TURN INTERRUPTS ON) ;

DECIMAL

 

Note the 2+ in red. This is there to move past the 0 that is stored in the variable SNDLIST. That is probably why your code doesn't work. You think you loading FF 50 35 87 03 but you're actually loading 00 00 FF 50 35 and the 87 03 does not get copied to VDP ram. If you're using Classic99 then have a look at VDP 3880 in the debugger. Are all the bytes there?

 

You could get around that need for 2+ by recognising that the value stored in the variable, and the data "comma'd in" after it are ajdacent in memory. You can use that to your advantage:

 

FF50 VARIABLE SNDLIST 35 C, 87 C, 03 C, ALIGN

 

See what I did? Now you don't need that 2+. Hope that makes sense!

 

Lee will correct if I have made any invalid assumptions! :grin:

 

(not sure if you need ALIGN - but since you are comma'ing in an odd number of bytes it ensures that the compilation address is aligned on an even boundary. This may be taken care of automagically for you. Don't know!

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...