Tuning in to Channel F

I first learned about this machine about 20 years ago in an article for the old classicgaming.com, back when I was an obsessive 10-year-old visitor of that site and all the dumb fansites it hosted.

I got into the system in earnest when an old interview with Jerry Lawson, one of the lead engineers on the project, was being passed around for Black History Month about 3 years ago. From there, I looked up what information there was for homebrewers (mostly just this wiki) and started tinkering here and there.

Beside the interesting history and my obvious fixation on technological primitivism, part of my fascination with the system comes from thinking of what could have been. The Channel F only ended up having about 26 games released for it, which seems like a far cry from the literally-industry-destroying hundreds the Atari 2600 ended up getting — but if you compare their libraries during their early years (up to 1978) the quantity and creativity of their software was roughly comparable (though Atari’s stuff was frankly better). I am thus led to wonder what history would have given us if their fortunes had been, by some chance, reversed.

Naturally, I haven’t actually done anything to really remedy that longing, but hope springs eternal.

What I have done thus far is make a fully commented disassembly of one of my favorite games on the system, Dodge It. The game is kind of like playing dodgeball if the balls were out to kill you. The amount of onscreen objects it can handle is quite impressive for the time (up to 11!), especially considering the system only came with 64 bytes of memory.

You can look at the code here (I even made a call graph and a memory map!):

Making this disassembly was quite a learning experience — though that does sound a bit ridiculous to say given how niche of a skill F8 assembly is — but I at least think I now have the confidence to make My Own Game now.

(I was working on a port of Hunt the Wumpus about a year and a half ago, but I never finished it because part of me realized that the idea (a line-by-line port of the original BASIC code) was a bit lame.)

tl;dr i now control f8 itself, ama

13 Likes

While the Atari 2600’s video chip is considered radical by modern standards, its design was fundamentally an incremental improvement over the electronics that drove the Pong-generation. The truly unorthodox part of the design was to have the chip be controlled not by a bespoke web of digital circuitry, but by a single-threaded mass-produced CPU racing against the beam. This unlikely marriage proved to be quite fruitful in its day, but lacks any modern descendants. The TIA is thus the zenith of a now-long-dead school of design.

The Channel F, on the other hand, displays video using the now-ubiquitous framebuffer, only in a very primitive form. It provides a luxurious 16 kilobit (2 kilobyte), 4 color, 128x64 pixel-addressable canvas, but said canvas is also only single-buffered, write-only, and lacking in any vsync or hsync capabilities. Moreover, it’s fill-rate is abysmal, allowing at most 1 pixel to be written per scanline. This framebuffer is thus the frail great-grandparent of its modern equivalents.

As far as resolution is concerned, only about 102x58 pixels of it are displayed onscreen, with the rest of the pixels being lost to time — unreadable and unshowable.

Regarding color, the system has a master palette of 8 colors. There are the primary foreground colors of red, blue, and green, and then a background color that can be set on a per-line basis (according to an offscreen column of pixels). The available background colors are light gray, light blue, light green, and black — however, if the background is black, then all foreground colors are white for that line.

chan0038

Anyhow, with that said, here are some out-of-context tests pics of my work on my rendering logic (colors, background colors, fill patterns, transparency, etc.). The code is adapted from here, but modified to suit my tastes and needs.

chan0016 chan0019 chan0021 chan0027 chan0030 chan0031 chan0032 chan0035

6 Likes

uh, i made another post here last night but i think i accidentally deleted it on my phone (mods halp) (paging @daphaknee)

EDIT: THANK YOU DAPHAKNEE!!

1 Like

Oh no it was a good post!

spent Too Much Time working on this today

time lapse of screenshots from each build:
diary 1

and here’s the last build of the day being rendered in slomo:
draw timelapse

This is going to be a simple 2 player side-view versus shooting game. Try to send your opponent into the drink. Get a shot into their goal to shorten the bridge on their side. Block their shots with your body, but be careful — that move might knock yourself into the water.

I don’t have anything remotely playable yet, but that’s the elevator pitch at least.

Anyhow, I wasted a whole byte of memory to make some waves:
waves v1

6 Likes

Status Update:

I got most of the player movement done (besides jumping and gravity), and the playfield collision is done.

The basic idea was to check the player’s position against a lot of bounding boxes, and clamp their position to a particular point, and set a flag accordingly. Here’s a handy diagram that I made to make sure I knew what I was doing when writing code:
hitboxes

I made a funny mistake with the collision underneath the bridge (I had my branches mixed up):
ejection error

The collision code isn’t the most elegant, but it does the job and should work for the bullets too. The movement handler is a placeholder (read: I still need to program in gravity), and as are the character graphics.
bg collision

The bridge allows you to land on it even from a couple pixels below.
bridge collision

The horizontal movement has acceleration, inertia, and drag. The x and y positions use the whole byte, with one bit of precision for subpixels. The x and y velocities are also only one byte, but they have 5 bits of subpixel precision. There’s a bit of weirdness to getting that to work, but it suffices.
horizontal movement b

It took me an embarrassing amount of time to figure out how to clamp the velocity in both directions. Despite my best efforts, figuring out which branch instructions correspond to which equality operators (==, >, <, etc) in which situations is still a maddening exercise.

oh, and if you hadn’t noticed, I updated the water animation. It still only uses one byte on the scratchpad (I still have 8 bytes that are unallocated).

Currently using 973 bytes of ROM space. I want to see if I can fit the game in 2k (at least for the first draft).

3 Likes

okay i got jumping to work:

jump stick on ceiling

wait why’s he sticking to the ceiling?

…lemme fix that…

ceiling glitch

uh, not what i had in mind…

*tries again*

moon jump

okay that’s more like it

5 Likes