Xmas Card

Developer(s): Chuck Dawson
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Holiday

This program displays an animated Christmas card greeting with a decorated tree and festive message, then plays three carol melodies in sequence using the BEEP command before looping. The display uses FLASH and alternating INK/PAPER colors to create a bordered announcement box, while PLOT and DRAW commands construct a filled triangle representing a Christmas tree with a star. Two UDGs are defined at line 9000 — UDG “a” (a filled circle, 60,126,255…) and UDG “b” (a hollow square/frame, 255,129,129…) — which are used as decorative ornaments scattered across the tree with randomised positions and colors. The music section at lines 110–140 reads DATA blocks for three separate tunes (“We Wish You a Merry Christmas,” “O Christmas Tree,” and another carol).


Program Analysis

Program Structure

The program is organised into distinct functional phases:

  1. Initialisation (lines 1–2): A RESTORE and GO SUB 9000 define the two UDG characters before any display occurs.
  2. Header box (lines 3–12): A flashing border box is drawn using PRINT AT with block graphics, enclosing the “MERRY CHRISTMAS / FROM THE DAWSONS” message.
  3. Tree construction (lines 15–30): A filled triangle is built with PLOT/DRAW loops and finished with a trunk rectangle.
  4. Ornament scatter (lines 40–100): UDG characters are placed at randomised screen positions with randomised ink colours and occasional FLASH.
  5. Music loop (lines 110–150): Three DATA blocks of note-duration pairs are played via BEEP, with PAUSE gaps between tunes, looping forever via GO TO 100.
  6. UDG definition subroutine (lines 9000–9510): Reads eight bytes each for UDGs “a” and “b” into their respective memory locations.

UDG Definition

Line 9000 uses a compact loop: FOR i=USR "a" TO USR "b"+7 to iterate over all 16 bytes covering both UDGs in a single pass, reading from the DATA at line 9500/9510. UDG “a” (bytes 60,126,255,255,255,255,126,60) defines a filled oval/circle shape used as a bauble. UDG “b” (bytes 255,129,129,129,129,129,129,255) defines a hollow square frame. The subroutine uses RESTORE 9000 to position the DATA pointer correctly before reading.

Tree Drawing Technique

The Christmas tree is drawn at lines 20–30 using a FOR loop with a STEP of 0.5, exploiting the Spectrum’s floating-point loop counter to achieve finer horizontal density. Each iteration draws two horizontal lines symmetrically from a central spine, creating a filled triangular silhouette. Lines 25 and 30 add a star at the apex using DRAW INK 9 and a rectangular trunk drawn with a second loop.

Music DATA Format

The three carol DATA blocks use paired values (duration, note) passed directly to BEEP. Each block’s duration values are divided by a different constant to control tempo:

LinesDATA startNote countDivisorEffect
11080030 pairs÷2Moderate tempo
12090061 pairs÷2Moderate tempo
130100057 pairs÷3Faster
140101096 pairs÷5Fastest

After the four tunes, PAUSE 120 provides a gap and GO TO 100 at line 150 returns to the ornament-scatter section rather than line 110, meaning the ornaments are re-randomised on each loop but the screen background is not cleared — baubles accumulate over iterations.

Notable BASIC Idioms

  • RND*4+8 style expressions produce random screen positions within constrained column ranges for each ornament type, distributing them across the tree area without explicit collision detection.
  • FLASH RND*1 at line 90 exploits the fact that RND returns a value in [0,1) — values ≥0.5 round to 1 (FLASH on) and values <0.5 round to 0 (FLASH off), giving a 50% random flash probability.
  • The inner loop at lines 90–100 prints eight instances of UDG “b” per pass with randomised positions and colours, increasing ornament density on repeated loops.
  • INK 9 (transparent ink) is used in several places to allow background paper colours to show through, and line 9999 sets INK 9 as a trailing default.

Anomalies and Notes

  • Line 9999 contains a bare INK 9 statement with no line flow leading to it from normal execution; it acts as a dead statement and is never reached during normal program operation.
  • Line 8999 is a STOP that prevents the interpreter from falling through from the music data into the subroutine at line 9000 if ever reached, acting as a guard.
  • The scripture quote at line 27 (“Unto you there has been born a Savior”) is positioned over the tree graphic area, overlapping the PLOT/DRAW content since no CLS is issued between the tree drawing and text printing phases.
  • The loop variable i (lowercase) and I (uppercase) are used interchangeably in different sections; on the Spectrum, these are treated as the same variable, which could cause loop counter interference between the ornament loops and the music loops if not properly managed by NEXT matching.

Content

Appears On

One of a series of library tapes. Programs on these tapes were renamed to a number series. This tape contained

Related Products

Related Articles

Related Content

Image Gallery

Xmas Card

Source Code

    1 REM SAVE *"XMASCARD" LINE 1
    2 RESTORE : GO SUB 9000
    3 BORDER 2: PAPER 1: CLS : RANDOMIZE 
    5 PRINT INK 2; PAPER 4; FLASH 1;AT 2,14;"▞▞▞▞▞▞▞▞▞▞▞▞▞▞▞▞▞"
    6 FOR i=3 TO 5: PRINT INK 2; PAPER 4; FLASH 1;AT i,14;"▞";AT i,30;"▞": NEXT i
   10 PRINT AT 3,15; INK 9;"MERRY CHRISTMAS"
   11 PRINT AT 4,15; INK 9;" FROM THE";AT 5,20;"DAWSONS"
   12 PRINT INK 2; PAPER 4; FLASH 1;AT 6,14;"▞▞▞▞▞▞▞▞▞▞▞▞▞▞▞▞▞"
   15 INK 4
   20 FOR I=16 TO 80 STEP .5: PLOT I,2*I: DRAW INK 4;(80-I),0: PLOT 80,I*2: DRAW INK 4;(80-I),0: NEXT I
   25 PLOT INK 4;80,160: DRAW INK 9;0,10: PLOT INK 6;77,165: DRAW INK 9;6,0
   27 PRINT INK 9;AT 14,17;"Unto you";AT 16,18;"there has been";AT 18,19;"born a Savior"
   30 FOR i=16 TO 31: PLOT INK 9;70,i: DRAW INK 9;20,0: NEXT i
   40 PRINT AT 15,RND*4+8; PAPER 4; INK RND*4;"\a"
   50 PRINT AT 10,RND*4+7; PAPER 4; INK RND*4;"\a"
   60 PRINT AT 16,RND*13+3; PAPER 7; INK RND*4;"\a"
   70 PRINT AT 14,RND*2+9; PAPER 4; INK RND*4;"\a"
   80 PRINT AT 17,RND*7+6; PAPER 4; INK RND*4;"\a"
   90 FOR i=1 TO 8: PRINT AT 19,RND*13+3; INK RND*7; FLASH RND*1;"\b": INK 9
  100 NEXT i
  110 RESTORE 800: FOR i=1 TO 30: READ a,b: BEEP a/2,b: NEXT i
  120 PAUSE 100: RESTORE 900: FOR i=1 TO 61: READ c,d: BEEP c/2,d: NEXT i
  130 PAUSE 120: RESTORE 1000: FOR i=1 TO 57: READ e,f: BEEP e/3,f: NEXT i
  140 RESTORE 1010: PAUSE 150: FOR i=1 TO 96: READ g,h: BEEP g/5,h: NEXT i
  150 PAUSE 120: GO TO 100
  800 DATA 1,2,1,7,.5,7,.5,9,.5,7,.5,6,1,4,1,4,1,4,1,9,.5,9,.5,11,.5,9,.5,7,1,6,1,2,1,2,1,11,.5,11,.5,12,.5,11,.5,9,1,7,1,4,.5,4,.5,4,1,2,1,9,1,6,3,7
  900 DATA 1,0,.75,5,.25,5,1,5,1,7,.75,9,.25,9,1.5,9,.5,9,.5,7,.5,9,1,10,1,4,1,7,1.5,5,1,0,.75,5,.25,5,1,5,1,7,.75,9,.25,9,1.5,9,.5,9,.5,7,.5,9,1,10,1,4,1,7,1.5,5,.5,12,.5,12,.5,9,1.5,14,.5,12,.5,12,.5,10,1.5,10,.5,10,.5,10,.5,7,1.5,12,.5,10,.5,10,.5,9,1,9,1,0,.75,5,.25,5,1,5,1,7,.75,9,.25,9,1.5,9,.5,9,.5,7,.5,9,1,10,1,4,1,7,1,5
 1000 DATA 1,12,.75,11,.25,9,1.5,7,.5,5,1,4,1,2,1.5,0,.5,7,1.5,9,.5,9,1.5,11,.5,11,3,12,.5,12,.5,12,.5,11,.5,9,.5,7,.75,7,.25,5,.5,4,.5,12,.5,12,.5,11,.5,9,.5,7,.75,7,.25,5,.5,4,.5,4,.5,4,.5,4,.5,4,.25,4,.25,5,1.5,7,.25,5,.25,4,.5,2,.5,2,.5,2,.25,2,.25,4,1.5,5,.25,4,.25,2,.5,0,1,12,.5,9,.75,7,.25,5,.5,4,.5,5,1,4,1,2,4,0
 1010 DATA 1,0,1,9,1,7,1,5,3,0,.5,0,.5,0,1,0,1,9,1,7,1,5,4,2,1,2,1,10,1,9,1,7,4,4,1,14,1,12,1,10,1,7,4,9,1,0,1,9,1,7,1,5,4,0,1,0,1,9,1,7,1,5,3,2,1,2,1,2,1,10,1,9,1,7,1,12,1,12,1,12,1,12,1,14,1,12,1,10,1,7,4,5,1,9,1,9,2,9,1,9,1,9,2,9,1,9,1,12,1.5,5,.5,7,4,9,1,10,1,10,1,10,1,10,1,10,1,9,1,9,.5,9,.5,9,1,9,1,7,1,7,1,9,4,7,1,9,1,9,2,9,1,9,1,9,2,9,1,9,1,12,1.5,5,.5,7,4,9,1,10,1,10,1,10,1,10,1,10,1,9,1,9,.5,9,.5,9,1,12,1,12,1,10,1,7,4,5
 8999 STOP 
 9000 RESTORE 9000: FOR i=USR "a" TO USR "b"+7: READ r: POKE i,r: NEXT i: RETURN 
 9500 DATA 60,126,255,255,255,255,126,60
 9510 DATA 255,129,129,129,129,129,129,255
 9999 INK 9

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

Scroll to Top