I ported to CP/M Twirl, a twirling bar animation demo in Intel 8080 Assembly. I originally developed it for emuStudio, an emulator and development environment that recreates a number of classic computers and CPUs. The port runs on any CP/M system with an ANSI terminal or display.
This video shows Twirl running under CP/M 3.0 on the Z80-MBC2 computer, controlled from a Minicom terminal emulator session under Crostini Linux on my Chromebox.
How it works
The demo displays an ASCII animation of a bar twirling clockwise at the home position of the console, i.e. the top left corner. After clearing the screen, Twirl repeatedly moves the cursor to the console home, prints the current animation frame, and checks for key presses to decide whether to terminate.
Although visually simple, the program demonstrates some key Assembly programming techniques such as looping, calling BDOS functions, and doing output with ANSI escape codes.
The original Twirl runs on a virtual Altair 8800 computer with a Lear Siegler ADM-3A terminal emulated by emuStudio.
However, I designed the program intending to port it to CP/M. The necessary work consisted in replacing the Altair-specific I/O rutines with equivalent BDOS calls for printing a single character (function
02h) and a string (
09h) of ANSI escape codes, and checking the console status for key presses (
The program logic works as is, but I had to modify the CP/M version for defining the appropriate constants and ANSI escape strings, as well as adapting to the execution environment of the operating system and returning control to it.
Building and running
For me, the whole point of writing programs like Twirl and getting Z80 hardware is to use Suite8080, the suite of Intel 8080 Assembly cross-development tools I'm writing in Python. The CP/M port is a new Suite8080 Assembly demo I built from source on Linux with
asm80, the Suite8080 assembler:
$ asm80 twirl.asm
I tested the resulting 74 bytes
twirl.com executable under CP/M 2.2 with the CP/M software emulators ANSI CP/M emulator and z80pack.
Running the demo at the CP/M prompt is straightoward:
Pressing any key quits Twirl and returns control to the operating system.
To exeute Twirl on actual hardware I converted
twirl.com to Intel HEX format with z80pack's
bin2hex tool, then transferred the
twirl.hex file to the Z80-MBC2 under CP/M 3.0.
It was really rewarding to see Twirl come to life on a real Z80 computer and get a sense of its performance.
Here is the full code of the CP/M port of Twirl:
; Twirling bar animation.
; Runs on CP/M with an ANSI terminal. Press any key to quit the program.
TPA equ 100h
BDOS equ 0005h
WRITESTR equ 09h ; Write string
WRITECHR equ 02h ; Write character
CONSTAT equ 0bh ; Console status
FRAMES equ 8 ; Number of animation frames
mvi c, WRITESTR
lxi d, cls ; Clear screen
loop: lxi h, anim ; Initialize frame pointer...
mvi b, FRAMES ; ...and count
loop1: push h
mvi c, WRITESTR
lxi d, home ; Go to screen home
mvi c, WRITECHR
mov e, m ; Print current frame
mvi c, CONSTAT ; Get console status
ora a ; Key pressed?
jnz exit ; Yes
inx h ; Point to next frame
dcr b ; One fewer frame
cls: db 1bh, '[2J$' ; ANSI clear screen: ESC [ 2 J
home: db 1bh, '[H$' ; ANSI go to screen home: ESC [ H
anim: db '|/-\|/-\' ; 8 frames
The program represents the animation as the string
|/-\|/-\, a sequence of ASCII characters that show the bar at various steps of the rotation.
After clearing the screen, Twirl begins the main loop
loop: by initializing the frame pointer and count. An inner loop
loop1: prints each animation frame, i.e. the characters of the animation sequence.
The inner loop moves the cursor to the home position and prints the current frame. Then it updates the frame pointer and count, and checks whether a key was pressed. In case of a key press the inner loop exits the program, otherwise it jumps back to the beginning of the main loop.
#Assembly #retrocomputing #Suite8080 #z80mbc2 #CPM
Email | Reply @firstname.lastname@example.org