;scrolling w trybie tekstowym 80-cio kolumnowym
;XDL, MEMAC, blitter

        opt     l-
        icl     'atarihw.ah'
        icl     'atarios.ah'
        icl     'vbxefx.asm'
        opt     l+


LINE_WIDTH equ 80


        org     $8000

init    rts
        ini     init

        org     $8000

start
        .local

        .zpvar  ptr1 .word
        .zpvar  ptr2 .word
        
        DetectCore
        seq
        rts
        ResetCore

        ;kopiowanie systemowego generatora znaków do pamięci VBXE
        ;używamy bank MEMAC-B w trybie dostępu dla CPU
        ;adres docelowy generatora w VBXE: 0x00800

        fxs     #0 FX_MEMC
        fxs     #MBCE FX_MEMB
        ;znaki 0 - 127 generatora systemowego
        mwa     #0xe000 ptr1
        mwa     #0x4800 ptr2
        ldx     #4
        ldy     #0
l1      lda     (ptr1),y
        sta     (ptr2),y
        iny
        bne     l1
        inc     ptr1+1
        inc     ptr2+1
        dex
        bne     l1
        ;druga część generatora (znaki 128 - 255) inverse
        mwa     #0xe000 ptr1
        ldx     #4
l2      lda     (ptr1),y
        eor     #0xff
        sta     (ptr2),y
        iny
        bne     l2
        inc     ptr1+1
        inc     ptr2+1
        dex
        bne     l2

        ;przepisywanie palety (nr1), użyjemy tylko 16 kolorów

        fxs     #1 FX_PSEL
        ldx     #0
        fxs     #0 FX_CSEL
        mwa     #palette ptr1
p1      ldy     #0
        lda     (ptr1),y
        fxsa    FX_CR
        ldy     #1
        lda     (ptr1),y
        fxsa    FX_CG
        ldy     #2
        lda     (ptr1),y
        fxsa    FX_CB
        adw     ptr1 #3
        inx
        cpx     #16
        bcc     p1

        ;kopiuj XDL i BlitterList do pamięci VBXE
        ;adres (w VBXE) 0x00000, w ATARI 0x4000 (początek MEMAC_B_WINDOW)

        ldx     #0
l3      lda     xdl_load_address,x
        sta     xdl_address,x
        inx
        bne     l3
        ;czyść ekran w pamięci VBXE
        ;dla uproszczenia 256 bajtów
        txa
l4      sta     scrollline,x
        inx
        bne     l4
        ;wskaż kontrolerowi VBXE adres XDL
        lda     <xdl_pointer
        fxsa    FX_XDL_ADR0
        lda     >xdl_pointer
        fxsa    FX_XDL_ADR1
        lda     ^xdl_pointer
        fxsa    FX_XDL_ADR2
        ;wskaż blitterowi adres XDL
        lda     <blitterlist
        fxsa    FX_BL_ADR0
        lda     >blitterlist
        fxsa    FX_BL_ADR1
        lda     ^blitterlist
        fxsa    FX_BL_ADR2
        ;włącz wyświetlanie
        fxs     #VC_XDL_ENABLED FX_VIDEO_CONTROL
        fxs     #0 FX_MEMB

        .endl

        ;pętla główna
loop    lda     20
        cmp     20
        req
        jsr     hscroll_routine
        jmp     loop


        ;procedura obsługi hscroll
hscroll_routine
        sei
        inc     NMIEN
        fxs     #MBCE FX_MEMB

        .local

        ;uaktualnij rejestr fine Hscrolling w XDL
        ;0,1,2,3,4,5,6,7,0,1,2, ....
        ;ta kolejność daje przesuw w lewo
        ;wartość 0 brak przesuwu, wartość 7 to przesuw o 7 pikseli w lewo.
        lda     xdl_hscroll_register
        add     #1
        and     #7
        sta     xdl_hscroll_register
        jne     l4

        ;Hscroll = 0
        ;Kopiowanie ekranu wraz z atrybutami
        ;na pozycję o jeden znak w lewo.
        ;Bufor ekranu ma w sumie LINE_WIDTH+1 znaków czyli z atrybutami
        ;(LINE_WIDTH+1)*2 bajtów

        ;kopiowanie przez CPU ATARI
;        ldx     #(0-LINE_WIDTH*2)
;l5      lda     scrollline+2-((0-LINE_WIDTH*2)&255),x
;        sta     scrollline-((0-LINE_WIDTH*2)&255),x
;        inx
;        bne     l5

        ;kopiowanie przez blitter VBXE
        fxs     #1 FX_BLITTER_START
czek    fxla    FX_BLITTER_BUSY
        jne     czek

        ;wypis nowego znaku na skrajnie prawej
        ;(dla przesuwu 0 całkowicie niewidocznej) pozycji
        ;Za każdym "powtórzeniem" linii tekstu
        ;nadamy nowy kolor 0 - 15 z palety nr 1, która jest przypisana dla
        ;Overlay automatycznie, gdy nie jest włączona mapa atrybutów
        ldx     txt_index
l1      lda     txt_array,x
        cmp     #255
        jne     l2
        ldx     #0
        lda     RANDOM
        and     #15
        sta     txt_color
        lda     txt_array
l2      inx
        stx     txt_index
        sta     scrollline+(LINE_WIDTH*2)
        lda     txt_color
        sta     scrollline+(LINE_WIDTH*2)+1

l4      fxs     #0 FX_MEMB
        mva     #0x40 NMIEN
        cli

        rts

txt_array
        .byte   "the quick brown fox jumps over the lazy dog "
        .byte   "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG "
        .byte   "the quick brown fox jumps over the lazy dog "*
        .byte   "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG "*
        .byte   "     "
        .byte   255

txt_index
        .byte   txt_index-txt_array-1
txt_color
        .byte   0

        .endl

palette
        ;prosta przykładowa paleta
        ;kolorów dla Overlay
        ;podstawowe barwy i ich podstawowe kombinacje
        ;R, G, B
        .byte   0, 0, 0               ;kolor 0
        .byte   0xa0, 0xa0, 0xa0      ;kolor 1
        .byte   0xff, 0xff, 0xff      ;kolor 2
        .byte   0xa0, 0, 0            ;kolor 3
        .byte   0xff, 0, 0            ;kolor 4
        .byte   0, 0xa0, 0            ;kolor 5
        .byte   0, 0xff, 0            ;kolor 6
        .byte   0, 0, 0xa0            ;kolor 7
        .byte   0, 0, 0xff            ;kolor 8
        .byte   0xa0, 0xa0, 0         ;kolor 9
        .byte   0xff, 0xff, 0         ;kolor 10
        .byte   0xa0, 0, 0xa0         ;kolor 11
        .byte   0xff, 0, 0xff         ;kolor 12
        .byte   0, 0xa0, 0xa0         ;kolor 13
        .byte   0, 0xff, 0xff         ;kolor 14
        .byte   0x80, 0x80, 0x80      ;kolor 15


;*** XDL ***

;XDL załaduje się do normalnej pamięci ATARI
;następnie zostanie skopiowane przy inicjalizacji programu do pamięci VBXE
;Korzystamy z bufora MEMAC_B
;dodatkowe założenie dla uproszczenia:
;wszystkie dane (XDL, ekran, fonty) dostępne
;są z banku nr 0 MEMAC_B
xdl_load_address equ *

        ;ładuj poza MEMAC_B ale asembluj pod adres MEMAC_B_WINDOW
        org     $4000,*

;ten adres wskażemy jako początek XDL w rejestrach XDL_ADR0,1,2
xdl_pointer equ *-$4000

;ten adres jest początkiem XDL widzianego przez okno MEMAC_B
xdl_address

        ;XDLC
        ;24 puste linie od góry ekranu ...
        .word   XDLC_RPTL
        .byte   3*8-1

        ;XDLC
        ;tryb tekstowy, załaduj też informacje o
        ;  - ilości kolejnych linii (XDLC_RPTL)
        ;  - adresie obszaru wyświetlanego (XDLC_OVADR)
        ;  - rejestrach scrollingu (XDLC_OVSCRL)
        ;  - adresie generatora znaków (XDLC_CHBASE)
        ;jednocześnie jest to koniec XDL (XDLC_END)
        .word   XDLC_TMON + XDLC_END + XDLC_RPTL + XDLC_OVADR + XDLC_OVSCRL + XDLC_CHBASE

        ;XDLC_RPTL
        ;razem 8 linii trybu tekstowego (jeden wiersz)
        .byte   7

        ;XDLC_OVADR
        ;adres ekranu bezpośrednio za XDL w pamięci VBXE
        .long   scrollline - $4000
        ;krok adresu - nie używamy (bo jest tylko jedna linia trybu tekstowego),
        ;ale musi być przy okazji adresu, więc niech będzie 0
        .word   0

        ;XDLC_OVSCRL
        ;rejestry scrollingu poziomego i pionowego dla tej linii tekstu
xdl_hscroll_register
        .byte   0       ;hscroll
        .byte   0       ;vscroll

        ;XDLC_CHBASE
        ;generator znaków w pamięci VBXE pod adresem 0x00800 ( 1 x 0x800 )
        .byte   1

blitterlist equ *-$4000

        ;tylko jeden blok BCB
        .long   scrollline - $4000 + 2 ;src adr (18 bit)
        .word   0                               ;src y step (-4096 ... 4095)
        .byte   1                               ;src x step (-128 ... 127)
        .long   scrollline - $4000     ;dst adr
        .word   0                               ;dst y step (-4096 ... 4095)
        .byte   1                               ;dst x step (-128 ... 127)
        .word   159                             ;width (0 ... 511 = 1 ... 512 bajtów)
        .byte   0                               ;height (0 ... 255 = 1 ... 256 linii)
        .byte   255                             ;AND mask
        .byte   0                               ;XOR mask
        .byte   0                               ;collision mask
        .byte   0                               ;zoom XY
        .byte   0                               ;pattern feature
        .byte   0                               ;control

        ;Obszar wyświetlany bezpośrednio za XDL
scrollline  equ *

;---------------------------------------------------------------------

        run     start

        end
