Rotate Character

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Utility

Rotate Character reads a user-defined graphic (UDG) character entered in graphics mode, extracts its 8×8 pixel bitmap by PEEKing the eight bytes from USR memory, transposes the bit matrix into a two-dimensional array, then rebuilds and POKEs the rotated bitmap back into the UDG’s memory location. The pixel extraction loop unpacks each byte bit-by-bit using successive halving of an initial value of 128, storing results in a DIM Z(8,8) array. The transposed matrix is then repacked into bytes and displayed using block graphic characters alongside the POKE operation. Lines 1000–1040 preload UDG “a” with a sample character (the DATA values 252,128,128,248,128,128,128,252) so the program has a ready-made graphic to demonstrate the rotation effect.


Program Structure

The program divides into three logical sections:

  1. Setup and input (lines 1–6): Sets display colors, prints a title, prompts the user to enter a UDG letter (a–u) in graphics mode, and validates the input.
  2. Rotation engine (lines 10–150): Extracts the 8×8 bitmap via PEEK, stores it in a 2-D array, transposes it, repacks bytes, POKEs them back, and displays the result.
  3. UDG preloader (lines 1000–1040): Seeds UDG “a” with a sample L-shaped character so the user has an immediate test case.

Input Validation Bug

Line 6 contains a logical error in the validation condition:

6 IF A$<"a" OR "a">"u" THEN GO TO 5

The second operand of OR should be A$>"u", not the constant expression "a">"u". Because "a">"u" is always 0 (false), the upper-bound check is never performed. Any string less than "a" correctly re-prompts, but characters beyond "u" are silently accepted, potentially PEEKing and POKEing beyond the UDG area.

Bitmap Extraction (Lines 40–90)

DIM Z(8,8) allocates an 8×8 numeric array. The outer loop iterates over the 8 rows (bytes) of the UDG; the inner loop unpacks each row bit-by-bit. Starting with X=128 and halving after each bit, the code subtracts X from the current byte value when the result is non-negative — the standard ZX Spectrum bit-test idiom. The extracted bit (1 or 0) is stored at Z(Q,W) where Q is the column index (1–8) and W counts down from 8 to 1, achieving a 90° transpose.

Bitmap Repacking and Display (Lines 100–140)

The second double loop reads the transposed array row by row. For each set bit it accumulates a byte value using A=A+B (where B starts at 128 and halves), mirrors a block graphic character (\:: — the full block █) to the screen, and otherwise prints a space. After each row, POKE C,A writes the new byte directly into UDG RAM and advances pointer C.

Key Variables

VariableRole
A$UDG letter entered by user
ACurrent PEEK address (walks through 8 UDG bytes)
CBase POKE address (saved copy of USR A$)
Z(8,8)Intermediate transposed bit matrix
Q, WColumn and row indices into Z during extraction
X, BBit-weight accumulators (128→1) in extraction and repacking

Continuation Loop (Lines 155–170)

After displaying the rotated graphic, line 155 prompts the user to delete graphics mode and press Y or N. Line 160 contains a second typo: IF "R"="N" should be IF R$="N". Because the string constant "R" never equals "N", the N branch never triggers; instead, execution falls through to the unconditional STOP at line 170, which coincidentally produces the correct behavior but for the wrong reason.

UDG Preloader (Lines 1000–1040)

Lines 1000–1040 are not called from the main program flow — they must be run separately (e.g., RUN 1000) to seed UDG “a” with the sample shape before testing the rotation routine. The DATA values 252,128,128,248,128,128,128,252 define a bold capital F or similar rectilinear form.

Notable Techniques

  • Using USR A$ to obtain the RAM address of a named UDG is idiomatic and avoids hard-coding system addresses.
  • The bit-extraction method (subtract powers of two from 128 downward) is a common ZX Spectrum BASIC approach since there is no bitwise AND operator in standard BASIC.
  • Storing intermediate bits in a floating-point array Z(8,8) is simple but memory-intensive; a machine code routine could perform the same transpose in microseconds.
  • The block graphic \:: (█) used for display gives a visual 8×8 preview of the rotated character at PRINT resolution.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    1 INK 7:PAPER 0:BORDER 0
    2 PRINT TAB 8;"ROTATE CHARACTER"'''
    5 PRINT "GO TO GRAPHICS MODE !!!":PAUSE 180:CLS :INPUT "CHARACTER TO BE ROTATED ? "; LINE A$
    6 IF A$<"a" OR "a">"u" THEN GO TO 5
   10 LET A= USR A$:LET C=A
   20 LET Q=1:LET W=8
   40 DIM Z(8,8):FOR D=1 TO 8
   50 LET X=128:LET B= PEEK A
   60 FOR F=1 TO 8
   70 IF (B-X) >=0 THEN LET B=B-X:LET Z(Q,W)=1
   80 LET X=X/2:LET Q=Q+1
   90 NEXT F:LET Q=1:LET W=W-1:LET A=A+1:NEXT D
  100 FOR X=1 TO 8:LET A=0:LET B=128
  110 FOR Y=1 TO 8
  120 IF Z(X,Y)=0 THEN PRINT " ";:GO TO 140
  130 LET A=A+B:PRINT "\::";
  140 LET B=B/2:NEXT Y:POKE C,A:LET C=C+1:PRINT :NEXT X
  150 PRINT :PRINT "LOOK AT THE NEW GRAPHIC '";a$;"'!"''''
  155 PRINT "Now delete GRAPHICS mode. Press Y to continue - or N to stop"
  160 INPUT "Y OR N ";R$:CLS :IF R$="Y" THEN GO TO 5:IF "R"="N" THEN STOP 
  170 STOP 
 1000 FOR n= USR "a" TO USR "a"+7
 1010 READ user:POKE n,user
 1030 NEXT n
 1040 DATA 252,128,128,248,128,128,128,252

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top