Twirl, an Intel 8080 Assembly program
I wrote Twirl, an Intel 8080 Assembly program that displays the ASCII animation of a bar twirling at the home position of the terminal screen. To make things a bit more clear I recorded a screencast to show the running program and what the animation looks like.
I developed this short program as an Assembly learning exercise related to Suite8080, a suite of Intel 8080 Assembly cross-development tools in Python I'm working on. The project, which is a lot of fun, drove me down a rabbit hole of Intel 8080 Assembly, CP/M, and retrocomputing.
I additionally wanted to explore the emuStudio execution environment and get the algorithm working. Now that it does, I can port Twirl to CP/M and add the program to Suite8080 as an Assembly demo.
The execution environment
Twirl runs on a virtual Altair 8800 computer in emuStudio, a beautiful emulator and Assembly development environment that can recreate a number of classic computers and CPUs.
I designed Twirl to run on a bare Altair 8800 connected to a Lear Siegler ADM-3A terminal. Any amount of RAM will do as the assembled code is only a few dozen bytes long. In the execution environment there's no host operating system or resident monitor, just a few basic character I/O subroutines emuStudio ships with.
Once started, Twirl runs an infinite animation loop. To terminate it I click the emuStudio
Stop emulation button.
By default the Altair 8800 runs at 2 Mhz in emuStudio, which causes some terminal flicker when executing Twirl. That's why I usually set the CPU frequency to 4 MHz, closer to that of late CP/M computers.
Here's the source code of Twirl:
; twirl.asm ; Twirling bar animation ; ; Runs in emuStudio emulating an Altair 8800 with an ; ADM-3A terminal FRAMES equ 8 ; Number of animation frames push h lxi h, CLS call putstr ; Clear screen pop h loop: lxi h, ANIM mvi b, FRAMES loop1: push h lxi h, HOME call putstr ; Go to home pop h mov a, m push h call putchar ; Print current frame pop h inx h dcr b jnz loop1 jmp loop hlt CLS: db 1ah, 0 ; ADM-3A escape sequence HOME: db 1eh, 0 ; ADM-3A escape sequence ANIM: db '|/-\|/-\' ; 8 frames include 'include\putstr.inc' include 'include\putchar.inc'
After clearing the screen, the program starts an infinite loop that repeats going through each frame of the animation, moving the cursor to the home position, and printing the current frame. The animation consists of a byte array containing the sequence of characters — frames — to display.
Some data definitions follow, i.e. the ADM-3A escape sequences to clear the screen and go to home, as well as the animation array.
The program ends with include directives for importing the following I/O subroutines:
putstr: prints to the terminal the 0-terminated string pointed to by the
putchar: prints to the terminal the character in register
The calls are enclosed in code that saves and restores the registers the subroutines overwrite.
What does it take to port Twirl to CP/M?
I use z80pack as my main CP/M emulator, so I design the Suite8080 demos to run on a machine with a VT100 or compatible terminal like the CP/M systems z80pack emulates.
I'll begin by converting the terminal escape codes from ADM-3A to VT100. Next, I'll replace the subroutine calls to equivalent BDOS calls. Finally, I want to support terminating the program by pressing any key. This will require code to check the console status for key presses.