
; Sin23
; (c) 2022 by Jerzy Kut aka Mono / Tristesse


	opt o+ h+ ?+ c-


LMS = $40
JVB = $41

progr = $2000
table = $2700

RTCLOK = $12

DMACTS = $22F
DLPTRS = $230
GTIACTS = $26F
COLPM0S = $2C0
COLPM1S = $2C1
COLPM2S = $2C2
COLPM3S = $2C3
COLPF0S = $2C4
COLPF1S = $2C5
COLPF2S = $2C6
COLPF3S = $2C7
COLBAKS = $2C8
KBCODS = $2FC

HPOSP0 = $D000
HPOSP1 = $D001
HPOSP2 = $D002
HPOSP3 = $D003
HPOSM0 = $D004
HPOSM1 = $D005
HPOSM2 = $D006
HPOSM3 = $D007
SIZEP0 = $D008
SIZEP1 = $D009
SIZEP2 = $D00A
SIZEP3 = $D00B
SIZEM = $D00C
GRAFP0 = $D00D
GRAFP1 = $D00E
GRAFP2 = $D00F
GRAFP3 = $D010
GRAFM = $D011
COLBAK = $D01A
PMCNTL = $D01D
WSYNC = $D40A
VCOUNT = $D40B


	org $80

pause	.ds 1

off:		;starting position in sine
?spr		;for all sprities
?p0	.ds 1
?p1	.ds 1
?p2	.ds 1
?p3	.ds 1
?m	.ds 1
?bgr		;and bars
?b01	.ds 1
?b10	.ds 1
?b11	.ds 1

prev:		;position of the previous bar in screen line
?spr		;(sprities don't use it)
?p0	.ds 1
?p1	.ds 1
?p2	.ds 1
?p3	.ds 1
?m	.ds 1
?bgr		;(graphic bars use it)
?b01	.ds 1
?b10	.ds 1
?b11	.ds 1

next:		;position of the current sprite/bar in screen line
?spr
?p0	.ds 1
?p1	.ds 1
?p2	.ds 1
?p3	.ds 1
?m	.ds 1
?bgr
?b01	.ds 1
?b10	.ds 1
?b11	.ds 1

buf	.ds 4	;buffer for draw routine


	org progr

; screen line

line:
:$20/4	.byte %00000000
?body
:$C0/4	.byte %00000000
:$20/4	.byte %00000000


; display list showing the same line on the screen

dlist:
.rept 238
	.byte $0E | LMS
	.word line.?body
.endr
	.byte JVB
	.word dlist


; entry point

start	lda #0				;no pause mode
	sta pause

.rept 5
	ldx #4*[0+#]			;initial positions of hardware sprites
	stx off.?spr+#			;don't draw sprities
	lda sinus2,x
	sta next.?spr+#
.endr
.rept 3
	ldx #4*[5+#]			;initial positions of background bars
	stx off.?bgr+#
	ldy sinus2,x
	sty prev.?bgr+#
	sty next.?bgr+#

	ldx sinus1,y			;draw bars
	ldy offset,x

	lda pixel.?left+$100*#,x
	eor line,y
	sta line,y
	lda #[%01010101 * [%01+#]]
	eor line+1,y
	sta line+1,y
	lda pixel.?right+$100*#,x
	eor line+2,y
	sta line+2,y
.endr

	lda #%00110000			;enable multicolor sprities
	sta GTIACTS			;and 5th player

	lda #%00100011			;configure wide ANTIC screen
	ldx #<dlist			;displaying one line on the whole screen
	ldy #>dlist
	sta DMACTS
	stx DLPTRS
	sty DLPTRS+1

	ldx #$8C			;overlapping colors
	ldy #$46			;PF0 + PF1 + PM0 + PM1
	stx COLPM0S
	sty COLPM1S
	ldx #$18
	ldy #$24
	stx COLPF0S
	sty COLPF1S

	ldx #$22			;and PF2 + PF3 + PM2 + PM3
	ldy #$1A
	stx COLPM2S
	sty COLPM3S
	ldx #$42
	ldy #$84
	stx COLPF2S
	sty COLPF3S

	lda #$00			;black border
	sta COLBAKS

	sta HPOSM1			;move not used missiles out of screen
	sta HPOSM2
	sta HPOSM3
	ldx #%11000000			;sprite size and shape
	ldy #%00000011			;for all players and missile 0
	sty SIZEP0
	sty SIZEP1
	sty SIZEP2
	sty SIZEP3
	sty SIZEM
	stx GRAFP0
	stx GRAFP1
	stx GRAFP2
	stx GRAFP3
	sty GRAFM
	sta PMCNTL			;display content of GRAF registers

; display one TV frame

?wait	lda VCOUNT			;wait for line 0
	bmi ?wait

?line
	lda VCOUNT			;show dense rainbow in the background
	asl
	sta COLBAK
.rept 5
	ldy next.?spr+#			;set hardware sprities positions
	lda sinus1,y
	sta HPOSP0+#
	inc next.?spr+#
.endr
.rept 3
	lda VCOUNT			;show dense rainbow in the background
	asl
	sta COLBAK

	ldy prev.?bgr+#			;prepare to clear previous graphics bar
	ldx sinus1,y			;from the screen line
	ldy offset,x			;calculate byte offset in screen line
	sty buf+3

	lda pixel.?left+$100*#,x	;takes left side of graphics bar
	sta buf+0
	lda pixel.?right+$100*#,x	;and the right one
	sta buf+1

	ldy next.?bgr+#			;prepare to draw new graphics bar
	sty prev.?bgr+#			;on the screen line
	inc next.?bgr+#
	ldx sinus1,y
	ldy offset,x

	lda pixel.?left+$100*#,x	;left side...
	sta buf+2

	lda VCOUNT			;rainbow in the bacground
	asl
	sta COLBAK

	lda pixel.?right+$100*#,x	;and the right side of the bar
	eor line+2,y

	ldx buf+3			;now old bar is cleared
	sta WSYNC			;and new bar is drawn
	sta line+2,y			;right part
	lda buf+1
	eor line+2,x
	sta line+2,x
	lda #[%01010101 * [%01+#]]	;middle
	eor line+1,y
	sta line+1,y
	lda #[%01010101 * [%01+#]]
	eor line+1,x
	sta line+1,x
	lda buf+2
	eor line+0,y			;and left
	sta line+0,y
	lda buf+0
	eor line+0,x
	sta line+0,x
.endr
	lda VCOUNT			;continue drawing of the screen content line by line?
	cmp #[247/2]
	jcc ?line

	lda RTCLOK+2			;no sines move
	and #%00000011			;when pause mode is on
	ora pause
	cmp #1
	ldx #8-1
?loop	scs
	inc off,x			;bars are moving every 4 TV frames

	ldy off,x			;initial position of the bar on the new screen
	lda sinus2,y
	sta next,x
	dex
	bpl ?loop

	lda #$FF			;pause mode is switched when any key is pressed
	cmp KBCODS
	beq ?skip
	sta KBCODS
	eor pause
	sta pause

?skip	jmp ?wait


	org table

sinus1	.byte sin($7C,$4C,$100)
sinus2	.byte sin($80,$7F,$100)

; bar offset in screen line counted in bytes
offset:
:$100	.byte #/4

; shape of the bar for all pixel colors %01, %10 and %11
pixel:
?left
:$100	.byte >[[%0101010100000000 * %01] >> [2 * [# & %11]]]	;left part of the byte
:$100	.byte >[[%0101010100000000 * %10] >> [2 * [# & %11]]]
:$100	.byte >[[%0101010100000000 * %11] >> [2 * [# & %11]]]
?right
:$100	.byte <[[%0101010100000000 * %01] >> [2 * [# & %11]]]	;right part of the byte
:$100	.byte <[[%0101010100000000 * %10] >> [2 * [# & %11]]]
:$100	.byte <[[%0101010100000000 * %11] >> [2 * [# & %11]]]


	run start


	end

