	processor 6502
	include vcs.h
	include macro.h

    include pixbuf.asm
    include text.asm
    include pinwheel.asm
    include rotozoom.asm
    include twister.asm

	;constants
PAL		equ	1
BANKSW  equ 1   ;enable bankswitching? (8k)

#if PAL

;PAL
VBLNK	equ	48-4            ;account for VERTICAL_SYNC
LINES	equ	228
OVERSCN	equ	36
FPS		equ	50

#else

;NTSC
VBLNK	equ	40-4            ;account for VERTICAL_SYNC
LINES	equ	192
OVERSCN	equ	30
FPS		equ	60

#endif

VBLNK64	equ	VBLNK*19/16		;value to set TIM64 to for VBLNK

	;RAM
	SEG.U VARS
	org $80

	;variables common to all scenes
temp	ds	3
frame	ds	1

	;song player vars
temp16L equ temp + 1
temp16H equ temp + 2
beat	ds	1
tempoCount	ds	1
measure	ds	1
atten	ds	1

fnptr   ds  2       ;function pointer
                    ;used for kernels and bank jump destinations

	;per-scene RAM starts here
SCENRAM	equ	*

	;This macro prints the amount of RAM left and
	;switches back to the start of the per-scene RAM.
	;In other words, it is used to delimit scene
	;specific RAM and keep track of how much memory
	;each one uses.
	MAC NEXT_SCENE_RAM
	echo "RAM:", ($100 - *), "bytes left"
	org SCENRAM
	ENDM

	NEXT_SCENE_RAM
    PIXBUF_VARS
	NEXT_SCENE_RAM
    PINWHEEL_VARS
    NEXT_SCENE_RAM
ramkernel   ds  KERNELSIZE
    NEXT_SCENE_RAM
    ROTOZOOM_VARS
    NEXT_SCENE_RAM
    TWISTER_VARS
    NEXT_SCENE_RAM

	;ROM
	SEG CODE

#if BANKSW
    ;Bank 0
	org $E000
    rorg $F000
#else
	org $F000
#endif

    include sintab.asm
    echo "Sintab ends @",*
    include plasmatab.asm
    echo "Plasmatabs end @",*
    include pinwheeltabs.asm
    echo "Pinwheeltabs end @",*
    GREETDATA
    echo "GreetData:",GreetData,"-",*

    PINWHEEL_KERNEL
    PINWHEEL_LOGIC

    include utils.asm

    PIXBUF_LOGIC
    PIXBUF_KERNEL
    PIXBUF_LOGIC2

	include font.asm

    SCROLLER_LOGIC

    include plasma.asm

    PLASMA_LOGIC

    include twistertabs.asm

    ROTOZOOM_LOGIC
RotozoomKernel
    ROTOZOOM_KERNEL 1
RotozoomKernel2
    ROTOZOOM_KERNEL 0

    TWISTER_LOGIC
    TWISTER_KERNEL

TextString
	.byte "HELLO GDANSK! THIS IS YOUR PAL TJOPPEN WITH A LITTLE DEMO FOR THE ATARI VCS. ENJOY THE SHOW!", 0

SceneMeasures
    .byte INTROLEN
    .byte INTROLEN+8
    .byte INTROLEN+12
    .byte INTROLEN+20
    .byte INTROLEN+24
    .byte INTROLEN+32

NUM_SCENES equ *-SceneMeasures+1

LogicPointers
    .word ScrollLogic
    .word TwisterLogic
    .word RotozoomLogic
    .word PlasmaLogic
    .word RotozoomLogic
    .word PinwheelLogic
    .word PlasmaLogic

KernelPointers
    .word PixBufKernel
    .word TwisterKernel
    .word RotozoomKernel
    .word PlasmaKernel
    .word RotozoomKernel2
    .word PinwheelKernel
    .word PlasmaKernel

ScrollLogic
    jsr PixBufLogic
    lda frame
    and #1
    beq ScrollLogic_Return
    ldx #64
    jsr PixBufShiftLeft
    ldx #51
    jsr ScrollerLogic

ScrollLogic_Return
    rts

BlackKernel
    ldx #LINES
BlackKernel_Loop
    sta WSYNC
    dex
    bne BlackKernel_Loop
    jmp DoneKernel

Start
	CLEAN_START

    START_SCROLLING_STRING TextString

MainLoop
	VERTICAL_SYNC
	lda #VBLNK64
	sta TIM64T

    lda measure
    cmp #SONGLEN
    bcc DoPlaySong

    ;black out/silence
    lda #0
    sta COLUBK
    sta COLUPF
    sta COLUP0
    sta COLUP1
    sta AUDC0
    sta AUDC1
    sta AUDF0
    sta AUDF1
    sta AUDV0
    sta AUDV1

    ;I could just JAM ($02) here, but Stella is dumb and stops rendering.
    ;Hence we need to run a dummy black kernel instead.
    lda #<BlackKernel
    sta fnptr
    lda #>BlackKernel
    sta fnptr+1
    jmp WaitForVblankEnd

DoPlaySong
    lda #<GotoSongPlayer
    sta fnptr
    lda #>GotoSongPlayer
    sta fnptr+1
    jmp JMPBank1
SongPlayerRet

	inc frame

    ldx #0
    lda measure
FindSceneLoop
    cmp SceneMeasures,X
    bcc FoundScene
    inx
    cpx #NUM_SCENES-1
    beq FoundScene
    bne FindSceneLoop

FoundScene
    txa
    asl
    pha
    tax
    lda #>(LogicReturnAddr-1)
    pha
    lda #<(LogicReturnAddr-1)
    pha
    lda LogicPointers,X
    sta fnptr
    lda LogicPointers+1,X
    sta fnptr+1
    jmp (fnptr)
LogicReturnAddr
    pla
    tax
    lda KernelPointers,X
    sta fnptr
    lda KernelPointers+1,X
    sta fnptr+1

WaitForVblankEnd
	lda INTIM
	bne WaitForVblankEnd
    sta VBLANK

    jmp (fnptr)

DoneKernel
    lda #2
    sta VBLANK
	ldx #OVERSCN
OverScanWait
	sta WSYNC
	dex
	bne OverScanWait
	jmp MainLoop

#if !BANKSW
	echo "ROM:", ($FFFC - *), "bytes left"

	org $FFFC
	.word Start
	.word Start
#else
    echo "Bank 0:", ($FFF2 - *), "bytes left"

    org $EFF2
    rorg $FFF2

;Jump to fnptr in bank 1
JMPBank1
    nop $1FF9
    jmp (fnptr)

    ;$FFF8-$FFFB
    ;aka $1FF8-$1FFB
    .byte 0,0,0,0

    .word Start
    .word Start

    ;Bank 1
    org $F000
    rorg $F000

    ;the music didn't fit in 4k. good thing we're allowed 8k :o
    include songplay.h
    include song.asm

    echo "Song+player:",*-$F000

Start2
    lda #<Start
    sta fnptr
    lda #>Start
    sta fnptr+1
    jmp JMPBank0

GotoSongPlayer
    jsr songPlayer
    lda #<SongPlayerRet
    sta fnptr
    lda #>SongPlayerRet
    sta fnptr+1
    jmp JMPBank0

    echo "Bank 1:", ($FFF2 - *), "bytes left"

    org $FFF2
    rorg $FFF2

;Jump to fnptr in bank 0
JMPBank0
    nop $1FF8
    jmp (fnptr)

    ;$FFF8-$FFFB
    ;aka $1FF8-$1FFB
    .byte 0,0,0,0

    .word Start2
    .word Start2
#endif
