Author: Claire Wilson
System: Amstrad CPC464
Language: Z80 assembly
Source Length: 31 lines (851 bytes)
Executable length: 48 bytes (37 executable, 11 data)
Description:
There's an 11 byte array (xpos) denoting the number of stars per row
Centre of an Amstrad CPC464 in mode 1 is column 20 so we get an x location
of 20-x/2 (or, as executed lines 9~12 20, value at current ix which is a pointer
into xpos shifted right 1; 20 is subtracted from this). For authenticity, I use
the Firmware call to emulate the standard text mode to locate the text cursor
then run the loop to print the number of stars indicated again calling the firmware's
print character routine. Increment row count, increment xpos pointer in ix, if we're
not on the 15th row (beyond buffer), rinse and repeat.
PrintChar equ &BB5A ; Firmware call to print character in a to location
Locate equ &BB75 ; Firmware call, directly equiv to LOCATE xy in hl
Asterix equ 42
org &1200
ld c, 1 ; Set counter to start
ld ix, xpos ; Begin by pointing to first entry
MainLoop:
; work out x position as 20 - (#stars / 2)
ld a, 20
ld e, (ix)
sra e ; divide by 2
sub e
; The firmware LOCATE call expects x in h and y in l with
; origin of 1,1 top-right
ld h, a
ld l, c
call Locate
ld b, (ix) ; Grab the number of stars and use this for loop
ld a, Asterix ; PrintChar firmware expects chr in a
InnerRepeat:
call PrintChar
djnz, InnerRepeat ; And loop the print
; Move on to the next row. If we're on row 15, return otherwise NEXT
inc c
ld a, 15
cp c
ret z
inc ix
jr MainLoop ; NEXT
xpos: db 1,3,5,7,3,7,11,15,5,11,17,23,3,3
NOTICE TEXTE n° 2 (3.02 Ko)
; ****************************
; * Vintage Computing *
; * Christmas Challenge 2021 *
; ****************************
;Leosoft's entry
;duration = 5156 NOPs
di ;because we use shadow regs
;Initialize values of shadow registers
;=====================================
;(for the drawing routine)
exx
push bc ;backup bc' first!
;setup the four pixel maps for the star character
ld bc,&6030
ld de,&c0f0
;setup starting screen adress
ld hl,&caa7 ;(starts in scanline #1, exact center screen
;with this adress, we can use inc L instead of inc HL
exx
;Values in the main loop
;=======================
;B = counter for 4 lines per section
;C = length (in stars) of current line
;D = counter for tree sections (init 3)
;E = growth per line in current section (in stars, init 2)
;H = screen width (constant 80 = &50)
;L = offset to add to HL' for next screen line start (init 1)
ld de,&0302
ld hl,&5001
;Main loop (tree section)
;========================
tree_section:
ld c,e ;calculate length of first line
dec c ;every row starts with (growth-1) stars
ld b,4 ;set counter to four lines per section
section_line:
ld a,l ;restore offset
sub c ;subtract new line length from offset
;(-> half line left from center)
exx
add l ;add new offset to HL'
ld l,a
jr nc,$+3
inc h
exx
ld a,c ;get line length, A is counter for following loop
exx
draw_star:
ld (hl),b ;draw line #1
inc l
ld (hl),b
set 5,h ;go to line #5
ld (hl),b ;draw line #5
dec l
ld (hl),b
res 3,h ;go to line #4
ld (hl),c ;draw line #4
inc l
ld (hl),d ;draw line #4
res 5,h ;go to line #2
set 4,h
ld (hl),d ;draw line #2
dec l
ld (hl),c
set 3,h ;go to line #3
ld (hl),e ;draw line #3
inc l
ld (hl),e
res 4,h ;go back to line #1
inc l ;and to next position
dec a
jr nz,draw_star
exx
;calc offset to center of next line
ld a,h ;(H=80)
sub c ;since one character is 2 bytes wide
;C is actually half a line
ld l,a ;save offset
;calculate length next of line
ld a,c ;load old length
add e ;add growth
ld c,a ;save new length
djnz section_line
inc e ;increment growth for next section
inc e
dec d ;decrement section counter
jr nz,tree_section
bit 1,e ;if we get here for the 1st time, E=8
;then we go on to the trunk
jr nz,finish ;after the trunk, E=2 and we finish
;else draw the trunk of the tree
ld bc,&0203 ;trunk is 2 lines high and 3 stars wide
ld e,d ;E=0, no line growth (D was 0 before)
inc d ;trunk is 1 section
jr section_line
finish:
exx
pop bc ;restore BC' to keep basic happy
exx
ret