; Race the Beam

; try for 40x192 15-color graphics on stock Apple II / Apple II+
;   this means, no double-hires

; by racing the beam we can possibly update at least 10 blocks
; per line to the 192-line resolution

; we can get 40x96 resolution simply by page flipping

; this all requires vapor lock cycle-counting


; by deater (Vince Weaver) <vince@deater.net>

; Zero Page
FRAMEBUFFER	= $00	; $00 - $0F
YPOS		= $10
YPOS_SIN	= $11
CH		= $24
CV		= $25
GBASL		= $26
GBASH		= $27
BASL		= $28
BASH		= $29
FRAME		= $60
WAITING		= $62
LETTERL = $63
LETTERH = $64
LETTERX = $65
LETTERY = $66
LETTERD = $67
LETTER  = $68
BLARGH		= $69
HGR_COLOR	= $E4
STATE		= $ED
DRAW_PAGE	= $EE
LASTKEY		= $F1
PADDLE_STATUS	= $F2
TEMP		= $FA
WHICH		= $FB

; Soft Switches
KEYPRESS= $C000
KEYRESET= $C010
SPEAKER	= $C030
SET_GR	= $C050 ; Enable graphics
SET_TEXT= $C051 ; Enable text
FULLGR	= $C052	; Full screen, no text
TEXTGR	= $C053 ; Split screen
PAGE0	= $C054 ; Page0
PAGE1	= $C055 ; Page1
LORES	= $C056	; Enable LORES graphics
HIRES	= $C057 ; Enable HIRES graphics

PADDLE_BUTTON0 = $C061
PADDL0	= $C064
PTRIG	= $C070

; ROM routines
;HGR	= $F3E2
;HPLOT0	= $F457
;HGLIN	= $F53A
;COLORTBL= $F6F6
TEXT	= $FB36				;; Set text mode
HOME	= $FC58				;; Clear the text screen
WAIT	= $FCA8				;; delay 1/2(26+27A+5A^2) us


	;==================================
	;==================================


setup_background:

	;===================
	; init screen
	jsr	TEXT
	jsr	HOME
	bit	LORES
	bit	SET_GR
	bit	FULLGR
	bit	PAGE0
	bit	KEYRESET

	;===================
	; init vars

	lda	#0
	sta	DRAW_PAGE
	sta	STATE
	sta	WAITING


	;=============================
	; Load graphic page0

;	lda	#$0c
;	sta	BASH
;	lda	#$00
;	sta	BASL                    ; load image to $c00

;	lda	#<bg_final_low
;	sta	GBASL
;	lda	#>bg_final_low
;	sta	GBASH
;	jsr	load_rle_gr

;	lda	#4
;	sta	DRAW_PAGE

;	jsr	gr_copy_to_current	; copy to page1

	; GR part
;	bit	PAGE1
;	bit	LORES							; 4
;	bit	SET_GR							; 4
;	bit	FULLGR							; 4

;	jsr	wait_until_keypressed


	;=============================
	; Load graphic page1

;	lda	#$0c
;	sta	BASH
;	lda	#$00
;	sta	BASL                    ; load image to $c00

;	lda	#<bg_final_high
;	sta	GBASL
;	lda	#>bg_final_high
;	sta	GBASH
;	jsr	load_rle_gr

;	lda	#0
;	sta	DRAW_PAGE

;	jsr	gr_copy_to_current

	; GR part
;	bit	PAGE0

;	jsr	wait_until_keypressed


	;==============================
	; setup graphics for vapor lock
	;==============================

	jsr	vapor_lock				; 6

	; vapor lock returns with us at beginning of hsync in line
	; 114 (7410 cycles), so with 5070 lines to go

	; so we have 5070 + 4550 = 9620 to kill

	jsr	gr_copy_to_current		; 6+ 9292

	; now we have 322 left

	; GR part
	bit	LORES							; 4
	bit	SET_GR							; 4
	bit	FULLGR							; 4

	; 322 - 12 = 310
	; - 3 for jmp
	; 307

	; Try X=9 Y=6 cycles=307

        ldy	#6							; 2
loopA:
	ldx	#9							; 2
loopB:
        dex                                                             ; 2
        bne     loopB                                                   ; 2nt/3

        dey                                                             ; 2
        bne     loopA                                                   ; 2nt/3

        jmp     display_loop						; 3
.align  $100


	;================================================
	; Display Loop
	;================================================
	; each scan line 65 cycles
	;       1 cycle each byte (40cycles) + 25 for horizontal
	;       Total of 12480 cycles to draw screen
	; Vertical blank = 4550 cycles (70 scan lines)
	; Total of 17030 cycles to get back to where was

	; We want to alternate between page1 and page2 every 65 cycles
        ;       vblank = 4550 cycles to do scrolling


	; 2 + 48*(  (4+2+25*(2+3)) + (4+2+23*(2+3)+4+5)) + 9)
	;     48*[(6+125)-1] + [(6+115+10)-1]

display_loop:

	;===================================
	; 192 lines, alternate PAGE0/PAGE1 every 2 lines
	;===================================


	ldy	#96		; *2=192 lines			; 2

	; we set PAGE0 (4) then want to NOP (61) for a total of 65
bouter_loop:
	bit	PAGE0						; 4
	ldx	#12		; 65 cycles with PAGE0		; 2
bpage0_loop:			; delay 61+bit
	dex							; 2
	bne	bpage0_loop					; 2/3
							;=============
							; 6+(12*5)-1=65

	; we set PAGE1 (4) as well as dey (2) and bne (3) then nop (55)
	;

	bit	PAGE1						; 4
	ldx	#11		; 65 cycles with PAGE1		; 2
bpage1_loop:
	dex							; 2
	bne	bpage1_loop					; 2/3
							;=============
							; 6+(11*5)-1=60

	dey							; 2
	bne	bouter_loop					; 2/3
							;==============
							; 5 to make 65

	;======================================================
	; We have 4550 cycles in the vblank, use them wisely
	;======================================================
	;			4550
	;			  +1  fallthrough
	;			  -2  for ldy in previous
	;			 -35  call through jumptable
	;			  -7  keyboard
	;			  -3  jmp
	;			========
	;			4504
	;========================
	; each subunit should take 4504 cycles

firework_state_machine:

check_keyboard:

	lda	KEYPRESS				; 4
	bpl	no_keypress				; 3
	jmp	restart
no_keypress:

	jmp	display_loop				; 3



restart:

	jmp	setup_background


.include "gr_hline.s"
;.include "../asm_routines/gr_unrle.s"
;.include "../asm_routines/keypress.s"
.include "gr_copy.s"
;.include "random16.s"
.include "vapor_lock.s"
.include "delay_a.s"


