COLOR0  equ     $40
COLOR1  equ     $50
COLOR2  equ     $60
TWISTBK equ     $88

    MAC TWISTER_VARS
twisterline ds  1
yoffset     ds  1   ;y offset of ribbons
yoffset2    ds  1   ;y offset of angle offset
xoffsetidx  ds  1
xoffset     ds  1
ribbonx     ds  3   ;known x positions of the ribbons
    ENDM

SINESTART   equ INTROLEN+4

    MAC TWISTER_LOGIC
TwisterLogic
    lda measure
    cmp #SINESTART
    bcc NoXOffset

    lda frame
    asl
    tax
    lda SinTab,X
    lsr
    adc frame
    asl
    sta xoffsetidx
    tax
    lda SinTab,X
    lsr
    lsr
    .byte $0C
NoXOffset
    lda #30
    sta xoffset

    lda frame
    tay
    lda SinTab,Y
    sta yoffset
    lda frame
    clc
    adc #100
    sta yoffset2

    lda #LINES/3
    clc
    adc yoffset2
    tax
    adc SinTab,X
    adc yoffset
    and #TABMASK
    tay
    lda XTab,Y
    clc
    adc xoffset
    sta ribbonx
    ldx #2
    jsr PositionObject

    tya
    adc #TABSIZE/3
    and #TABMASK
    tax
    lda XTab,X
    clc
    adc xoffset
    sta ribbonx+1
    ldx #3
    jsr PositionObject

    tya
    adc #TABSIZE*2/3
    and #TABMASK
    tax
    lda XTab,X
    clc
    adc xoffset
    sta ribbonx+2
    ldx #4
    jsr PositionObject

    sta WSYNC
    sta HMOVE
    sta WSYNC
    sta HMCLR

    lda #$02
    sta ENAM0
    sta ENAM1
    sta ENABL
    lda #$30
    sta NUSIZ0
    sta NUSIZ1

    rts
    ENDM

    MAC TWISTER_KERNEL
TwisterKernel
    lda #TWISTBK
    sta COLUBK
    sta COLUP0
    sta COLUP1
    sta COLUPF

    lda #LINES/3
    sta twisterline
TwisterKernel_Loop
    sta WSYNC
    sta HMOVE

    ;toggle playfield priority based on where the ball ribbon is
    ;this causes it to be hidden behind the other two ribbons
    ;half the time, which looks quite nice
    tya
    adc #41-TABSIZE*2/3
    lsr
    lsr
    lsr
    ;and #$04       ;we don't care about REF and SCORE
    ora #$30
    sta CTRLPF

    lda measure
    cmp #SINESTART
    bcc NoXOffset2

    ldx xoffsetidx
    inx
    inx
    stx xoffsetidx
    lda SinTab,X
    lsr
    lsr
    sta xoffset

NoXOffset2
    lda twisterline
    clc
    adc yoffset2
    tax
    adc SinTab,X
    adc yoffset
    and #TABMASK
    tay
    lda Palette,Y
    ora #COLOR0
    sta COLUP0
    ldx ribbonx
    lda XTab,Y
    clc
    adc xoffset
    sta ribbonx
    txa
    sec
    sbc ribbonx
    asl
    asl
    asl
    asl
    sta HMM0

    tya
    clc
    adc #TABSIZE/3      ;NOTE: due to Y & TABMASK, this never carries
    and #TABMASK
    tay
    lda Palette,Y
    ora #COLOR1
    sta COLUP1
    ldx ribbonx+1
    lda XTab,Y
    clc
    adc xoffset
    sta ribbonx+1
    txa
    sec
    sbc ribbonx+1
    asl
    asl
    asl
    asl
    sta HMM1

    tya
    clc
    adc #TABSIZE/3    ;NOTE: due to Y & TABMASK, this never carries
    and #TABMASK
    tay
    lda Palette,Y
    ora #COLOR2
    sta COLUPF
    ldx ribbonx+2
    lda XTab,Y
    clc
    adc xoffset
    sta ribbonx+2
    txa
    sec
    sbc ribbonx+2
    asl
    asl
    asl
    asl
    sta HMBL

    dec twisterline
    beq TwisterKernel_Done
    jmp TwisterKernel_Loop

TwisterKernel_Done
    lda #0
    sta ENAM0
    sta ENAM1
    sta ENABL
    sta COLUBK

    jmp DoneKernel
    ENDM
