%s 3
{
Logiker Christmas Challenge 2025 to draw a snowflake.

Method:
The snowflake is symmetrical horizontally & vertically.
If the central vertical & horizontal lines are drawn explicitly,
each line can be defined using a 16-bit data value.

Option 1:
Define each line of snowflake as a 16-bit data value.
Code needs 1 scan to traverse data forwards.
Data needed for whole pattern.
Code size: 64 words (128 bytes)

Option 2 (used here):
Split pattern horizontally into 2 halves, and just
define the top half using a set of 16-bit values.
Code needs 2 scans to traverse data forwards and backwards.
Data needed for 1/2 of the pattern.
Code size: 60 words (120 bytes)

Option 3:
Split pattern into 4 quadrants and just define the
top-left section using a set of 8-bit data values.
Code needs 4 scans to traverse data in forwards
and backwards combinations.
Data needed for 1/4 of the pattern.
Not yet tried; PleX is word-based (16-bits) so this option
will probably be larger than the others.

Register usage:
r0 - @pattern
r1 - char count
r2 - line count
r3 - char to draw
r4 - boolean to scan forwards or reverse
r5 - star char (TEST only)
}

#USE_PRINTER 0	;0 for oper, 1 for printer
#TEST 0	;uses different char on each line to check wrap-round

#STAR '*
#SPACE OP_CH_SPACE
#MAX_WIDTH 19
#MAX_CHARS MAX_WIDTH - 3	;allow for central lines being longer
#MID_POINT MAX_WIDTH / 2
#MAX_LINES 9	;top half excluding central horiz line

%m $10
	movs r4 0
	mov r0 pattern	;@top half of snowflake
	?TEST mov r5 'A
:out_patt
	movs r2 MAX_LINES
.nxt_line
	callrs out.space	;start of each line
	mov r1 MAX_CHARS
.nxt_ch
	rotls @r0 1	;C is set if ms-bit is 1
	callrs out	;draw star or space

	;draw extra star at mid-point of line
	;this forms central vertical line
	cmps r1 MID_POINT
	callrs.z out.star
	dec r1
	jmprs.nz nxt_ch

	callrs out.space	;draw blank at end of each line
	callrs nl

	;check scan direction to inc/dec pattern line pointer
	cmps r4 0
	jmprs.z scan_fwd
.scan_rev
	subs r0 2	;avoid jump over inc
.scan_fwd
	inc r0
.end_line
	?TEST inc r5
	dec r2
	jmprs.nz nxt_line

	cmps r4 0
	jmprs.z top_done
	;bottom done, all finished
	hlt

.top_done
	;draw horizontal line at halfway point
	mov r1 MAX_WIDTH
.nxt_ch_central
	callrs out.star
	dec r1
	jmprs.nz nxt_ch_central
	callrs nl

	;draw bottom half by scanning pattern in reverse order
	dec r0	;@end of top half of snowflake
	inc r4	;set boolean to scan in reverse
	jmprs out_patt

:nl
.wait
	?USE_PRINTER sys LP_STAT
	?!USE_PRINTER sys OP_STAT
	jmprs.z wait
	?USE_PRINTER sys LP_WR_LIT | LP_CH_CR
	?!USE_PRINTER sys OP_WR_NL
	ret

:out
	jmprs.c star
.space
	mov r3 SPACE
	jmprs wait
.star
	?TEST mov r3 r5
	?!TEST mov r3 STAR
.wait
	?USE_PRINTER sys LP_STAT
	?!USE_PRINTER sys OP_STAT
	jmprs.z wait
	?USE_PRINTER sys LP_WR_R | $3
	?!USE_PRINTER sys OP_WR_CH_R | $3
	ret

::

%d
;top half of snowflake
.pattern
	$0000
	$0240
	$518A
	$300C
	$724E
	$0990
	$0420
	$9249
	$4992

%is "PleX-Functions.pls"
