; compile with MADS
	icl "includes.m65"

ROWCRS	equ $54		;Row of cursor, 1 byte
;COLCRS	equ $55		;Column of cursor, 2 bytes
OLDROW	equ $5a
OLDCOL	equ $5b
color	equ $2fb	;Color for graphics operations
;drawpoint	equ $f1ca				;f1d8 (if oldrow/col not needed)
drawpoint 		equ $f1d8
drawline		equ $f9af
drawline_raw	equ $f9c2
openmode		equ $ef9c
putchar			equ $f1a4

	org $2000

start
;############### init stuff
	mva #0 AUDCTL		; init POKEY
	mva #3 SKCTL
	
	lda #8				; open gr.8 via illegal OS B opcode
	jsr openmode

	ldy #<vbi			; setup VBI
	ldx #>vbi
	lda #$07
	jsr SETVBV
	
	
	
;####################### main loop
fx						; do some funky fx stuff here
	ldx vbipos+1		; "jump table"
	cpx #4				;************ could be optimized by using another initial vbipos value and leveraging bmi,bpl,beq
	bcc part1
	beq part2
	bcs part4

part1					; draw pseudo moire pattern
	stx COLOR2			; x ranges from 0 to 3, so almost black (saves the lda #0 stuff)
	inc COLCRS
	bne weiter
	inc ROWCRS
weiter
	lda $b0
	adc ROWCRS
	sta $b0
	lda $b1
	adc COLCRS
	sta $b1
	eor $b0
	sta color
	jsr drawpoint
	bvc fx
	
part2					; scroll up upper and lower half of the screen
;	lda SAVMSC+1		; switch between the two banks (upper and lower half) and scroll each
;	eor #$10
;	sta SAVMSC+1
	jsr $f7f7			; illegal OS B vector to scroll part of the screen up (within the 4k bank)
	jmp fx
	
part4
	lda #0				; open GR.0 with black background
	jsr openmode
part4start
	jsr $f9a6			; illegal OS B vector to save SAVMSC in ADRESS

	ldx #24
	stx ay
part4y
	ldy #39
	sty ax				; just use *any* constant value as init
part4x
	txa
	adc vbipos			; inc x factor
part4adc
	adc ax				; ora gives fullscreen scrolling black/white, eor gives fullscreen scrolling stripes, adc gives scrolling curve pattern
	sta ax
part4eor
	sta ay				; eor with y factor
	and #128			; use only inverse bit
	ora textdata,y		; or with SquoQuo text
	sta (ADRESS),y		; and save to screen
	
	dey					; next
	bpl part4x

	clc					; increase address by either 40 or 41 (see vbi) => chess board or diagonal board
	lda ADRESS
part4adder
	adc #40				; 40 gives standard chess board, other values give diagonally teared chessboards
	sta ADRESS
	bcc noinc
	inc ADRESS+1
noinc

	lda vbipos			; inc y factor
	adc ay
	sta ay

	dex					; next row
	bne part4y
	stx COLOR2			; x is 0 now, so use this as the background color
	
	beq part4start		; repeat endlessly (bpl before fails, so bmi must jump)
ax	equ $a0
ay	equ $a1


;################### VBI mainly driving the audio
vbi						; VBI is locate on page start, so we can use static init values for multiple initializations
	inc vbipos			; increase 16 bit counter (RTCLOK wouldn't do because of the unstable starting value)
	bne vbi_start
	inc vbipos+1
;	lda part4adder+1
;	eor #1
;	sta part4adder+1
;	inc part4adder+1	; increase zoomer line offset to generate different patterns

	lda part4adc		; change the zoom-interference commands to change the patterns
	eor #$20			; switch between adc and eor (curves vs scrolling stripes)
	sta part4adc
	cmp #$45
	beq vbi_start		; only switch the other commands every second run
	lda part4eor
	eor #$c0			; switch between eor and sta (replace for illegal DOP)
	sta part4eor
	bpl vbi_start		; only switch the last command every fouth run
	lda part4x
	eor #$12			; switch between txa and tya (as pseudo constant init)
	sta part4x
vbi_start

	;#### audio part
	lda vbipos+1		; easy pattern selection, only 4 variants are possible (valid values: 0,2,4,6)
	and #6				; a bit pattern testing each channel separately would be better, but uses more memory
	tax
audioloop
	ldy audioamp,x		; preload current amplitude
	lda vbipos
	and audiomask,x
	bne audiodec		; if trigger fires...

	ldy vbipos			; new frequency is only set if trigger fires
	lda audioramp+1,x	; get the rom page used for this channel
	sta audioromreader+1
	lda (audioromreader),y	; grab some random ROM part
	ora #7				; failsafe to avoid to high notes
	sta AUDF1,x			; and use as "note"
	ldy #25				; set the amplitude to 25 (will be decremented afterwards anyway)
audiodec
	tya					; get the current amplitude
	sbc audioramp,x		; falloff
	bpl audiodec_valid
	lda #0				; clip to 0
audiodec_valid
	sta audioamp,x		; store amplitude
	ora audiomask+1,x	; or the sound mask
	sta AUDC1,x			; and fill the audc register

	dex					; next one (skip 2 since we're using this as an index to the AUDC1-4 registers
	dex
	bpl audioloop
	
vbi_end


.ifdef edit
	;**************** keycode for adjusting the sound patterns
	lda KEY
	cmp #255
	beq vbi_finish
	cmp keyold
	beq vbi_finish
	
	cmp #$8e
	bne key_not_up
	inc audioramp+1
key_not_up
	cmp #$8f
	bne vbi_finish
	dec audioramp+1
	jmp vbi_finish
keyold	dta 255
vbi_finish
	sta keyold
	lda #255
	sta KEY
	;************* end of keycode
.endif


	jmp RETURN
	
	
	
	
	
	
vbipos		equ $80			; dword, should be 0 initially, will be 16bit frame counter
audioamp	equ $82			; 8 bytes of zero initially
audioromreader	equ $8a

audiomask
			dta $07,$80		; each line corresponds to one audio channel
			dta $07,$80		; first byte is the and mask for triggering
			dta $24,$a0		; second byte is the ORed audio control (use lower 4 bits for constantly playing sound)
			dta $0f,$60

audioramp		; since value starts at 25 (due to size optimized routine, see above) falloff values below 3 lead to audibly delayed sounds
			dta $10,$30		; each line corresponds to one audio channel
			dta $05,$f0		; first byte is the falloff value (i.e. 0=constant, 1=longest tone, $10=click)
			dta $0e,$f0		; second byte is the memory page used for frequencies
			dta $02,$e8

;audiobit	dta $00,$00,$01,$01,$02,$02,$04,$04


;26 60 08 ee
;07 82 0a e8		relaxed nice rhythm
;26 a0 03 fb
;24 a0 03 f0		chords
;07 80 10 30		closed hihat
;0f 60 01 e8		bassline

textdata	dta d'SquoQuo'

	run start