--- title: "Merry Christmas / Happy New Year" id: 57142 type: "computer_media" slug: "merry-christmas-happy-new-year" url: "http://localhost/computer_media/merry-christmas-happy-new-year/" markdown_url: "http://localhost/computer_media/merry-christmas-happy-new-year.md" published_at: "2024-10-04T00:45:55+00:00" modified_at: "2026-03-30T21:19:33+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/91_XMAS.png" excerpt: "A festive greeting program scrolls Christmas and New Year messages up and down the screen, driven by a machine code routine hidden inside a REM statement." 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: 56733 title: "Timex Sinclair Public Domain Library Tape 1002" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1002/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/91_XMAS.png" media_type_tags: "Holiday" --- # Merry Christmas / Happy New Year This program displays a scrolling Christmas and New Year greeting by printing messages at successive screen rows and calling a machine code routine embedded in the REM statement at line 1. The machine code (stored from address 16514) is invoked repeatedly via RAND USR 16514, which suppresses the resulting error return value. The routine itself appears to implement a colour-cycling or display effect — the inner loop of 32 calls to the machine code at line 50/110 produces a timed animation between each row advance. The program alternates between scrolling “**MERRY CHRISTMAS**” downward (rows 0–21) and “**HAPPY NEW YEAR**” upward (rows 21–0) in a continuous loop. *** ## Program Analysis ### Program Structure The program has three distinct phases running in an infinite loop via `GOTO 10` at line 140: 1. **Downward scroll (lines 10–70):** Iterates `A` from 0 to 21, printing “**MERRY CHRISTMAS**” at row `A`, column 6, and calling the machine code routine 32 times per row for timing/effect. 2. **Upward scroll (lines 80–130):** Iterates `A` from 21 down to 0, printing “**HAPPY NEW YEAR**” at the same column, again calling the machine code 32 times per row. 3. **Loop restart (line 140):**`GOTO 10` repeats indefinitely. Line 160 is dead code — it is never reached due to line 140. ### Machine Code Routine in REM The REM statement at line 1 contains a machine code routine beginning at address 16514 (the second byte of the REM data, since 16514 = start of program + 4-byte line header + 1 for the REM token). The bytes are: | Offset | Hex | Z80 Instruction | Notes | | --- | --- | --- | --- | | 0 | `3E 12` | LD A, 18 | Load attribute or border value | | 2 | `CD 1D 15` | CALL 0x151D | ROM routine (likely set colour attribute) | | 5 | `3E 21` | LD A, 33 | Load next value | | 7 | `CD 1D 15` | CALL 0x151D | ROM routine called again | | 10 | `EF 04 34` | RST 08 / data bytes | RST 8 is ZX81 error/CALL ROM handler; 04 34 are parameters | | 13 | `CD A7 0E` | CALL 0x0EA7 | ROM routine (likely SLOW/FAST display sync) | | 16 | `2A 0C 40` | LD HL, (0x400C) | Load address from system variable area | | 19 | `09` | ADD HL, BC | Offset into display file | | 20 | `23` | INC HL | | | 21 | `54` | LD D, H | | | 22 | `5D` | LD E, L | | | 23 | `7E` | LD A, (HL) | Read display byte | | 24 | `23` | INC HL | | | 25 | `01 1F 00` | LD BC, 31 | Block of 31 bytes | | 28 | `ED B0` | LDIR | Block copy (shift display left by one character) | | 30 | `2B` | DEC HL | | | 31 | `77` | LD (HL), A | Write original byte to end | | 32 | `C9` | RET | Return to BASIC | The routine performs a one-character left-rotate of a line in the display file — shifting 31 bytes left with `LDIR` and placing the first byte at the end, producing a hardware-level horizontal scroll effect on one row of the ZX81 display. ### Role of POKE 16515 Address 16515 is the second data byte of the REM, used by the machine code as a parameter. By poking `A` into this location before calling the routine, the BASIC program tells the machine code which display row to scroll, synchronising the visual effect with the printed message position. ### Key BASIC Idioms - `RAND USR 16514` — calls the machine code without needing a subroutine or risking a STOP; the random number side-effect is discarded. - The inner `FOR B=1 TO 32` loop runs the scroll routine 32 times per row, providing both the scrolling animation and a timing delay. - Two-space padding in the message strings (“MERRY CHRISTMAS”, “HAPPY NEW YEAR”) is used for visual centering rather than AT column arithmetic. ### Bugs and Anomalies - Line 160 (`GOTO 10`) is unreachable dead code; line 140 already loops the program back to line 10. - Line 150 is a `SAVE` command embedded in the running program flow between lines 140 and 160 — it is also unreachable at runtime and appears to be a development artifact left in the listing. ## Source Code ``` 1 REM \3E\12\CD\1D\15\3E\21\CD\1D\15\EF\04\34\CD\A7\0E\2A\0C\40\09\23\54\5D\7E\23\01\1F\00\ED\B0\2B\77\C9 10 FOR A=0 TO 21 20 POKE 16515,A 30 PRINT AT A,6;"**MERRY CHRISTMAS**" 40 FOR B=1 TO 32 50 RAND USR 16514 60 NEXT B 70 NEXT A 80 FOR A=21 TO 0 STEP -1 85 POKE 16515,A 90 PRINT AT A,6;"**HAPPY NEW YEAR**" 100 FOR B=1 TO 32 110 RAND USR 16514 120 NEXT B 130 NEXT A 140 GOTO 10 150 SAVE "1009%1" 160 GOTO 10 ```