FEEDFACE.COM

300 IN AAAA 2001:1a50:7:1::feed:face



2005-04-07

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 open firmware, 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:

  • screen-width
    screen-height
    these expand to the dimension of the screen in pixels
  • set-colors
    this enables you to specify an 8bit palette.
  • frame-buffer-adr
    this is the base address of the frame buffer. write bytes to the memory range between frame-buffer-adr and frame-buffer-adr + screen-width * screen-height and watch how the pixels on the screen take on the corresponding index color.
/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