Christmas Special

Date: 1983
Type: Program
Platform(s): TS 2068

This program renders an animated starfield scene with custom UDG characters and scrolling text banners, accompanied by a musical fanfare. Seven UDGs (labeled “a” through “f” and “e”) are defined using BIN literals to create pixel-art sprites — likely figures and decorative elements — by poking 8-byte bitmaps into the UDG area via USR. The drawing section uses PLOT and DRAW commands to construct geometric shapes (possibly a building or trophy outline) and fills regions using nested FOR loops. Two string variables, a$ and b$, each 65 characters wide, implement horizontal marquee scrolling at screen rows 3 and 6 by rotating characters through string slicing. The BEEP-based music routines at lines 4000–5110 play a short repeating fanfare with recognizable rhythmic patterns using pitch values and durations.


Program Analysis

Program Structure

The program is organized into several clearly separated phases:

  1. Initialization (lines 5–80, 100–570): Variables are set and seven UDG characters are defined via POKE.
  2. Scene setup (lines 1000–1100): Scrolling string buffers are initialized and the screen is cleared with black paper.
  3. Background drawing (lines 2000–2010): Stars (dots) and UDG \f characters are scattered randomly.
  4. PLOT/DRAW artwork (lines 3000–3270): Geometric shapes are drawn and filled using nested loops.
  5. Scrolling loops (lines 3300–3999): Two marquee text rows scroll indefinitely, with music subroutine calls between passes.
  6. Music subroutines (lines 4000–5110): BEEP-based fanfares organized into modular subroutines.

UDG Character Definitions

Lines 10–570 define six UDGs using POKE USR "x"+n, BIN xxxxxxxx to write 8-byte bitmaps. The UDGs defined are:

UDGEscapeNotes
"e"\eAsymmetric figure, likely a person or alien sprite
"a"\aMirror/variant of \e; row 6 missing (line 170 absent)
"b"\bDense rectangular shape, possibly a trophy or object
"c"\cHorizontal line in center row only (row 3 = BIN 11111111); acts as a spacer/divider
"d"\dMirror of \b
"f"\fDiamond/star shape; used in the starfield foreground

Note that UDG "a" is missing its row 6 definition (line between 160 and 180 is absent), so USR "a"+6 retains its previous value — a minor anomaly that may affect the sprite’s appearance.

Background and Scene Drawing

Lines 2000–2010 scatter 250 dot characters and 52 \f UDG instances at random screen positions to create a starfield. The \f UDG (a diamond pattern) is placed in INK 4 (green) to differentiate foreground stars.

Lines 3000–3270 use PLOT and DRAW to render what appears to be a building or monument silhouette, complete with a doorway cutout (the conditional skip at lines 3100–3110) and a curved roof drawn with incrementing/decrementing loop variable a. The nested fill loops in 3090–3190 use floating-point increments (a+.7, a-.7) to approximate diagonal edges.

Scrolling Text Technique

Two string variables implement horizontal marquee scrolling:

  • a$ (65 characters): scrolls right-to-left at row 3 by rotating the last character to the front: LET a$=a$(64)+a$(TO 63).
  • b$ (65 characters): scrolls left-to-right at row 6 by rotating the first character to the end: LET b$=b$(2 TO LEN b$)+b$(1).

Each loop prints only the first 32 characters of the buffer (a$(TO 32)) to fill one screen row. PAUSE 20 and PAUSE 10 control scroll speed. The strings embed UDG characters (\b, \c, \e, \a, \d) to display sprite-based content within the scrolling banner.

Music Subroutines

The music is organized as a small call tree:

  • GO SUB 4000 — master fanfare: calls 4005, then 4050, then 4005, then falls through to 5100.
  • GO SUB 4005 — plays three beeps via GO SUB 5050, then a melodic phrase (lines 4010–4040).
  • GO SUB 4050 — plays a short five-note motif.
  • GO SUB 5050 — plays three identical beeps at pitch 10.
  • GO SUB 5100 — plays a descending four-note phrase with a long final note, then pauses.

Line 4000 uses GO TO 5100 rather than GO SUB 5100: RETURN, relying on 5110 RETURN to unwind back to the original caller — a stack-efficient tail-call pattern.

Notable Anomalies

  • Line 3075 contains REM go to 3200, indicating the PLOT/DRAW fill section (3090–3190) was intentionally bypassed during development but later re-enabled by removing or not executing a GO TO 3200. The REM is left as a comment artifact.
  • Line 3300 uses variable i as the loop start (FOR n=i TO 64), but i is last set during the PLOT/DRAW section (line 3230, loop variable). This couples the drawing phase to the scroll loop timing and means the first scroll pass may be shorter than subsequent ones.
  • Variables sk and s initialized at line 5 and the DIM c$(32) array are never used in the visible program — likely remnants of a removed gameplay or scoring feature.
  • Line 4999 (STOP) is unreachable dead code between the music subroutines.

Content

Appears On

Related Products

Related Articles

Here are two programs that give a moving graphics representation of the holiday spirit. The first version is for the...

Related Content

Image Gallery

Source Code

    5 LET sk=0: LET s=0: DIM c$(32)
   10 POKE USR "e",BIN 00000101
   20 POKE USR "e"+1,BIN 00000010
   30 POKE USR "e"+2,BIN 00000010
   40 POKE USR "e"+3,BIN 10000110
   50 POKE USR "e"+4,BIN 11111111
   60 POKE USR "e"+5,BIN 01111110
   70 POKE USR "e"+6,BIN 01010101
   80 POKE USR "e"+7,BIN 01010101
  100 POKE USR "a",BIN 10100000
  120 POKE USR "a"+1,BIN 01000000
  130 POKE USR "a"+2,BIN 01000000
  140 POKE USR "a"+3,BIN 01100001
  150 POKE USR "a"+4,BIN 11111111
  160 POKE USR "a"+5,BIN 01111110
  180 POKE USR "a"+7,BIN 10101010
  200 POKE USR "b",BIN 10100000
  210 POKE USR "b"+1,BIN 10110001
  220 POKE USR "b"+2,BIN 10110001
  230 POKE USR "b"+3,BIN 11111110
  240 POKE USR "b"+4,BIN 11111100
  250 POKE USR "b"+5,BIN 01000100
  270 POKE USR "b"+6,BIN 01000100
  280 POKE USR "b"+7,BIN 11111110
  300 POKE USR "c",BIN 00000000
  310 POKE USR "c"+1,BIN 00000000
  320 POKE USR "c"+2,BIN 00000000
  330 POKE USR "c"+3,BIN 11111111
  340 POKE USR "c"+4,BIN 00000000
  350 POKE USR "c"+5,BIN 00000000
  360 POKE USR "c"+6,BIN 00000000
  370 POKE USR "c"+7,BIN 00000000
  400 POKE USR "d",BIN 00000101
  410 POKE USR "d"+1,BIN 10001101
  420 POKE USR "d"+2,BIN 10001101
  430 POKE USR "d"+3,BIN 01111111
  440 POKE USR "d"+4,BIN 00111111
  450 POKE USR "d"+5,BIN 00100010
  460 POKE USR "d"+6,BIN 00100010
  470 POKE USR "d"+7,BIN 01111111
  500 POKE USR "f",BIN 00011000
  510 POKE USR "f"+1,BIN 00011000
  520 POKE USR "f"+2,BIN 00111100
  530 POKE USR "f"+3,BIN 00111100
  540 POKE USR "f"+4,BIN 01111110
  550 POKE USR "f"+5,BIN 01111110
  560 POKE USR "f"+6,BIN 00011000
  570 POKE USR "f"+7,BIN 00011000
 1000 LET a$="                                                  \b\c\e\e\c\e\e\c\e\e\c\e\e ": LET b$="                                                 \a\a\c\a\a\c\a\a\c\a\a\c\d "
 1100 PAPER 0: BORDER 7: INK 7: CLS 
 2000 FOR n=1 TO 250: PRINT AT INT (22*RND),INT (32*RND);".": NEXT n
 2010 INK 4: FOR n=1 TO 50: PRINT AT INT (RND*10)+8,INT (RND*21);"\f": NEXT n: PRINT AT 9,25;"\f";AT 13,27;"\f"
 3000 INK 7: PLOT 0,10: DRAW 255,10: PLOT 0,20: DRAW 255,10
 3010 PLOT 193,35: DRAW 30,0: DRAW 0,15: DRAW -15,10: DRAW -15,-10: DRAW 0,-15
 3020 DRAW -20,30: DRAW 0,15: DRAW 20,-30
 3030 PLOT 173,80: DRAW 15,10: DRAW 20,-30
 3040 PLOT 189,90: DRAW 15,-10: DRAW 20,-30
 3050 PLOT 184,88: DRAW 0,8: DRAW 8,0: DRAW 0,-8
 3060 PLOT 180,84: DRAW 0,18: DRAW 5,-6
 3070 PLOT 180,102: DRAW 8,0: DRAW 4,-6
 3075 REM go to 3200
 3090 FOR n=195 TO 221: FOR i=35 TO 49
 3100 IF n>210 AND n<216 AND i<44 AND i>37 THEN GO TO 3120
 3110 PLOT n,i
 3120 NEXT i: NEXT n
 3130 LET a=50: FOR n=196 TO 208: FOR i=50 TO a
 3150 PLOT n,i
 3160 NEXT i: LET a=a+.7: NEXT n
 3170 LET a=58: FOR n=208 TO 220: FOR i=a TO 49 STEP -1
 3180 PLOT n,i
 3190 NEXT i: LET a=a-.7: NEXT n
 3200 FOR j=1 TO 2: LET i=52: FOR n=194 TO 176 STEP -1
 3210 PLOT n,1: DRAW 12,10
 3220 LET i=i+1.5: NEXT n
 3230 LET i=59: FOR n=209 TO 189 STEP -1
 3240 PLOT n,i: DRAW 15,-8
 3250 LET i=i+1.5: NEXT n
 3260 NEXT j
 3270 PLOT 192,38: LET a=38: FOR n=192 TO 173 STEP -1: PLOT n,a: DRAW 0,10: LET a=a+1.5: NEXT n
 3300 FOR n=i TO 64
 3310 PRINT AT 3,0;a$( TO 32)
 3320 LET a$=a$(64)+a$( TO 63)
 3330 PAUSE 20: NEXT n
 3335 GO SUB 4000
 3340 FOR n=1 TO 64
 3350 PRINT AT 6,0;b$( TO 32)
 3360 IF LEN b$>1 THEN LET b$=b$(2 TO LEN b$)+b$(1)
 3370 PAUSE 10: NEXT n
 3380 GO SUB 4000
 3999 GO TO 3300
 4000 GO SUB 4005: GO SUB 4050: GO SUB 4005: GO TO 5100
 4005 GO SUB 5050: PAUSE 20: GO SUB 5050: PAUSE 20
 4010 BEEP .25,10: BEEP .25,13: BEEP .27,6: BEEP .25,8: BEEP .75,10: PAUSE 30
 4030 BEEP .25,11: BEEP .25,11: BEEP .25,11: BEEP .1,11: BEEP .1,11: BEEP .25,11: BEEP .25,10: BEEP .25,10
 4040 BEEP .1,10: BEEP .1,10: BEEP .25,10
 4045 RETURN 
 4050 BEEP .25,8: BEEP .25,8: BEEP .25,10: BEEP .5,8: BEEP .5,13
 4055 RETURN 
 4999 STOP 
 5050 FOR n=1 TO 3: BEEP .25,10: NEXT n: RETURN 
 5100 BEEP .25,13: BEEP .25,11: BEEP .25,8: BEEP 1,6
 5110 PAUSE 50: RETURN 

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

People

No people associated with this content.

Scroll to Top