A Bit about Alphabit

During Synchrony 2019, on the train from New York City to Montreal, two of us (nom de nom and shifty) wrote a 64 byte Commodore 64 program which ended up in the Old School competition. (It could have also gone into the Nano competition for <=256 byte productions.) Our Alphabit edged out the one other fine entry in Old School, a Sega Genesis production by MopeDude also written on the train.

The small program we wrote is not a conventional or spectacular demo; like almost all of the work by nom de nom, it uses character graphics exclusively. But since we like sizecoding on the Commodore 64, we wanted to explain this small program byte by byte. We hope this explanation will be understandable to interested people who know how to program, even if they may not have much assembly or C64 experience.

To get Alphabit itself, download the program from nickm.com and run it in a C64 emulator or on some hardware Commodore 64. You can see a short video of Alphabit running on Commodore 64 and CRT monitor, for the first few seconds, for purposes of illustration.

              starting here,
              these bytes load
at:     02 08 01 00 00 9E 32 30
$0808   36 31 00 00 00 20 81 FF
$0810   C8 8C 12 D4 8C 14 D4 C8
$0818   8C 20 D0 AD 12 D0 9D F4
$0820   D3 8C 18 D4 D0 F5 8A 8E
$0828   0F D4 AE 1B D4 E0 F0 B0
$0830   F6 9D 90 05 9D 90 D9 AA
$0838   88 D0 E0 E8 E0 1B D0 DB

Load address. Commodore 64 programs (PRG files) have a very simple format: a two-byte load address, least significant byte first, followed by the machine code which will be loaded at that address. So this part of the file says to load at $0802. The BASIC program area begins at $0801, but as explained next, it’s possible to cheat and load the program one byte higher in memory, saving one byte in the PRG file.

BASIC bootloader, $0802–$080c: This program starts with a tiny BASIC program that will run when the user types RUN and presses ENTER. When run, this program, a bootloader, will execute the main machine code. In this case the program is “0 SYS2061” with the line number represented as 00 00, the BASIC keyword SYS represented by a single byte, 9E, and its argument “2061” represented by ASCII-encoded digits: 32 30 36 31. When run, this starts the machine code program at decimal address 2061, which is $080D, the beginning of the next block of bytes.

Advanced note: Normally a BASIC program would need at least one more byte, because two bytes at $0801 and $0802 are needed to declare the “next line number.” You would have to specify where to go after the first line has finished executing. But for our bootloader, any non-null next line number will work as the next line number. Our program is going to run the machine code at $080d (decimal 2061) and then break. So we only need to fulfill one formal requirement: Some nonzero value has to be written to either $0801 or $0802. For our purposes, whatever is already in $0801 can stay there. That’s what allows this program to load at $0802, saving us one byte.

On the 6502: There are three “variables” provided by this processor, the accumulator (a general-purpose register, which can be used with arithmetic operations) and the x and y registers (essentially counters, which can be incremented and decremented).

Initialization, $080d–$081a: This sets up two aspects of the demo, sound and graphics. Actually, after voice 3 is initialized, it is used not only to make sound, but also to generate random numbers for putting characters on screen. This is a special facility of the C64’s sound chip; when voice 3 is set to generate noise, one can also retrieve random numbers from the chip.

The initialization proceeds by clearing the screen using the Kernal’s SCINIT routine. When SCINIT finishes, the y register has $84 in it. It turns out that for our purposes the noise waveform register and the sustain-decay register can both be set to $85, so instead of using two bytes to load a new value into y (ldy #$85), the program can simply increment y (iny), which takes only one byte. After storing $85 in those two registers, the goal is to set the border color to the same as the default screen color, dark blue, $06. Actually any value with 6 for a second hex digit will work, so again the program can increment y to make it $86 and then use this to set the border color. Finally, the y register is going to count down the number of times each letter (A, B, C … until Z) will be written onto the screen. Initially, the program puts ‘A’ on screen $86 times (134 decimal); for every subsequent letter, it puts the letter on screen 256 times — but that comes later. The original assembly for this initialization:
    iny         ; $85 works for the next two...
    sty $d412   ; voice 3 noise waveform
    sty $d414   ; voice 3 SR
    iny         ; $86 works; low nybble needs to be $6
    sty $d020   ; set the border color to dark blue
Each letter loop, first part, $081b–$0826: This loop counts through each of the 26 letters. The top part of the loop has a loop within it in which some of the sound is produced; then there is just a single instruction after that.

Fortunately, the x register already is set up with $01, the screen code of the letter ‘A’, thanks to SCINIT. In this loop, the value of the current raster line (the lowest 8 bits of a 9-bit value, to be precise) is loaded into the accumulator. The next instruction stores that value in a memory location indexed by x; as x increases during the run of the program, this memory location will eventually be mapped to the sound chip registers for voices 1 and 2, starting at $d400, and this will make some sounds. This is what gives some higher-level structure to the sound in the piece, which would otherwise be completely repetitive. After this instruction, however many characters are left to put onto the screen (counting down from 255 to 0) goes into the volume register, which causes the volume to quickly drop and then spike to create a rhythmic effect. With the noise turned on it makes a percussive sound. All of this takes place again and again until that raster line value is 0, which happens twice per frame, 120 times a second.

After all of this, the value in x (which letter, A–Z, is the current one) is transferred into the accumulator, necessary because of how the rest of the outer loop is written. The original assembly for the beginning of the outer loop:
raster:
    lda $d012   ; get raster line (lowest 8 bits)
    sta $d3f4,x ; raster line --> some sound register
    sty $d418   ; # of chars left to write --> volume
    bne raster
    txa
Get random, $0827–$0830: This code does a bit more sound work, using the x register to set the frequency. Since this is the current letter value, it increases throughout the run of the program, and the pitch generally rises. Then, a random value (well, not truly random, but “noisy” and produced by the sound chip’s noise generator) is loaded in that x register, with the program continuing to get the value until it is in the range $00–$ef (decimal 0–239). If the value has to be obtained multiple times, frequency gets set multiple times, too, adding some glitchiness to the sound. Because the random value is bounded, the program will place the characters in a 40 character × 6 line (240 character) region.
random:
    stx $d40f       ; current letter --> freq
    ldx $d41b       ; get random byte from voice 3
    cpx #240
    bcs random
Each letter loop, last part, $0831–$083a: In the bottom part of this loop, the characters are put onto the screen by writing to screen memory and color memory. Screen memory starts at $0400, and $0590 is the starting point of our 6-line rectangle in the middle of the screen. The corresponding point in color memory is $d990. Our current character (A–Z) is in the accumulator at this point, while the x register, used to offset from $0590 and $d990, has a random value. After putting the accumulator’s value (as a letter) into screen memory and (as a color) into color memory, the accumulator is transferred back into the x register, a counter. Then the y register (counting down to 0) is decremented. The program keeps doing this whole process, the “each letter loop,” until y reaches 0.
    sta $0590,x  ; jam the current letter on screen
    sta $d990,x  ; make some colors with the value
    tax
    dey
    bne raster
Outer loop, $083b–$083f: This is the code for counting from 1 to 26, A to Z. Since the x register stores the current letter, it is incremented here. It is compared with decimal 27; if the register has that value, the program is done and it will fall through to whatever is next in memory … probably $00, which will break the program, although anything might be in memory there. It would have been nice to have an explicit brk as part of this PRG, but hey, this is a 64-byte demo with a BASIC bootloader, written one day on a train. If the program has more letters to go through, it branches all the way back up to the beginning of the “each letter loop.”
    inx
    cpx #27     ; have we gotten past ‘Z’?
    bne raster

Sounds, User-Input Phrases, and Monkeys in “Taroko Gorge”

Check out “Wandering through Taroko Gorge,” a participatory, audio-enabled remix.

As James T. Burling stated on the “projects” page of MAD THEORY:

>In this combination of presentation and poetry reading, I’ll present a remix of Nick Monfort’s javascript poetry generator, “Taroko Gorge.” My remix added a musical component using a computers oscilloscope function, and more importantly allows participant-observers to type in answers to prompts which are then added to the poem in real-time. The poem will be available throughout the day, gradually adding all inputs to its total sum. I’ll discuss the process of decoding html and javascript as a non-coder, describe some of my theories on participatory performance using computer interfaces, and raise questions about agency in performance and how a digital artifact can function as a poetic event.

Funk’s SoundBox 2012

Chris Funkhouser’s SoundBox 2012 has been posted in the online gallery space of DDDL, which I believe stands for Digital, Digital, Digital, digitaL. Or maybe Digital Digital Digital Littérature? There is a rich array of work up there; Chris’s contribution blends sounds with the carefully-recorded speech that he has recorded across many conferences and beyond, providing a rich audio record of activity in electronic literature and E-Poetry. As the description of the work says,

> Combining music, demented artistic performances, lectures, and studio experiments, Funk’s SoundBox 2012 draws from hundreds of digital recordings produced by poet-critic Chris Funkhouser, who condenses them into a single interactive space. Users of this personal archive – a balance of words and sounds Funkhouser wishes to remember and share – will find ambient and raw materials amidst discussions led by some of the most influential figures in the field of digital writing, grand improvisations featuring a range of instrumentation, software play, and more weaved into a unique sonic projection.

Except — wait. Those are documented artistic performances, lectures, and studio experiments. Sheesh.

Zombies, Run! Enhancement Instructions

Beginner: Run up behind the participant unseen, assume the attitude of a zombie, and say “ggrgrghrhrhHHH BRAINS!” and the like.

Intermediate: Run up alongside the participant, assume the attitude of Michael Jackson in Thriller, and say “It’s only a movie!,” “What’s the problem? Come on, I’ll take you home,” and the like.

Ubu Runs Ubuntu!

Welcome back to the Web’s major agglomeration of the avant-garde, Ubuweb.

(I don’t know that Ubu actually runs Ubuntu, but some statements are univocalically true regardless. And the site is back up, that’s for sure.)

Steve McCaffery Reading Carnival at Purple Blurb

Steve McCaffery read at MIT in the Purple Blurb series on March 19, 2012. A recording of part of that reading (his reading of Carnival) is embedded above; the text of my introduction follows.

Thank you all for braving the cold to come out today. Did you know that today is officially the last day of Winter? Ever! Winter is officially over forever!

But I come not to bury Winter, but to praise Steve McCaffery, and to introduce him. Steve McCaffery is professor and Gray Chair at the University of Buffalo in the Poetics Program. He comes to us from there, and before, from Canada, where he did much of his pioneering work in sound and concrete poetry. He is one of those people who is know for his non-digital work but without whom the current situation of electronic literature, of digital writing, could not exist. He is in that category, for instance, with Jorge Luis Borges.

You would have me institutionalized for loggorrhea if I attempted to read Steve McCaffery’s entire bibliography and discography to you.

Know, however, that McCaffery was one of the Four Horsemen, along with bpNichol, Rafael Barreto-Rivera, and Paul Dutton. This groundbreaking group of sound poets, numbering almost as many mouths as there are vowels, released several albumbs: “Live in the West,” and “Bootleg,” and “caNADAda.”

McCaffery’s critical writing can found in “North of Intention: Critical Writings 1973-1986” and “Prior to Meaning: The Protosemantic and Poetics” His two-volume selected poems, “Seven Pages Missing,” was published in Coach House in 2000. It earned him his second Governor General’s Awards nomination; his first was for his 1991 book “Theory of Sediment.” More recently, there’s his “Verse and Worse: Selected Poems 1989-2009,” which he and Darren Wershler edited.

And, I’ll mention two other books, his “The Basho Variations,” published in 2007, which consists of different translations and version of Matsuo Basho’s famous haiku, which could be rendered clunkily as “old pond / frog jump in / water sound.” A digital version of this haiku can be seen in Neil Hennesy’s “Basho’s Frogger,” a modified version of the game Frogger in which the first row of floating items is missing so that one can only … you know … jump in. McCaffery is pond and frog and sound, placid and salient and resonant, and we are very lucky to have him here with us tonight.

Finally, I want to mention his extraordinary poem “Carnival.” I’ve taught the first panel to dozens of students here at MIT, so it’s black and red and read all over. The two panels of “Carnival” are incredible documents. If only fragments of them survive in three thousand years, that will be adequate for archaeologists to reconstruct the functioning and history of the typewriter completely. Of course, there’s more to “Carnival” than that material writing technology. But instead of saying more, I should simply let our guest give voice to “Carnival” and other works of his. Please join me in welcoming Steve McCaffery…

Charles Bernstein Sounds Off

Charles Bernstein just gave the keynote-like presentation at E-Poetry. (Actually, he used PowerPoint.) I’m providing a few notes, feebly extending in my subjective way some of his oral and photographic/digital presentation for those of you in the information super-blogosphere.

He started by mentioning the UB Poetics Program and its engagement with digital humanities, saying: “As Digital Humanities departs from poetics, it loses its ability to articulate what it needs to articulate.”

EPC and PennSound, he explained, are noncommerical spaces that aren’t proprietary, don’t have advertising, and are not hosted on corporate blogs or systems. These are dealing with digital archival issues – not as much computational poetry – but very important work to do on the Web. There was no foundation support for EPC, even though it was acknowledged as the most widely used poetry site on the Web.

PennSound, a project with the strong support of Penn thanks to the work of Al Filreis, has around 10 million downloads/year – even bigger than Billy Collins! There are about 40,000 individual files. This is bigger than anyone thinks poetry is today. But the NEH won’t fund the project because we aren’t mainly a preservation project; we don’t put audio on gold-plated CDs and place them in a vault.

Bernstein’s new book _Attack of the Difficult Poems_ gives an account of language reproduction technologies and poetics, explaining how different technologies exist overlaid at once. Hence, he explained that he is interested not only in e-poetry but also in d-poetry and f-poetry. Alphabetic, oral, and electronic cultures are overlaid today.

Talking machines, since Edison’s recitation of “Mary had a little lamb,” produce sounds that we process as if they were speech. The recorded voice only speaks and is private – unlike in the public of a live talk. The digital creates proliferations of versions, undermining the idea of the stable text even further.

Bernstein demonstrated the aesthetics of microphone breakdown and then explored the poetic possibilities of the presenter having difficulties with computer interface – he played some audio clips, too, showing that the “archives” we are discussing are productive of new works. Bernstein also welcomed an outpouring of “cover versions” of poems. Poets now only read each others’ work aloud at memorial gatherings. “Any performance of a poem is an exemplary interpretation.” Bernstein went though the specifics of four possibilities found in speech but not in text. Bernstein discussed “the artifice of accent” and how recorded voice, and digital access, have been important to this aspect of poetry.

Bernstein went on to discuss Woody Allen’s fear of books on tape, odd for someone for whom the more recent technologies of TV were so important. Charles presented his Yeats impersonation, which he suggests may be not as important as Yeats’ actual recorded reading, just as the Pope’s prayers may actually be more important even though we like to think that everyone’s are the same. Sound writing is the only kind of writing other than unsound writing.

I have a final image macro based on something Bernstein said immediately before he corrected himself. I hope this gives you some idea of why I’m a follower, a close follower, of Charles Bernstein…

an image macro

One-Line C64 BASIC Music

Local sound artist/electronic musician Keith Fullerton Whitman released an extraordinary piece on the b-side of his November 2009 cassette hallicrafters, inc. The piece is called 10 poke 54272+int(rnd(1) *25),int(rnd(1) *256) : goto 10 and is 18 minutes of sound produced by a Commodore 64 emulator running the BASIC program that is the title of the piece.

The memory locations beginning at 54272 are mapped on the Commodore 64 to the registers of the SID (Sound Interface Device). By POKEing random values into them, the SID, although it is a musical chip, is stimulated to produce sounds in what probably seems like a non-musical way: based on the effect of register settings and the sequence produced by the system’s random number generator, a polynomial counter.

I’m listening to the piece running on a hardware C64 now, which is soothing, although it seems like it shouldn’t be. Looking at the code, I note that the program

10 poke 54272+rnd(1) *25,rnd(1) *256 : goto 10

will put the same values into the same memory locations (and therefore SID registers) in the same order. The INT function is unnecessary because all arithmetic in C64 BASIC is done in floating point and then cast to integer whenever necessary. It’s possible that removing these functions will cause the piece to speed up, however, and I suspect it will, even though a BASIC interpreter could skip the unnecessary INT calls to begin with. There would be various ways of determining this, but the one I’d like to try involves getting two C64s, each with one version of the program, and seeing if they go out of phase.

By the way, I say that these two programs will put the same values in the same order because RND(1) returns a deterministic sequence. Any time either of these programs is invoked before other calls to RND are made, they will produce the same sequence. Using RND(0) would seed the random number generator on the jiffy clock, so would do different things depending upon how long the computer had been on before startup.

Thanks to sound artist and digital media scholar Kevin Driscoll, a.k.a. Lone Wolf, for letting me know about this.

Update: Hilariously, I overlooked that Whitman is not the author of this program – he credits Noah Vawter, a.k.a. Shifty, who is currently collaborating with me on a project about a one-line Commodore 64 BASIC program. I guess I was too distracted by that picture of an iPhone running a C64 emulator.