Jump to content



2

Forth Tutorials


85 replies to this topic

#76 Willsy OFFLINE  

Willsy

    Dragonstomper

  • 765 posts
  • Location:Uzbekistan (no, really!)

Posted Thu Feb 23, 2012 8:41 AM

View PostVorticon, on Wed Feb 22, 2012 7:47 PM, said:

2- If I EDIT block 1, and I reach the end of it's 1K, what happens then if I still have more program commands to enter? Does it automatically flow into block 2 or do I have to manually perform a 2 EDIT etc...?

Excellent question.

When you get to the end of a block, you can use the word -->

The word --> when encountered at load time, will automatically pull in the next block from disk and continue loading. You can chain blocks together like this indefinately.

Attached File  editor.png   88.42K   2 downloads

Note, you can use --> in the middle of a colon definition (i.e. a colon definition can span more than one block, but it's very very bad practice and liable to get you shot by the Forth Police, so don't do it!)

When you're in the editor, you can use CTRL O and CTRL P to move to the previous, and next block respectively.

Now is probably a good time to introduce you to block buffers. Most Forth systems, including TurboForth, have the notion of block buffers. The basically work like a block cache. When you request a block (with EDIT, or with LOAD, or with LIST or whatever) the requested block is loaded into (in TurboForth's case) one of six buffers (in TF these buffers are in VDP memory to keep CPU memory free for your code).

You can see the 'block cache' in action by typing the following (it's VERY obvious if you're using a REAL TI machine with floppy drives).

1 LIST
2 LIST
3 LIST
4 LIST
5 LIST
6 LIST


See how each request caused a trip to the floppy disk drive? Now type, say, 4 LIST again.

Notice how there was no round-trip to the floppy disk? That's because TF knew that block 4 was already in its cache, so it didn't bother going to the floppy disk for it.

When you EDIT a block, it brings it into one of the six buffers and invokes the editor. The moment you make a change in the editor (by changing the source code in any way) the buffer in which your block resides is marked as dirty (because it has been changed, so the version on disk is 'out of date' with the version in memory).

When you exit the editor with FCTN 9 the editor block is in the cache and will NOT be written to disk until it is FLUSHed. A flush happens under two circumstances:
  • You type FLUSH on the command line.
  • All six buffers are in use and you request a new block (that is not in the cache)
At this point, any buffers that are dirty are flushed to disk, and all the buffers are marked as clean again.

You'll get into the habit of exiting the editor and typing FLUSH to make sure you're edits are saved back to disk (it's fairly easy to crash all Forth systems, since you are completely free to screw up in any way you see fit!)

Note that you can also load code directly from the cache! You don't have to do anything special to do that; if the block requested is in the cache then it gets served to the compiler/editor/whatever from the cache.

Finally, if you are editing a block and you screw up, just press FCTN =. This will exit the editor but it will NOT mark the buffer/block as dirty. It will actually mark the buffer in which that block was residing as empty, which will force the original block to be re-loaded when you edit it again.

Okay, that's probably quite a lot to digest in one hit! I hope this makes sense. It's actually very natural... There's a cache between you and the block hosting device; be that a ram disk, hard disk, floppy disk, CF7, whatever...

Please feel free to ask further questions!

#77 Lee Stewart OFFLINE  

Lee Stewart

    Chopper Commander

  • 175 posts

Posted Thu Feb 23, 2012 10:11 AM

Vorticon...

One point to always keep in mind when editing Forth blocks: Within a Forth block, the only "white" space that separates one Forth word (or other Forth entity) from its neighbors is one or more spaces. In particular, there are no embedded carriage-return characters at the ends of lines that could act in this capacity, as they do in other programming languages. When you get to the end of a line, your typing character-wraps around to the next line until you get to the end of the block, at which point it jumps back to the first position of the same (last) line.

As long as I have been programming in Forth, I still trip over this gotcha. It has caused insidious bugs in my programs that always prompt me to smack my forehead when I realize what I have done!

Again, if there is no intervening space between the string of characters at the end of one line and the string of characters at the beginning of the next line, the latter string is the continuation of the former and, thus, part of the same word.

...lee

#78 Willsy OFFLINE  

Willsy

    Dragonstomper

  • 765 posts
  • Location:Uzbekistan (no, really!)

Posted Thu Feb 23, 2012 10:48 AM

Indeed. Well put, Lee. Simply put, a block is *displayed* for human convenience as 16 lines of 64 characters, but forth sees it as a single 1024 character long line.

#79 Vorticon OFFLINE  

Vorticon

    Moonsweeper

  • 494 posts
  • Location:St. Paul, MN, USA

Posted Thu Feb 23, 2012 12:22 PM

Thank you guys for the explanations. Willsy, is all this info somewhere on your site?

#80 idflyfish OFFLINE  

idflyfish

    Chopper Commander

  • 101 posts

Posted Sun Feb 26, 2012 4:18 PM

Forthies,

I want to draw bit mapped images using TF which I assume can be done by putting the right data in the right VDP memory locations using v!. Could anyone reply with a short tutorial on drawing a bit mapped line, square, or a circle using forth?

#81 Lee Stewart OFFLINE  

Lee Stewart

    Chopper Commander

  • 175 posts

Posted Sun Feb 26, 2012 8:16 PM

View Postidflyfish, on Sun Feb 26, 2012 4:18 PM, said:

Forthies,

I want to draw bit mapped images using TF which I assume can be done by putting the right data in the right VDP memory locations using v!. Could anyone reply with a short tutorial on drawing a bit mapped line, square, or a circle using forth?

Uh...not so much, unfortunately. Mark has not implemented bitmap graphics for Turboforth. That is one thing you can do in TI Forth that you cannot easily do in Turboforth. The biggest problem with implementing bitmap graphics is that VDP memory has to be organized significantly differently from what it is in the other text and graphics modes. To get an idea of the difficulty, look at the "Section 21 Color, Graphics and Sprites" in the TI Editor/Assembler Manual and the VDP Memory Map in Chapter 4 of the TI Forth Instruction Manual. We could write some Forth code to do it, I am sure---but it is not trivial. In particular, disk buffering gets short shrift as do some other buffers.

You could do some rudimentary plotting by manipulating the available characters in clever ways as is done in pretty much all the games written in TI BASIC and TI Extended BASIC; but, you cannot plot one pixel at a time without putting the 9918A into bitmap mode.

...lee

#82 idflyfish OFFLINE  

idflyfish

    Chopper Commander

  • 101 posts

Posted Mon Feb 27, 2012 12:10 AM

I am having a problem when I try to increment a variable I am using as a counter. When I execute this code I expect to have 10 printed to the screen but what I get is ERROR:COUNTER not found. Anyone know what I am doing wrong here?


VARIABLE COUNTER
0 COUNTER !
10 0 DO COUNTER @ 1 + COUNTER ! LOOP ;
COUNTER @ .

Edited by idflyfish, Mon Feb 27, 2012 12:11 AM.


#83 Willsy OFFLINE  

Willsy

    Dragonstomper

  • 765 posts
  • Location:Uzbekistan (no, really!)

Posted Mon Feb 27, 2012 1:27 AM

The loop needs to go inside a colon definition. Some words, like DO etc can only be compiled - not executed on the command line...


VARIABLE COUNTER
0 COUNTER !
: TEST 10 0 DO COUNTER @ 1 + COUNTER ! LOOP ;
TEST
COUNTER @ .


#84 apersson850 OFFLINE  

apersson850

    Star Raider

  • 84 posts

Posted Mon Feb 27, 2012 6:18 AM

Quote

Uh...not so much, unfortunately. Mark has not implemented bitmap graphics for Turboforth. That is one thing you can do in TI Forth that you cannot easily do in Turboforth. The biggest problem with implementing bitmap graphics is that VDP memory has to be organized significantly differently from what it is in the other text and graphics modes. To get an idea of the difficulty, look at the "Section 21 Color, Graphics and Sprites" in the TI Editor/Assembler Manual and the VDP Memory Map in Chapter 4 of the TI Forth Instruction Manual. We could write some Forth code to do it, I am sure---but it is not trivial.
It's not for Forth, but for Pascal and the p-system, but you can get an idea of the complexity of forcing such functionality onto a system not really desgined for it by looking at what I did to implement bit-map graphics in the p-system. You can also see routines for drawing straight lines and writing characters anywhere on the screen (not limited to the normal 32*24 positions, but where a character can have it's upper left corner at any pixel)

Link here

#85 Willsy OFFLINE  

Willsy

    Dragonstomper

  • 765 posts
  • Location:Uzbekistan (no, really!)

Posted Mon Feb 27, 2012 6:36 AM

It can be done in TurboForth, however it would seriously impact on the block buffer functionality, since the screen and block buffers would overlap.

That might not really be a problem though; If your program doesn't access the disk drive after it has loaded, then you could safely invoke bitmap mode and have at it, without a care in the world for the block buffers. At the end of your program, a simple COLD command would restore the system.

However, I personally have never done any work in bitmap mode; I would need someone to write optimised line drawing routines (Bresenham for diagonal lines and optimised routines for horizontal and vertical would be best) and circle drawing.

Probably the best person for that job is Sometimes, as he has done a lot of bitmap work over the years.

It could exist as a simple loadable extension.

Mark

#86 apersson850 OFFLINE  

apersson850

    Star Raider

  • 84 posts

Posted Mon Feb 27, 2012 8:18 AM

Feel free to use the simple straight line routines that are in my files, which I linked to above. I didn't bother with circles at that time. I don't think I was aware of the Bresenham algorithm when I did my implementation, but just did the first that came to my mind. Internet as we know it didn't exist back then, so finding information was slower.

A good feature with the p-system, when doing modifications like this one, is that it's from the beginning designed to be portable. I don't think there's any data anywhere in that system that's not referenced via some pointer, so you can easily move whole chunks of system data if you need to.

Edited by apersson850, Mon Feb 27, 2012 8:25 AM.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users