FLIP is a BASIC loader and demonstration program that installs a 118-byte Z80 machine code routine at address 58250, providing two display-manipulation functions: a horizontal mirror (“backwards”) called via RANDOMIZE USR 58250, and a vertical flip (“upside down”) called via RANDOMIZE USR 58310. The machine code works directly on the display file, which on the TS2068/ZX Spectrum begins at address 16384 (0x4000), as evidenced by the DATA values 0,64 (low/high bytes of 16384) and the CLEAR 58249 protecting the code area in high RAM. Once installed, the routine persists in memory even after the BASIC loader is cleared with NEW, allowing it to be integrated into user programs and saved independently as CODE 58250,118. The demonstration loop uses PAUSE 0 followed by INKEY$ to efficiently wait for a keypress before invoking either entry point.
Program Analysis
Program Structure
The program is organized into four logical phases, separated by REM blocks:
- Introduction (lines 100–180): Clears memory above 58249 and prints usage instructions, explaining how to incorporate the routine into user programs.
- Machine Code Installation (lines 900–950): A
FOR/READ/POKEloop deposits 118 bytes of Z80 machine code into addresses 58250–58367. - Data (lines 1000–1040): Five
DATAstatements holding the machine code bytes. - Demonstration Loop (lines 1500–1930): Waits for a keypress and dispatches to the appropriate entry point.
Memory Layout
CLEAR 58249 at line 50 sets RAMTOP just below the installation area, protecting the machine code from BASIC’s memory management. The routine occupies addresses 58250–58367, a span of exactly 118 bytes, consistent with the SAVE "name" CODE 58250,118 instruction shown at line 180.
| Address | Purpose |
|---|---|
| 58250 | Entry point: horizontal mirror (“B” / backwards) |
| 58310 | Entry point: vertical flip (“U” / upside down) |
| 58367 | Last byte of routine |
Machine Code Analysis
The DATA bytes reveal Z80 operations working directly on the display file. Key constants embedded in the data confirm this:
0, 64— little-endian address 16384 (0x4000), the start of the display file.192— 0xC0, used as a row counter (192 pixel rows in the display).32— 0x20, used as a column counter (32 bytes per pixel row).24— 0x18, likely 24 character rows for attribute/row handling.- Negative DATA values (
-9,-23) are relative jump offsets for Z80JRinstructions, stored as signed bytes; BASIC accepts these and POKEs the correct two’s-complement value. 203— 0xCB, the Z80 CB prefix, indicating bit manipulation or rotate/shift instructions used for the flip logic.237, 176— Z80 opcodeLDIR(block copy), used in the final DATA line to efficiently copy data back to the display.201— Z80RET, terminating the routine and returning control to BASIC’sRANDOMIZE USR.
The horizontal mirror routine (entry at 58250) reads each pixel row, reverses the bit order within each byte, and writes the bytes back in reverse order across the row. The vertical flip routine (entry at 58310) swaps pixel rows top-to-bottom. The display’s non-linear pixel row addressing in the file necessitates careful pointer arithmetic, which the machine code handles with 16-bit register pair operations (HL, DE, BC).
Key BASIC Idioms
- PAUSE 0 / INKEY$ pattern: Line 1500 uses
PAUSE 0to halt until any key is pressed, then line 1510 captures the key withLET k$=INKEY$. Lines 1920–1930 form a secondary wait loop ensuring the key has been released before looping back, preventing repeated triggering. - Case-insensitive input: Lines 1900 and 1910 test both lowercase and uppercase variants of the trigger keys, accommodating either shift state.
- Signed DATA bytes: Using
-9and-23for Z80 relative jump offsets is a practical technique; BASIC’sREADaccepts signed integers andPOKEstores the low byte, yielding the correct two’s-complement displacement.
Notable Techniques
Distributing the machine code across five DATA lines (1000–1040) rather than one long line keeps each line short enough to be reliably entered and edited. The BASIC loader is designed to be disposable: the user runs it to install the code, then types NEW to clear BASIC while the machine code survives above RAMTOP. The routine can then be saved as a standalone CODE file for use in other projects, as documented in the on-screen instructions.
Bugs and Anomalies
Line 1920 checks IF INKEY$="" THEN GO TO 1500, intending to loop back only when no key is held. However, if a key other than “B”, “U”, “b”, or “u” was pressed, lines 1900 and 1910 both fall through, and line 1920 will loop back to 1500 immediately once the key is released — this is functionally correct but means unrecognized keys are silently ignored rather than flagged. This is a minor design choice rather than a defect.
The comment at line 2000 states the routine “requires one second to manipulate the display,” which is a realistic estimate for iterating over 192 pixel rows in interpreted Z80 machine code without any hardware acceleration.
Content
Source Code
10 REM "FLIP"
20 REM CATS Library FEB 1986
30 REM
50 CLEAR 58249
100 REM -INTRODUCTION-
110 PRINT AT 0,7; FLASH 1;" WELCOME TO FLIP "
120 PRINT : PRINT : PRINT """U""= UPSIDE DOWN (flip vertical)"
130 PRINT : PRINT """B""= BACKWARDS (flip horizontal)"
140 PRINT : PRINT : PRINT " This short Basic program installs a machine code, display manipulating routine at 58250."
150 PRINT : PRINT "To demonstrate: Touch ""U"" or ""B"""
160 PRINT : PRINT " To incorporate the code into your own program: RUN ""FLIP"" : CLEAR ""FLIP"" by entering NEW : ENTER your own Basic Program:"
170 PRINT "Call: ""B"" by RANDOMIZE USR 58250 ""U"" by RANDOMIZE USR 58310"
180 PRINT "Save with:",," SAVE ""name""CODE 58250,118"
899 REM
900 REM -INSTALL MACHINE CODE-
901 REM
910 FOR i=58250 TO 58367
920 READ a
930 POKE i,a
950 NEXT i
1000 DATA 33,42,228,17,0,64,213,6,192,197,6,32,197,1,0,8,26,203,7,48,2,203,193,203,9,16,246,113,43,19,193,16,235,14,64,9,193,16,226
1010 DATA 33,42,252,6,24,197,1,64,32,26,119,43,19,16,250,9,193,16,242,24,48
1020 DATA 33,0,64,17,10,252,229,1,0,24,197,175,6,8,78,203,1,48,2,203,199,15,16,-9,18,35,27,193,11,120,177,32,-23
1030 DATA 1,0,3,17,10,255,126,18,35,27,11,120,177,32,-9
1040 DATA 209,33,11,228,1,0,27,237,176,201
1497 REM
1498 REM -DEMONSTRATE "B" & "U"
1499 REM
1500 PAUSE 0
1510 LET k$=INKEY$
1900 IF k$="b" OR k$="B" THEN RANDOMIZE USR 58250
1910 IF k$="u" OR k$="U" THEN RANDOMIZE USR 58310
1920 IF INKEY$="" THEN GO TO 1500
1930 GO TO 1920
2000 REM "FLIP" REQUIRES ONESECOND TO MANIPULATE THE DISPLAY
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.


