"Xmas GIFT" - VC³ 2024 coding tips
- Overflow
- 2 days ago
- 4 min read
Updated: 11 minutes ago
A few months ago, I participated in the Vintage Computing Christmas Challenge 2024.

I also took part, last year, in 2023 edition - you can check out the details on Logon System's blog. Recently, I was urged to share some explanations about the tricks I used, so here they are.
By the way, the Amstrad team did exceptionally well this year, as noted on the official results page.

The best part? By combining my ideas with those of others, we managed to optimize our code even further, reducing it to just 38 bytes! You can download the final dsk or source code from the site.

Animated GIF to show algorithm & main idea

Main source/code map

(A) CALL <nnnn> from Basic initializes DE
CALL <nnnn> from Basic sets Z80 DE register to <nnnn>.
This saves some bytes for initializing DE to value #0901 at start.
(B) MAIN MEMORY full of 00/NOP
The call from Basic starts at #0901. It is assumed that the memory area from #0901 to #2100 is filled with NOPs. Thus, even if the call starts at #0901, the main code (beginning at #2100) will execute after running through many NOPs.
0901 00 NOP
... 00 NOP
2100 ; main code starts here
; assuming DE=#0901
(C) RST LO_SIDE_CALL : DEFW BASIC_PRINT_STRING
Credit for finding this gem goes to lightforce6128.
Read the thread at https://www.cpcwiki.eu/forum/programming/
This call within Basic ROM prints characters or control codes starting from HL until (HL) is 0.
This avoids to lose some bytes to loop on CALL #BB5A (prints character or control code from A register).
(D) MAIN MEMORY full of 00/NOP
The RST LO_SIDE_CALL : DEFW BASIC_PRINT_STRING ends when it encounters a 0 in the list. There's no need to explicitly set a final 0 within the list since the main memory defaults to 0.
2126 00
(E) COUNTER for line/y at #2121
This allows to set HL with ease since H=L=#21
2106 LD L,H
(F) COUNTER for line/y is NEGATIVE COUNTER
The counter runs from -#14 to -#01 and stops at #00. As we'll see later, this negative value will be useful later in this algorithm.
2107 INC (HL)
...
2121 EC ; = -#14
(G) RET to Basic is at half-loop
First half of the loop draws the knot "\o/".
Second half of the loop draws one line from the box,
either "+--------+--------+" or "! ! !".
At each loop (except the last one) the second half deletes the knot.
This algorithm shows some nice optimization.
This is also a stylish way of rising the gfx as a cathedral rising from the ground.
2108 RET Z
(H) HL set to "! "
Thanks to the charset, this saves 1 or 2 bytes. Since " " equals "!" -1, (or #20 equals #21 -1), DEC HL transforms "!!" into "! " as expected.
210F DEC HL
(I) DEC HL is part of ANOTHER OPCODE
The last byte from LD HL,"+-" is #2B, which is the binary code for DEC HL. This saves one byte thanks to a clever JR jr_y_std.
JR NZ,jr_y_std
...
210D 21 LD HL,"+-" ; counts for 3 bytes 21 2D 2B
210E 2D
jr_y_std 210F 2B DEC HL
(J) JP loop_y is part of DATA used elsewhere
This saves 1 or 2 bytes since the address for the jump is also used as data.
211E C3 JP #091F ; counts for 3 bytes C3 1F 09
data_ctrl 211F 1F ; 1st character / control code
2120 09 ; 2nd character / control code
...
(K) MAIN MEMORY full of 00/NOP
This allows at each loop_y to run plenty of NOPs without care.
loop_y 091F 00 NOP
... 00 NOP
2100 ; code for loop starts here
...
211E C3 JP loop_y ; JP #091F
211F 1F
2120 09
(L) LOCATE 9,y (with y<0) scrolls SCREEN DOWN
When using contol code to LOCATE <x,y> at a given character place, if y<0 then screen scrolls down 1 character - and located y/line is the upper one. This allows the algorithm to scroll the screen down and build the 'cathedral' gfx.
data_ctrl 211F 1F ; 1st character / control code
2120 09 ; 2nd character / control code
2121 EC ; 3rd character / control code
; = LOCATE #09,-#14
(M) COUNTER for line/y is also used as other DATA
Saving 1 byte - no need to have a fixed negative value there.
data_ctrl 211F 1F ; 1st character / control code
2120 09 ; 2nd character / control code
cpt_y 2121 <-y> ; 3rd character / control code
; = LOCATE #09, <from #EC to #FF>
Overflow / Logon System
Tuesday, April 15th 2025