;-------------------------------------------------------------------------------
; SPINNING SQUARE ANIMATION
; Program generates an animation of a single line of 5 4x4 rotating squares.
; Animation handled by updating vram in response to a timer interrupt.
;
; CHARACTER FILE REQUIRED: Requires character file laying out the bitmaps for
; the different characters of the animation. The file should be organized by
; animation frame, with the bitmap bytes of each character in the 4x4 frame
; organized left to right, top to bottom.
;
; TO RUN:
; Load the character from disc: eg LOAD"CHARS",8,1
; Load the main program from disc: eg LOAD"SQRLN.PRG",8,1
; Relocate character ROM to $1800 (6144): POKE 36869,254
; RUN
;-------------------------------------------------------------------------------

; Structure
;	ADDRESS SYMBOLS
;	JMP MAIN
;	CODE:
;		IRQ CODE
;		MAIN
;		SCREEN ANIMATION CODE


;                              >>> ADDRESSES <<<
;
SCR1_RAM = $1E00
LIN1_RAM = $1E01 ; Selecting from these addresses picks which line the square
LIN2_RAM = $1E59 ; appear on.
LIN3_RAM = $1EB1
LIN4_RAM = $1F09
LIN5_RAM = $1F61
COLR_RAM = $9600
CHAR_MEM = $1800
SCRN_SEL = $9002


;                              >>> JMP MAIN <<<
;
; Makes tass assembler add these two bytes at start of binary (little endian)
	* = $1001
; SYS 4111 - this byte sequence launchs prg by running BASIC: SYS 4111
	.BYTE $0D,$10,$0A,$00,$9E,$28,$34,$31,$31,$31,$29,$00
	BRK #$00
	JMP MAIN


;                                >>> CODE <<<
;
;---- IRQINIT ------------------------------------------------------------------
; Initialize IRQ wedge: adapted from Mastering VIC20 demo on using the timer.
; Init code updates irq vector to point to custom irq wedge (handler); Address
; can be found by assembling the code and inspecting the symbol table.
IRQINIT
	SEI
	LDA #$27	; set lo-byte of IRQ wedge subroutine
	STA $0314
	LDA #$10	; set hi-byte of IRQ wedge subroutine
	STA $0315
	LDA #$0
	STA CNTR	; initialize variables used by irq handler
	STA CURFRM
	CLI
	RTS

;---- IRQS ---------------------------------------------------------------------
; IRQ wedge (ie interrupt handler) that calls animation subroutine
IRQS
	INC CNTR
	LDA CNTR
	CMP #$06 ; -> 60 ticks = 1 sec
	BNE IRQEND

	LDA #$00 ; reset counter
	STA CNTR
	JSR SCRNUPDT

IRQEND
	JMP $EABF

; IRQ DATA
CNTR	.BYTE	$00
CURFRM	.BYTE	$00

;---- MAIN ---------------------------------------------------------------------
MAIN
	JSP CLR_SCREEN
	JSR IRQINIT
WAIT
	NOP		; Spin in a loop while animation runs
	JMP WAIT

;---- CLR_SCREEN ---------------------------------------------------------------
; Clears screen by writing spaces to character matrix and setting the character
; color to blue. In effect, turns every cell 'on' so that writes to screen RAM
; are immediately visible (no need to set color each time).
CLR_SCREEN
	LDX #$00
	LDA #$20		; PETSCII space char
CLR_LP1
	STA SCR1_RAM, X		; splits screen in half to use 8bit counter
	STA SCR1_RAM + $0100, X
	INX
	BNE CLR_LP1

	; Do color RAM next
	LDX #$00
	LDA #$06		; blue
CLR_LP2
	STA COLR_RAM, X		; splits screen in half to use 8bit counter
	STA COLR_RAM + $0100, X
	INX
	BNE CLR_LP2

	RTS


;---- SCRNUPDT -----------------------------------------------------------------
; Updates the screen with the next frame in the animation
SCRNUPDT
	INC CURFRM
	LDA CURFRM
	CMP #$08
	BNE MULT
	LDA #$00
	STA CURFRM
MULT
	CLC   ; since we know fram number <= 7, won't need to CLC each ROL
	ROL A
	ROL A
	ROL A
	ROL A ; multiply frame # by 16 == left shift x4

	TAY       ; Y should be offset pointing to start of frame in charmem
	          ; so: char index = Y + X w/ Y = 16*FrameNum
	          ; With Frame number zero-indexed
		  ; Y should hold the frame base offset at top of loop (here)

	LDX #0    ; for upcoming loops after branch

DRAWLP
	CLC
	STA LIN2_RAM, X
	STA LIN2_RAM + 4, X
	STA LIN2_RAM + 8, X
	STA LIN2_RAM + 12, X
	STA LIN2_RAM + 16, X
	ADC #$04
	STA LIN2_RAM + 22, X
	STA LIN2_RAM + 26, X
	STA LIN2_RAM + 30, X
	STA LIN2_RAM + 34, X
	STA LIN2_RAM + 38, X
	ADC #$04
	STA LIN2_RAM + 44, X
	STA LIN2_RAM + 48, X
	STA LIN2_RAM + 52, X
	STA LIN2_RAM + 56, X
	STA LIN2_RAM + 60, X
	ADC #$04
	STA LIN2_RAM + 66, X
	STA LIN2_RAM + 70, X
	STA LIN2_RAM + 74, X
	STA LIN2_RAM + 78, X
	STA LIN2_RAM + 82, X
	ADC #$04
	INY
	TYA
	INX
	CPX #$04
	BNE DRAWLP
DRAWEND
	RTS