( Dev/Time )

%+  { ADD } %-   { SUB }  %*  { MUL } %/   { DIV }  
%<  { LTH } %>   { GTH }  %=  { EQU } %!   { NEQ } 
%++ { ADD2 } %-- { SUB2 } %** { MUL2 } %// { DIV2 } 
%<< { LTH2 } %>> { GTH2 } %== { EQU2 } %!! { NEQ2 } 

%8* { #30 SFT }
%2// { #01 SFT2 }
%4// { #02 SFT2 }
%2** { #10 SFT2 }

%DIAMETER  { #0080 }
%RADIUS    { DIAMETER 2// }

%TOS     { #00 SWP }
%RTN     { JMP2r }
%MOD     { DUP2 DIV MUL SUB }
%ABS2    { DUP2 #0f SFT2 EQU #05 JCN #0000 SWP2 -- }
%SCALEX  { 2// .center/x LDZ2 ++ RADIUS -- }
%SCALEY  { 2// .center/y LDZ2 ++ RADIUS -- }
%12HOURS { DUP #0c GTH #0c MUL SUB }
%LTS2    { #8000 ++ SWP2 #8000 ++ GTH2 }
%GTS2    { #8000 ++ SWP2 #8000 ++ LTH2 }
%GET-CHAR-SPRITE { 8* TOS ;font-hex ++ }

( devices )

|00 @System     [ &vector $2 &pad      $6 &r      $2 &g     $2 &b      $2 ]
|10 @Console    [ &vector $2 &read     $1 &pad    $5 &write $1 &error  $1 ]
|20 @Screen     [ &vector $2 &width    $2 &height $2 &auto  $1 &pad    $1 &x      $2 &y      $2 &addr $2 &pixel $1 &sprite $1 ]
|b0 @DateTime   [ &year   $2 &month    $1 &day    $1 &hour  $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 ]

( variables )

|0000

@color   $1
@current $1
@center
	&x $2 &y $2
@needles
	&hx $2 &hy $2 &mx $2 &my $2 &sx $2 &sy $2
@line
	&x0 $2 &y0 $2 &x $2 &y $2 &sx $2 &sy $2 &dx $2 &dy $2 &e1 $2 &e2 $2

( program )

|0100 ( -> )
	
	( theme ) 
	#0ff8 .System/r DEO2 
	#0f08 .System/g DEO2 
	#0f08 .System/b DEO2

	#00f0 .Screen/width DEO2
	#0120 .Screen/height DEO2

	( vectors ) 
	;on-frame .Screen/vector DEO2

	( center )
	.Screen/width DEI2 2// .center/x STZ2
	.Screen/height DEI2 2// .center/y STZ2

BRK

@on-frame ( -> )

	( only draw once per second )
	.DateTime/second DEI .current LDZ = ,&skip JCN
		;draw-clock JSR2
		;draw-display JSR2
		&skip

	.DateTime/second DEI .current STZ

BRK

@draw-clock ( -- )

	( clear ) #00 ;draw-needles JSR2

	#00 .DateTime/second DEI 2** ;table ++ LDA2
		TOS SCALEY .needles/sy STZ2
		TOS SCALEX .needles/sx STZ2
	#00 .DateTime/minute DEI 2** ;table ++ LDA2
		TOS 4// DUP2k ++ ++ #0020 ++ SCALEY .needles/my STZ2
		TOS 4// DUP2k ++ ++ #0020 ++ SCALEX .needles/mx STZ2
	#00 .DateTime/hour DEI 12HOURS #20 SFTk NIP ADD 2** ;table ++ LDA2
		TOS 2// RADIUS ++ SCALEY .needles/hy STZ2
		TOS 2// RADIUS ++ SCALEX .needles/hx STZ2

	( draw ) #01 ;draw-needles JSR2

	( circle )
	#3c #00 
	&loop
		( load ) DUP TOS 2** ;table ++ LDA2
		TOS SCALEY .Screen/y DEO2
		TOS SCALEX .Screen/x DEO2
		DUP #0f MOD #00 EQU INC .Screen/pixel DEO
		INC GTHk ,&loop JCN
	POP2

RTN

@draw-needles ( mul -- )

	STH
	.center/x LDZ2 .center/y LDZ2 .needles/sx LDZ2 .needles/sy LDZ2 #02 STHkr * ;draw-line JSR2
	.center/x LDZ2 .center/y LDZ2 .needles/mx LDZ2 .needles/my LDZ2 #01 STHkr * ;draw-line JSR2
	.center/x LDZ2 .center/y LDZ2 .needles/hx LDZ2 .needles/hy LDZ2 #01 STHr * ;draw-line JSR2

RTN

@draw-display ( -- )

	( auto x ) #01 .Screen/auto DEO

	( date )
	.center/y LDZ2 #0058 -- .Screen/y DEO2
	.center/x LDZ2 #0014 -- .Screen/x DEO2
		.DateTime/month DEI INC
		DUP #0a DIV GET-CHAR-SPRITE .Screen/addr DEO2
			#03 .Screen/sprite DEO
			#0a MOD GET-CHAR-SPRITE .Screen/addr DEO2
			#03 .Screen/sprite DEO
	.Screen/x DEI2 #0008 ++ .Screen/x DEO2
		.DateTime/day DEI
		DUP #0a DIV GET-CHAR-SPRITE .Screen/addr DEO2
			#03 .Screen/sprite DEO
			#0a MOD GET-CHAR-SPRITE .Screen/addr DEO2
			#03 .Screen/sprite DEO

	( time )
	.center/y LDZ2 #0050 ++ .Screen/y DEO2
	.center/x LDZ2 #0020 -- .Screen/x DEO2
		.DateTime/hour DEI
		DUP #0a DIV GET-CHAR-SPRITE .Screen/addr DEO2
			#01 .Screen/sprite DEO
			#0a MOD GET-CHAR-SPRITE .Screen/addr DEO2
			#01 .Screen/sprite DEO
	;spacer-icn .Screen/addr DEO2
	.DateTime/second DEI #01 AND .Screen/sprite DEO
		.DateTime/minute DEI
		DUP #0a DIV GET-CHAR-SPRITE .Screen/addr DEO2
			#01 .Screen/sprite DEO
			#0a MOD GET-CHAR-SPRITE .Screen/addr DEO2
			#01 .Screen/sprite DEO
	;spacer-icn .Screen/addr DEO2
	.DateTime/second DEI #01 AND .Screen/sprite DEO
		.DateTime/second DEI 
		DUP #0a DIV GET-CHAR-SPRITE .Screen/addr DEO2
			#01 .Screen/sprite DEO
			#0a MOD GET-CHAR-SPRITE .Screen/addr DEO2
			#01 .Screen/sprite DEO

	( auto none ) #00 .Screen/auto DEO

RTN

@draw-line ( x1 y1 x2 y2 color -- )
	
	( load ) .color STZ .line/y0 STZ2 .line/x0 STZ2 .line/y STZ2 .line/x STZ2
	.line/x0 LDZ2 .line/x LDZ2 -- ABS2 .line/dx STZ2
	.line/y0 LDZ2 .line/y LDZ2 -- ABS2 #0000 SWP2 -- .line/dy STZ2
	#ffff #00 .line/x LDZ2 .line/x0 LDZ2 LTS2 2** ++ .line/sx STZ2
	#ffff #00 .line/y LDZ2 .line/y0 LDZ2 LTS2 2** ++ .line/sy STZ2
	.line/dx LDZ2 .line/dy LDZ2 ++ .line/e1 STZ2
	&loop
		.line/x LDZ2 .Screen/x DEO2 
		.line/y LDZ2 .Screen/y DEO2 
		.color LDZ .Screen/pixel DEO
		[ .line/x LDZ2 .line/x0 LDZ2 == ] 
		[ .line/y LDZ2 .line/y0 LDZ2 == ] AND ,&end JCN
		.line/e1 LDZ2 2** .line/e2 STZ2
		.line/e2 LDZ2 .line/dy LDZ2 LTS2 ,&skipy JCN
			.line/e1 LDZ2 .line/dy LDZ2 ++ .line/e1 STZ2
			.line/x LDZ2 .line/sx LDZ2 ++ .line/x STZ2
		&skipy
		.line/e2 LDZ2 .line/dx LDZ2 GTS2 ,&skipx JCN
			.line/e1 LDZ2 .line/dx LDZ2 ++ .line/e1 STZ2
			.line/y LDZ2 .line/sy LDZ2 ++ .line/y STZ2
		&skipx
		;&loop JMP2
	&end

RTN

@table ( 60 positions on a circle )
	8000 8d00 9a02 a706 b40b c011 cb18 d520
	df2a e734 ee40 f44b f958 fd65 ff72 ff80
	ff8d fd9a f9a7 f4b4 eec0 e7cb dfd5 d5df
	cbe7 c0ee b4f4 a7f9 9afd 8dff 80ff 72ff
	65fd 58f9 4bf4 40ee 34e7 2adf 20d5 18cb
	11c0 0bb4 06a7 029a 008d 0080 0072 0265
	0658 0b4b 113f 1834 202a 2a20 3418 3f11
	4b0b 5806 6502 7200

@spacer-icn
	0000 0010 0010 0000

@font-hex ( 0-F )
	007c 8282 8282 827c 0030 1010 1010 1010
	007c 8202 7c80 80fe 007c 8202 1c02 827c
	000c 1424 4484 fe04 00fe 8080 7c02 827c
	007c 8280 fc82 827c 007c 8202 1e02 0202
	007c 8282 7c82 827c 007c 8282 7e02 827c
	007c 8202 7e82 827e 00fc 8282 fc82 82fc
	007c 8280 8080 827c 00fc 8282 8282 82fc
	007c 8280 f080 827c 007c 8280 f080 8080