Turtle Graphics on the Fignition!

277 views
Skip to first unread message

AshleyF

unread,
Feb 18, 2012, 11:52:51 PM2/18/12
to fign...@googlegroups.com

I’ve been having fun playing with 160x160 graphics mode. I have a very rudimentary turtle graphics working for it. The engine itself fits snugly in a single block. It adds the following words for controlling the “turtle”:

c – clear screen (cls doesn’t work in 160x160 graphics mode)
g – Go to an x y coordinate (0,0 is the center of the screen – y-axis is mirrored from mathematics)
h – Set heading (0-60 - 0 is North, 15 East, 30 South, 45 West)
b – Begin (enters 160x160 graphics mode, clears, resets turtle)
e – End (waits for key, exits graphics mode)
t – Turn the turtle (see h above – negative values for counter-clockwise)
n – Sine function (used internally – see h above – returns scaled by 255)
m – Move turtle number of pixels along current heading (no drawing)
p – Plot pixel currently under turtle
f – Forward number of pixels while plotting

Yes, this all fits in a single block and compiles to just 307 bytes! It uses a table-based sine function with 6 degree (pi/30 radian) increments – think minute marks on a clock. This is still divisible by many things (2, 3, 4, 5, 6, 10, 12, 15, 20, 30), so it works out well enough for Logo and makes the lookup table small.

In a second block are some demos putting it to use. The sine (n) function can be seen to work with:

: sin 160 0 do i i n 4 / 80 + plot loop ;

And we can see that using it to plot lines in each of the 60 available angles works:

: burst 60 0 do 0 0 g i h 110 f loop ;


Other demos show off some of the creative Logo patterns you may have played with as a kid:

: squiral -50 50 g 20 0 do 100 f 21 t loop ;



: circle 60 0 do 4 f 1 t loop ;
: spiral 15 0 do circle 4 t loop ;


: star 5 0 do 80 f 24 t loop ;
: stars 3 0 do star 20 t loop ;



: rose 0 50 0 do 2 + dup f 14 t loop ;



One of my favorites is this flower:

: hp 15 0 do 5 f 1 t loop 15 0 do 2 f -1 t loop ;
: petal hp 30 t hp 30 t ;
: flower 15 0 do petal 4 t loop ;

Source and hex files attached.
Demo video: http://youtu.be/dfKFuOudx3Y
Blog post: http://bit.ly/figlogo

Have fun!

Logo.fth
Logo00.hex
Logo01.hex

carl attrill

unread,
Feb 19, 2012, 3:50:00 AM2/19/12
to fign...@googlegroups.com
That is very impressive, I have seen the video too.

I have often thought that forth and logo make ideal bedfellowscompliment each other.

Julian Skidmore

unread,
Feb 19, 2012, 9:43:05 AM2/19/12
to fign...@googlegroups.com
Hi Ashley,

Wow - the video is really impressive. I'm at GEEK2012 in Kent at the moment and I have (oddly enough) limited internet access, but I meant to reply to you yesterday when you first mentioned it. It's brilliant, I've been showing the video here :-)

Catch up soon, cheers from julz

--
                             
                  The DIY 8-bit computer from nichemachines™


FIG - black on whiteMini.jpg
NmLogoMini.jpg

AshleyF

unread,
Feb 19, 2012, 6:07:00 PM2/19/12
to fign...@googlegroups.com
Silly me! I was calculating sine/cosine for every single-pixel of motion. Of course this only needs to be done when the heading changes - just keep the multipliers around for future use. Also, I made a small optimization to avoid multiplication for single-pixel movement. This sped things up by a factor of four or five and still fits in a single block:

hex 0 var x 0 var y 0 var a 0 var q 0 var w 
1B var n 354F , 687F , 96AB , BECE , DDE9 , F3F9 , FEFF , 
: s >r r abs >r r F mod r 1E mod E > if F swap - then n + 
  c@ r 3C mod 1E > if minus then r> drop r> drop ;
: c 9380 C80 0 fill ; 
: g FF * y ! FF * x ! ; 
: h dup dup a ! s q ! 2D + 3C mod s w ! ; 
: b 1 vmode 1 pen c 0 0 g 0 h ; 
: e key 0 vmode cls ; 
: t a +! a @ h ; 
: m dup q @ * x +! w @ * y +! ; 
: k @ FF / 50 + ; 
: p x k y k plot ; 
: f 1 do q @ x +! w @ y +! p loop ;
 

Attached are new source and hex files.
Short demo video: http://youtu.be/Z9hPNnwMSB8?hd=1
Logo.fth
Logo00.hex
Logo01.hex

Simon

unread,
Feb 20, 2012, 4:19:15 AM2/20/12
to fign...@googlegroups.com
Nice work.  Very nice.

Andrew Ebling

unread,
Feb 21, 2012, 7:33:52 AM2/21/12
to fign...@googlegroups.com
Very impressive work Ashley - well done!

P.S. Noticed in the video your FIGnition is resting on an anti-static bag - be aware those bags can be slightly conductive; might be better to use something else :).

AshleyF

unread,
Feb 21, 2012, 10:37:10 AM2/21/12
to fign...@googlegroups.com
Ha! Thanks Andrew. You can see I'm not a hardware guy... :)

Julian Skidmore

unread,
Feb 21, 2012, 10:37:31 AM2/21/12
to fign...@googlegroups.com
Hi Ashley,

I've been thinking a bit about your code - and it can be optimised a little further as follows:

Firstly, it only uses 15 angles not 16, so we only need 15 table entries!

Secondly, in the draw calculations it does FF / to calculate the fixed point arithmetic, but we could use 8.8 fixed point binary and convert it with 8 >> . 8 >> is much faster than /. The table entries are now:

0, 0x1B, 0x35, 0x4F, 0x68, 0x80, 0x96, 0xAB, 0xBE, 0xCF, 0xDE, 0xEA, 0xF3, 0xFA, 0xFF

Thirdly, the origin is calculated using 50 (hex) + for both x and y, but this could be folded into the b command by calculating it in the g command.

Fourthly, s generation can be simplified quite a bit to only require one mod operation. If we reverse the table it becomes a cosine table which has the property that cos(a)=cos(-a). So the first step is abs; then if we simply do 3C ( 60) mod, do a reverse angle calculation by testing to see if a 29 >, and secondly a sign adjustment if angle is 14 > we can make s calculations about 3x faster.

Fifthly, we can un-factor the routines that aren't repeated to save space. This is important for the forward command: by avoiding the repeated updates to x and y we can eliminate the memory fetches and call/return and points can be plotted in the region of 100us / pixel (10K pixels/s), this compares with my estimate of,

: k @ FF / 50 + ; ( 20 [call/ret] + 20 + 6 + 155 + 6 + 3 = 210)
: p x k y k plot ; ( 20 [call/ret] + 20 + 210 + 20 + 210 + 30 = 510)
: f 1 do q @ x +! w @ y +! p loop ; ( (20 + 20 + 20 + 50 )*2 + 510 + 20 = 750us/point.

So, I think we can speed it up a little further ;-) I'll leave the debugging of this revision to the avid reader :-D


hex 0 var x 0 var y 0 var
 a 0 var q 0 var w

FFFA var n F3E9 , DECF , BEAB, 9680 , 684F , 351B , 0 c,

: dd drop drop ;

: s ( angle -- )
  abs ( because -angle = angle for cosines)
  3C mod ( range 0..59)
  dup 1D > if ( if 30 >=, then it's mirror image)
    3C swap - ( so subtract from 60)
  then
  dup 0D > if ( if 15 >=, then it's mirrored & negated)
    -1 1E rot - ( .. -1 1E-angle)
  else
    1 swap ( not mirrored .. 1 angle )
  then
  n +  ( index via the table )
  c@ * ( fetch table entry and multiply by sign)
;

: c 9380 C80 0 fill ; ( clg as before)

: gc ( value coordAddr -- )
  >r 50 + 8 << r> ! ( adjust for origin and convert to 8.8 fixed-point)
;

: m ( dist -- )

 dup q @ * x +! w @
 * y +! ; ( add dist * q to x and dist *w to y)

: g ( x y -- )
  y gc x gc ;

 : h ( angle -- )
  dup a ! ( update angle)
  dup s w ! ( calc cos for dy )
  2D + s q ! ( sine calc is + 45 of our angle units)
;

: f ( distance -- )
  >r ( : distance )
  q @ x @
  y @ w @  ( q x y w : distance)
  r 1 do
    >r r + >r ( q x : y' w ..)
    over + ( q x' : y' w .. )
    dup 8 >> r 8 >> plot ( q x': y' w .. )
   r> r> ( q x' y' w )
  loop
  dd dd r> m ( finally drop coords & move)
;


: e key 0 vmode cls ;

: b 1 vmode 1 pen c 0 0 g
 0 h ; ( as before)

: t ( angle -- )
  a @ + h ; ( add to angle and set heading)

;approx 16*3+20+30 = 95us/pix.

-cheers from julz


On Tue, Feb 21, 2012 at 12:33 PM, Andrew Ebling <andrew...@gmail.com> wrote:
Very impressive work Ashley - well done!

P.S. Noticed in the video your FIGnition is resting on an anti-static bag - be aware those bags can be slightly conductive; might be better to use something else :).



FIG - black on whiteMini.jpg
NmLogoMini.jpg
TurtleLib.fth

AshleyF

unread,
Feb 21, 2012, 7:14:23 PM2/21/12
to fign...@googlegroups.com
Holy smokes! That is brilliant Julian, thanks so much!
This is easily 15x faster than the original :)
It works perfectly: http://youtu.be/y7jChW6fOYA

I made a few tiny tweaks (attached):
- Trig function was indexing off the end (e.g 14 s)
- Can't represent 1.0 as a byte in 8.8 fixed point (resorted to cos(0) = 0.996... in the table)
- Forward (f) was skipping ahead a pixel at the end (no longer doing m now)

This is blazing fast man, thanks again!
Logo.fth
Logo00.hex
Logo01.hex

Julian Skidmore

unread,
Feb 22, 2012, 8:27:23 AM2/22/12
to fign...@googlegroups.com
Hi Ashley,

Actually I'm pretty stunned by the whole turtle graphics thing myself - I didn't you'd go straight from getting the FIGnition to logging onto the group; suggesting the project and doing it before I'd had time to even say "Good idea!" !

And cramming it into 1 page really sets the bar. You're right about the 0D > comparison, 0xd is 13 not 14 D'oh! And thanks for fixing the cos table, it's not just a reverse of the sin table. I realised we can have our cake and eat it by adding 1 after we fetch from the table (and adjusting the rest of the values, so the table ends in 1A now). Your improvement at the end of f is cool, and improves performance especially for short lines. I made a change to f, surely the loop should start at 0 because as it stands I think 1 f and 2 f would do the same thing? Anyway, it makes the images slightly larger.

Although it's not a fair comparison, I've compared the demo procedures with the LCSI ZX Spectrum version of Logo.

Burst: 14.79s  ( FIGnition: 1.2s)
Squiral: 4.22s ( FIGnition: 0.4s ish)
Spiral: 2:14.47s !!! (FIGnition: 3.8s about 35x faster)
Stars: 3.34s. ( FIGnition: <0.4s)
Rose:13.28s. (  FIGnition <1s)
Flower: 2:15.44s !!! (FIGnition: 3.72).

I don't know how it compares with BBC Logo, but it's a © ROM so I can't legally download it. However, we can see that the Spectrum is awfully slow compared with FIGnition. However, we should consider that the Spectrum was using floating point arithmetic; the Logo screen is scaled and Logo is interpreted rather than being compiled, but the line drawing should dominate the time even on the Spectrum and FIGnition is still way faster :-)

How does it compare with Apple II Logo?

The latest .fth is attached (along with some .pngs of the images on my Spectrum).

-cheers from julz
FIG - black on whiteMini.jpg
SpiralLcsiScreenShot.png
StarsLcsiScreenshot.png
Turtle00.hex
TurtleLib.fth
NmLogoMini.jpg
BurstLcsiLogo.png
BurstLcsiScreenShot.png
FlowerLcsiScreenshot.png
Listings1.png
Listings2.png
Listings3.png
RoseLcsiScreenshot.png

Simon

unread,
Feb 22, 2012, 8:46:03 AM2/22/12
to fign...@googlegroups.com
I once fried a 3.25" floppy drive controller like that.  Blue smoke n everything.

Tony Kingsmill

unread,
May 22, 2012, 4:50:50 PM5/22/12
to fign...@googlegroups.com
Thought I'd try some of my saved programs since upgrading to "0_9_6Fix" firmware from the Google group on 2/2/12 and found I'm now having trouble loading Turtle graphics. It worked lovely before upgrading the firmware but now when loading the first block I get the error:

0x18 @0xd8 !0x142 vmode?
Err # 0

With my crude understanding of FigForth and the Figgy I imagine that vmode is no longer recognised for some reason. Any ideas what's going on? Has the keyword changed syntax or something? Cheers!

Rob Fielding

unread,
Dec 5, 2012, 2:17:33 PM12/5/12
to fign...@googlegroups.com
I'm also having trouble loading the Logo files not loading correctly.

I've tried the first Logo00.hex and the last speeded up Logo with the same result.

Seen with both the two recent PAL fix roms. FirmwareRev0_9_7PalLcd.hex

(steps, I'm a newbie, so this bit could be wrong)

avrdude -c usbasp -p m168 -u -U eeprom:w:Logo00.hex

boot the Fignition into TV,
-1 edit
Cmd-write 
See OK
shutdown, back to PC
 
avrdude -c usbasp -p m168 -u -U eeprom:w:Logo01.hex 

boot the Fignition into TV,
-2 edit
Cmd-write
See OK

2 load
seems OK [*]
d see ERR in amongst the jumble of hex from the load

Try and load again I can see ERR repeat alng the lines and down the screen.
[*] I've also managed to get it to just crash dead, requiring pull power and insert.
(Instant on - Love it!)

Will try another demo prog - have to jump. Back soon.

Julian Skidmore

unread,
Dec 5, 2012, 3:06:48 PM12/5/12
to fign...@googlegroups.com
Hi Rob,

It's not your fault, it's because text blocks are handled differently for the new firmware version. In the new one the editor edits ragged lines, like normal editors do, with <cr> characters at the end of each line. You can have lots of lines and up to 511 characters in a block and the editor window will scroll if necessary to see all of them. It's much, much nicer.

In the old editor it just edited a grid of 25x20 characters directly on the screen so it was limited to 500 characters. By default the last 12 characters were just inverse © characters.

So, when you load an old block using the new editor it can't understand the end of the block, it thinks it's the command ©©©©©©©©©©©©, so it gets confused.

The real solution is (for me/us) to publish screens that have the new format. Until then, I wonder if this will work. When you boot the FIGnition. Type this:

:<space><SW2+SW6>377  ( you should see a colon then space then inverse ©)
Then do cursor left and then press <SW6+SW2> which is MARK, it marks the current cursor position. Then go forward and press <SW1+SW5> which should be COPY. You'll see a second inverse ©. Then hold down <SW1+SW5> until you get 12 inverse © symbols in total.

Finally type ; then <exe> to compile it ( <SW5> then release then enter).

Now load in the first turtle graphics block.  Was that better?

-cheers from julz
NmLogoMini.jpg
FIG - black on whiteMini.jpg

Julian Skidmore

unread,
Apr 22, 2013, 3:51:24 PM4/22/13
to FIGnition
Hi folks, I've attached an update to the Turtle graphics library and demonstration program in a version that is intended to work with firmware 0.9.8. I've tested it on my version of the firmware.

There's a 4 block non-cryptic version (Turtles.fth) and a 2-block cryptic version. The cryptic version can be made more readable with the new ragged line editor, because it's always best to start a new command on a new line.

Have fun (non-cryptic library code listed):

0 var x 0 var y
0 var angle
0 var dx 0 var dy

hex create cosTable
-2 , F9F2 , E9DD ,
CEBD , AA95 , 7F67 ,
4E34 , 1A00 , decimal

: cos ( ang -- cos[ang])
  abs 60 mod dup 29 > if
    60 swap -
  then
  dup 14 > if
    -1 30 rot -
  else
    1 swap
  then
  cosTable + c@ 1+ *
;

: fixPoint!
  >r 80 + 8 << r> !
;

: jump ( dist--)
  dup dx @ * x +!
  dy @ * y +!
;

: setPos ( x y --)
  y fixPoint!
  x fixPoint!
;

: setH ( heading --)
  dup angle !
  dup cos dy !
  45 + cos dx !
;
( the first block ends here)

blk# @ 1- load
: fd ( dist--)
  >r dx @ x @ y @ dy @
  r 0 do
    >r r + >r over +

    dup 8 >> r 8 >> plot
    r> r>
  loop
  drop y ! x ! drop
  r> drop
;

: turtleEnd
  0 0 at
  ." Press a key to end"
  key 0 vmode
;

: home
  1 vmode 1 pen cls
  0 0 setPos 0 setH
;

: rt ( turn--)
  angle @ + setH
;


NmLogoMini.jpg
FIG - black on whiteMini.jpg
Turtles.zip
TurtleCrypt.fth
Reply all
Reply to author
Forward
0 new messages