Jump to content
IGNORED

Forth Tutorials


matthew180

Recommended Posts

Thanks again! :) Keeping the stack straight is one of the most difficult tasks in Forth from my point of view.

 

Ahem... I actually have one more question. I know I'm being a pest, so please feel free to shoo me away :P

Given the above initialization of the TRIANGLE array, I want to draw a point at each vertex, i.e. each pair of numbers in TRIANGLE is an x/y coordinate. I know I could just do it manually, but I'm actually working my way towards a draw routine for any polygon that I want to use in a future project.

 

: TDRAW 6 0 DO I 2 * TRIANGLE + DUP @ >R 2+ @ R> SWAP DRAW 2 +LOOP ;

 

I'm probably missing something very obvious as usual, but I AM learning, I promise!

Link to comment
Share on other sites

You see, there would have been absolutely no way for me to figure this out. Thanks!!! Maybe this tidbit should be included in the next version of the manual.

Any thoughts about the second issue I had?

 

You're referring to HEX and DECIMAL, right?

 

Well, they are not 'immediate' words - they just get compiled into your definition like any other word does, so they end up executing at run-time (when your word runs) which isn't what you wanted.

 

Forth does have a way (there's always a way in Forth!) to do it though:

 

: someWord blah blah blah [ hex ] 100 [ decimal ] blah blah blah ;

 

When [ is encountered, Forth stops compiling your word, and treats everything that it sees thereafter as if it had been typed alone on the command line. Pretty darned neat eh? When ] is encountered, compiliation resumes.

 

So, [ hex ] effectively 'escapes out' of compilation, executing hex (which sets BASE) and resumes compilation again, so any numbers are now treated as hex.

 

Or, you could define an immediate word that executes during compilation like this:

 

: [HEX] HEX ; IMMEDIATE

: [DECIMAL] DECIMAL ; IMMEDIATE

 

: TEST [hex] 100 [decimal] 256 ;

 

TEST .S

256 256 ok

 

Immediate words are special. As I mentioned, they execute as soon as they are encountered during compilation (i.e. immediately) so they can do magic behind the scenes, like compile extra code, for example. They can be pretty mind melting for the Forth newbie, but it's quite natural when you get used to it. And mega powerful.

 

Keep hacking! You're getting there!

 

And yes. There's no doubt about it: Forth is harder than other languages. In most other languages, you're controlling the order of execution of code. You do that in Forth too, of course, but in addition, you have to manage the order of data because we have a LIFO stack!

Link to comment
Share on other sites

Thanks again! :) Keeping the stack straight is one of the most difficult tasks in Forth from my point of view.

 

Ahem... I actually have one more question. I know I'm being a pest, so please feel free to shoo me away :P

Given the above initialization of the TRIANGLE array, I want to draw a point at each vertex, i.e. each pair of numbers in TRIANGLE is an x/y coordinate. I know I could just do it manually, but I'm actually working my way towards a draw routine for any polygon that I want to use in a future project.

 

: TDRAW 6 0 DO I 2 * TRIANGLE + DUP @ >R 2+ @ R> SWAP DRAW 2 +LOOP ;

 

I'm probably missing something very obvious as usual, but I AM learning, I promise!

 

It's quite obvious that you're learning! I wouldn't think of shooing you away. I enjoy this! :) The only thing that TRIANGLE needs to plot the vertices is DOT in place of DRAW . Put DRAW before the loop to change to DRAW mode.

 

Here are some things that you can do to possibly improve TRIANGLE:

  • Any operation inside a loop that does not change can often be hoisted out of the loop to save CPU cycles. TRIANGLE and DRAW are such. I would make TRIANGLE + 12 the limit and TRIANGLE the initial value of the loop and put DRAW as the first word before the loop---once you've put the 4A's bitmap graphics into DRAW mode, it stays that way.
  • Put DOT where DRAW was.
  • Unless I'm missing something, you don't need to use the return stack here for temporary storage.

Here's one way to do it

 

: TDRAW DRAW TRIANGLE 12 + TRIANGLE DO I @ I 2+ @ DOT 4 +LOOP ;

 

...lee

Link to comment
Share on other sites

Thanks again! :) Keeping the stack straight is one of the most difficult tasks in Forth from my point of view.

 

Ahem... I actually have one more question. I know I'm being a pest, so please feel free to shoo me away :P

Given the above initialization of the TRIANGLE array, I want to draw a point at each vertex, i.e. each pair of numbers in TRIANGLE is an x/y coordinate. I know I could just do it manually, but I'm actually working my way towards a draw routine for any polygon that I want to use in a future project.

 

: TDRAW 6 0 DO I 2 * TRIANGLE + DUP @ >R 2+ @ R> SWAP DRAW 2 +LOOP ;

 

I'm probably missing something very obvious as usual, but I AM learning, I promise!

 

It looks fine to me. What does DRAW do? Does it plot a single pixel?

 

To see what was going on, I initialised the array with unique data first:

 

1 2 3 4 5 6 TINIT

 

Then I defined DRAW thus:

 

: DRAW CR . . ;

 

Then, when I run TDRAW I get the following output:

 

5 6

3 4

1 2 ok:0

 

(I was using TurboForth as I don't have TIF installed at the moment).

 

As I say, looks okay to me. I probably wouldn't have used the return stack though. I'd have used SWAP:

 

: TDRAW 6 0 DO I 2 * TRIANGLE + DUP @ SWAP 2+ @ DRAW 2 +LOOP ;

 

Which is simpler. More than one way to skin the cat! Notice how I used spaces to make each 'section' of the definition clearer: Determining the array index, fetch the first operand from the array, fetch the second operand from the array. Three logical sections in the definition, separated into 'paragraphs' to make reading easier.

 

Be careful when using the return stack inside a loop. It *must* be restored before you hit LOOP or +LOOP. Also, if you put something on the return stack inside a loop, you can't use I or J until you've taken that something off again. That's a gotcha! I & J are very simple words; they simply look 'x' bytes 'down' the return stack and push whatever they find there, so obviously, if you've put something on the return stack, the loop data (that is on the return stack) is 2 bytes away from where I/J are looking! Same thing if you hit LOOP/+LOOP with temporary data on the return stack.

 

And here endeth the lesson!

Link to comment
Share on other sites

 

Or, you could define an immediate word that executes during compilation like this:

 

: [HEX] HEX ; IMMEDIATE

: [DECIMAL] DECIMAL ; IMMEDIATE

 

: TEST [hex] 100 [decimal] 256 ;

 

TEST .S

256 256 ok

 

 

 

Oh I like that! Maybe shorten it to something like ^B and ^H and just prefix any base changes I need. This certainly comes handy when dealing with bitmap and the VDP. Thanks :)

Link to comment
Share on other sites

It's quite obvious that you're learning! I wouldn't think of shooing you away. I enjoy this! :) The only thing that TRIANGLE needs to plot the vertices is DOT in place of DRAW . Put DRAW before the loop to change to DRAW mode.

See, I told you it would something simple. That's why one should not program too late into the night :D

Here are some things that you can do to possibly improve TRIANGLE:

  • Any operation inside a loop that does not change can often be hoisted out of the loop to save CPU cycles. TRIANGLE and DRAW are such. I would make TRIANGLE + 12 the limit and TRIANGLE the initial value of the loop and put DRAW as the first word before the loop---once you've put the 4A's bitmap graphics into DRAW mode, it stays that way.
  • Put DOT where DRAW was.
  • Unless I'm missing something, you don't need to use the return stack here for temporary storage.

Here's one way to do it

 

: TDRAW DRAW TRIANGLE 12 + TRIANGLE DO I @ I 2+ @ DOT 4 +LOOP ;

 

...lee

Very nice. Didn't think of making TRIANGLE as the loop index...And yes, looking at it from fresh eyes this morning, I really did not need to use the return stack. As Willsy mentioned, SWAP would have done the trick...

Link to comment
Share on other sites

 

: TDRAW 6 0 DO I 2 * TRIANGLE + DUP @ SWAP 2+ @ DRAW 2 +LOOP ;

 

Which is simpler. More than one way to skin the cat! Noticed how I used spaces to make each 'section' of the definition clearer: Determining the array index, fetch the first operand from the array, fetch the second operand from the away. Three logical sections in the definition, seperated into 'paragraphs' to make reading easier.

 

Be careful when using the return stack inside a loop. It *must* be restored before you hit LOOP or +LOOP. Also, if you put something on the return stack inside a loop, you can't use I or J until you've taken that something off again. That's a gotcha! I & J are very simple words; they simply look 'x' bytes 'down' the return stack and push whatever they find there, so obviously, if you've put something on the return stack, the loop data (that is on the return stack) is 2 bytes away from where I/J are looking! Same thing if you hit LOOP/+LOOP with temporary data on the return stack.

 

And here endeth the lesson!

 

Yes, I definitely need to be mindful of my formatting as it will make future revisions a lot easier. Restoring the return stack before LOOP is a great piece of advice because I bet it would have caused me a lot of headache in future programs. Thanks!

Link to comment
Share on other sites

I have to be in DC for the next 5 days for a meeting, so I'm going to try and install MESS on my laptop at the hotel tonight so I can continue to play with this given that Classic 99 cannot not handle TIF's disk operations. Do I need TI ROMS for this?

Lee, if you have a ready made MESS setup, would you be willing emailing it to me? I am completely unfamiliar with MESS and I'm not very excited about spending a lot of time configuring it just to run TIF...

Link to comment
Share on other sites

I have to be in DC for the next 5 days for a meeting, so I'm going to try and install MESS on my laptop at the hotel tonight so I can continue to play with this given that Classic 99 cannot not handle TIF's disk operations. Do I need TI ROMS for this?

Lee, if you have a ready made MESS setup, would you be willing emailing it to me? I am completely unfamiliar with MESS and I'm not very excited about spending a lot of time configuring it just to run TIF...

 

I'll see what I can do. I need to re-install it, but I have the ROMs. I may not get to it until Sunday.

 

...lee

Link to comment
Share on other sites

Count up by 1 instead of 2, and use C@ ("char fetch") and C! ("char store") for your memory access.

 

That's it. No big secret :-)

 

Remember that ALLOT allots bytes, so no change required there.

 

So, your original TDRAW code would be:

 

: TDRAW 6 0 DO I TRIANGLE + DUP C@ >R 1+ C@ R> SWAP DRAW LOOP ;

 

TF works exactly same, so you can use this if it's of any help.

 

HTH

Link to comment
Share on other sites

Count up by 1 instead of 2, and use C@ ("char fetch") and C! ("char store") for your memory access.

 

That's it. No big secret :-)

 

Remember that ALLOT allots bytes, so no change required there.

 

So, your original TDRAW code would be:

 

: TDRAW 6 0 DO I TRIANGLE + DUP C@ >R 1+ C@ R> SWAP DRAW LOOP ;

 

TF works exactly same, so you can use this if it's of any help.

 

HTH

 

Yes, that's what Brodie's book says, but I think there is more to it in TIF unless I am utterly confused, which is also a very likely possibility.

Link to comment
Share on other sites

I'll see what I can do. I need to re-install it, but I have the ROMs. I may not get to it until Sunday.

 

...lee

Thanks Lee but it looks like the win994a emulator handles TIF disk ops just fine, so I won't need to use MESS, although I am a bit curious about it having never used prior...

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