man -w machine

quick'n'dirty guide to coding frame buffer fx in open firmware

introduction

while playing around with booting custom darwin kernels, i recently discovered that my powerbook provides lots of fun without even booting an operating system. so i spent all of breakpoint 05 demo party in openfirmware, trying to create some graphical effects. since there is not much documentation on this topic on the web, i wrote up the results of my try-and-error research here. since this is by no means exhaustive or coherent, feel free to contact me with questions =)

you can check out what i have accomplished so far if your dare:
hello.4th

setup the developing environment

to quickly write and test code for open firmware, a setup consisting of two hosts is recommended. the idea is to boot into open firmware on the mac and load the forth code via tftp over an ethernet link. a file called hello.4th located in /tftpboot on the server can be loaded in open firmware by the following command:

boot enet:172.23.5.23,hello.4th,172.23.5.5


with that setup, it is possible to conveniently edit the forth code on another machine and test it right away, without having to switch between darwin and open firmware. to avoid having to keep CMD-ALT-O-F pressed after booting every time, do setenv auto-boot? false. this will drop you to open firmware after power on. to continue to boot into darwin, use mac-boot.

header.4th

dev screen

one feature of open firmware is the ability to traverse the device tree via the dev command. depending on where in the device tree you are located, there are different forth words available. use dev screen to make the main screen the current dev node. (actually, screen is a devalias to the corresponding device node, try devalias screen to check where it's pointing to) this gives you some interesting words: /System/Library/CoreServices/BootX (the file which gets booted by open firmware and in turn boots /mach_kernel) contains code to set the color palette:

variable RGB-temp struct ( 000 )

: color!    ( r g b index -- )
  >r 
    RGB-temp 2+ c! 
    RGB-temp 1+ c!
    RGB-temp    c!
    RGB-temp
  r> 
  1 set-colors
;


using this word, we can define our own palette. unfortunately, index #0 is used as text color and index #f is used as background color, so in order to still be able to read the text, we can only use index #10 to index #ff for a nice grayscale palette:

ff ff ff 0 color! ( foreground color )
00 00 00 F color! ( background color )
100 10 do i i i i color! loop

color.4th
fb.4th

sine table

since open firmwares forth interpreter doesnt know about floating point arithmetics, it is necessary to work with integer sine tables. a short c program generates a forth table consisting of 360 entries ranging from 0x8 to 0x7F (so we can add two sine values later on without minding index wrap around)

sin.c
tsin.4th
trig.4th

a sine field in forth

: sinefield ( -- )
  numlines 0 do
    i
    screen-width 0 do
      dup 
      dup sin i sin +
      swap i pixeladr
      c!
    loop 
    drop 
  loop
;

since the primary data structure in forth is the stack, nested counting loops look kinda ugly =)

sinefield.4th

links

a forth tutorial
an open firmware reference
sample sources
all rights [r] belong to us.