--- title: "Seasons Greetings" id: 57581 type: "computer_media" slug: "seasons-greetings" url: "http://localhost/computer_media/seasons-greetings/" markdown_url: "http://localhost/computer_media/seasons-greetings.md" published_at: "2024-10-05T22:33:03+00:00" modified_at: "2026-04-03T07:58:20+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/seasons-greetings.png" excerpt: "A festive greeting card that endlessly scrolls block-graphic decorations while flashing \"Merry Christmas\" and \"Happy New Year\" in inverse video." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Holiday" slug: "holiday" taxonomy: "genre" url: "http://localhost/type/holiday/" media_contents: - id: 56722 title: "Synchro-Sette December 1982" type: "computer_media" url: "http://localhost/computer_media/synchro-sette-december-1983/" media_type: "Program" mediadate: "December 1982" images: - url: "http://localhost/wp-content/uploads/2024/10/seasons-greetings.png" media_type_tags: "Holiday" --- # Seasons Greetings This program displays an animated Christmas and New Year greeting card with scrolling graphical decorations. It uses machine code via RAND USR 16514 and a POKE to address 16418 to initialise the display environment before the main loop. Three string variables (B$, C$, D$) each hold a 64-character pattern built from block graphics representing candles or decorative motifs, and are horizontally scrolled each frame by rotating the string one character left using the slice idiom s$(2 TO LEN s$)+s$(1). The PRINT statement alternates between inverse-video and normal-video versions of “MERRY CHRISTMAS” and “HAPPY NEW YEAR” text, creating a flashing effect on each loop iteration. *** ## Program Analysis ### Program Structure The program divides into four functional phases: 1. **Initialisation (lines 2–6):** Sets FAST mode, calls machine code at 16514, POKEs address 16418 to zero, prints a bottom border row, then restores SLOW mode. 2. **String setup (lines 10–40):** Builds the shared prefix `A$` and constructs three display strings `B$`, `C$`, `D$` each longer than 32 characters to support rotation. 3. **Display loop (line 100):** A single compound `PRINT AT` statement renders three rows of graphics and two text labels in both normal and inverse video. 4. **Scroll update (lines 200–300):** Each string is rotated left by one character and control returns to line 100. ### Machine Code Usage `RAND USR 16514` at line 3 calls a machine-code routine at address 16514 in RAM. On a standard 16K or 64K TS1000/ZX81 this area sits within the system variables or early RAM; the exact function depends on what has been loaded or pre-POKEd into that location, but this pattern is a common technique to execute an initialisation stub before the BASIC program runs. The subsequent `POKE 16418,0` writes to the system variable `RAMTOP` low byte or a related display variable to adjust memory layout or clear a flag. ### String Construction and the Rotation Idiom All three animated strings are constructed by concatenating `A$` (32 spaces in inverse video acting as a left-pad buffer) with a pattern of block graphics. This makes each string 64+ characters long. The rotation at lines 200–220 uses the classic ZX81 cyclic-shift idiom:`X$ = X$(2 TO LEN X$) + X$(1)` This drops the first character and appends it to the end, producing a one-character leftward scroll per frame. Printing only the first 32 characters with the slice `B$( TO 32)` then shows a moving window across the pattern, creating smooth horizontal animation without any array or loop overhead. ### Block Graphics Usage The three display rows use ZX81 block graphic characters to suggest a repeating decorative motif (likely stylised candles or Christmas trees): | String | Row | Graphics used | Visual role | | --- | --- | --- | --- | | `B$` | Top | ▝▝▐, O, / | Flame / top of candle | | `C$` | Middle | ▖, dashes, % | Candle body | | `D$` | Bottom | ▌▌▌, ▐▐▐, \;;\;; sequences | Candle base / holder | The `\;;` sequences in `D$` represent character code 59 (semicolon) used as a block-fill element for the base row. ### Flashing Text Technique Line 100 prints the two greeting strings twice within the same `PRINT` statement: first in inverse video (`%H%A%P%P%Y%…` and `%M%E%R%R%Y%…`) and then in normal video. Because SLOW mode re-enters the display interrupt on each frame, the two renderings appear in rapid alternation across loop iterations, producing a flashing effect without any explicit `IF` branch or flag variable. ### Key BASIC Idioms - Compound `PRINT AT … ; AT … ; AT …` in a single statement to minimise interpreter overhead per frame. - String slicing with `( TO 32)` to extract a fixed-width window from a longer rotating buffer. - `LET B$=A$+"…"` pattern to share the common 32-character prefix across all three row strings, saving re-typing and memory. - `GOTO 100` infinite loop with no termination condition — typical for demo/greeting programs. ## Source Code ``` 1 REM Y% .'. :%KNOT $TAB @@RND: TAB '.RNDTAN 2 FAST 3 RAND USR 16514 4 POKE 16418,0 5 PRINT AT 22,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % " 6 SLOW 10 LET A$="% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % " 20 LET B$=A$+" ' ' :% % ' ' :% % ' ' :% % ' ' :% % % %/% %O % " 30 LET C$=A$+"% .%-%- .%-%- .%-%- .%-%- % " 40 LET D$=A$+"% : : : % % : : :% % : : :% % : : :% % ;;;;;;;;% " 100 PRINT AT 10,0;B$( TO 32);AT 11,0;C$( TO 32);AT 12,0;D$( TO 32);AT 4,8;"MERRY CHRISTMAS";AT 18,8;"%H%A%P%P%Y% %N%E%W% %Y%E%A%R";AT 4,8;"%M%E%R%R%Y% %C%H%R%I%S%T%M%A%S";AT 18,8;"HAPPY NEW YEAR" 200 LET B$=B$(2 TO LEN B$)+B$(1) 210 LET C$=C$(2 TO LEN C$)+C$(1) 220 LET D$=D$(2 TO LEN D$)+D$(1) 300 GOTO 100 9998 SAVE "SEASONS GREETING%S" 9999 RUN ```