Dokončení popisu čipu GTIA: vertikální posun spritů a detekce kolizí

9. 4. 2026
Doba čtení: 54 minut

Sdílet

Projekt Atari perex.
Autor: Michal Tauchman, podle licence: CC BY-SA 4.0
Projekt Atari perex.
Dnes se již naposledy budeme věnovat popisu práce se sprity s využitím čipu GTIA. Popíšeme si dvě důležité techniky. Nejdříve se budeme zabývat vertikálními posuny spritů a posléze si popíšeme detekci kolizí.

Dokončení popisu čipu GTIA: horizontální posun spritů, detekce kolizí

Co se dozvíte v článku
  1. Dokončení popisu čipu GTIA: horizontální posun spritů, detekce kolizí
  2. Podprogram pro vertikální posun spritu
  3. První demonstrační příklad: posun spritu vertikálním směrem
  4. Korekce posunu spritu: „smazání stop“
  5. Druhý demonstrační příklad: korektní automatický posun spritu směrem dolů
  6. Třetí demonstrační příklad: posun spritu směrem nahoru
  7. Ovládání spritu joystickem
  8. Čtvrtý demonstrační příklad: ovládání spritu joystickem
  9. Detekce kolizí čipem GTIA
  10. Význam jednotlivých bitů v kolizních registrech
  11. Pátý demonstrační příklad: detekce kolize prvního hráče s dalšími hráči
  12. Vymazání kolizních registrů
  13. Šestý demonstrační příklad: korektní vymazání kolizních registrů
  14. Kolize střel s hráči
  15. Sedmý demonstrační příklad: detekce kolize první střely s hráči
  16. Kolize spritů s prvky herního pole
  17. Osmý demonstrační příklad: realizace detekce kolize hráče s herním polem
  18. Příloha: Makefile pro překlad všech demonstračních příkladů
  19. Repositář s demonstračními příklady
  20. Odkazy na Internetu

Dnes se již naposledy budeme věnovat popisu práce se sprity (hráči a střelami neboli PMG) s využitím čipu GTIA, který je nedílnou součástí osmibitových mikropočítačů Atari. Popíšeme si dvě důležité techniky. Nejdříve se budeme zabývat vertikálními posuny spritů, přesněji řečeno vertikálními posuny postaviček či objektů zobrazených na obrazovce (samotné sprity jsou totiž stále vysoké 128 nebo 256 řádků a nemohou se vertikálně posunout, jejich obsah už ale ano).

Ve druhé polovině článku si popíšeme koncept detekce kolizí (collision detection). Čip GTIA totiž umožňuje na hardwarové úrovni detekovat například kolizi dvou hráčů, kolizi střely s hráčem nebo více hráči a dokonce i kolizi spritu s herním polem (playfield). Díky tomu je možné například zjednodušit výpočty ve hře a detekci a výpočet kolizí ponechat na hardware. Navíc jsou kolize detekovány s pixelovou přesností, takže jsou hry vytvořené na Atari mnohdy v tomto ohledu „přesnější“, než stejné hry portované na jiné stroje (PC, ZX Spectrum atd.).

Podprogram pro vertikální posun spritu

Připomeňme si, že horizontální posun spritu (ať již hráče či střely) je triviální, protože postačuje zapsat osmibitovou hodnotu představující posun do některého z řídicích registrů čipu GTIA. Tento zápis je proveden jen v několika strojových cyklech, takže je horizontální posun proveden prakticky „zadarmo“. Komplikovanější je ovšem situace u posunu vertikálního, protože ten vyžaduje modifikaci bitmapy spritu (ta má 128 nebo 256 řádků). Tato operace je složitější, a to jak z pohledu programového kódu, tak i z časového hlediska.

Samotný vertikální posun spritu lze realizovat různě, například skutečným posunem celého bloku 128–1 nebo 256–1 bajtů. To se typicky provádí dvěma podprogramy, protože posun „nahoru“ se pořadím prováděných operací liší od posunu „dolů“. Ovšem existuje i kratší varianta, a to přenos dat spritu z původní oblasti RAM, ve které je uložena bitmapa. Příkladem může být náš hráč o výšce pouhých osmi obrazových řádků. Bitmapu hráče lze do oblasti spritů (stránka 152 a další tři stránky) přenést například takto:

.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        tya
        pha                     ; uložit Y na zásobník

        ldx #8                  ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
Poznámka: důležité je, že tomuto podprogramu předáváme v index registru Y vertikální pozici hráče, který by v tomto případě měla být v rozsahu 0 až 128–8=120. Hodnotou index registru Y tedy můžeme řídit novou pozici hráče na obrazovce. A pozor: stará pozice není smazána! K tomuto problému se ihned vrátíme.

První demonstrační příklad: posun spritu vertikálním směrem

V dnešním prvním demonstračním příkladu je ukázáno, jak lze realizovat jednoduchý posun spritu (konkrétně prvního hráče) směrem dolů. Hlavní smyčka programu je upravena do této podoby:

        ldy #0                  ; počáteční vertikální pozice spritu
 
loop:
        jsr _wait_vsync         ; čekat na překreslení snímku
        jsr _wait_vsync         ; dtto
        jsr _wait_vsync         ; dtto
 
        jsr draw_at_y
        iny                     ; vertikální posun
        jmp loop
Poznámka: povšimněte si, že index registr Y je použit jako počitadlo s maximální hodnotou 255. To ovšem znamená, že po proběhnutí 128 iterací se začne de facto posouvat druhý hráč (což je chyba). A navíc nijak neřešíme mazání části bitmapy na původní pozici hráče:
Vertikální pohyb prvního hráče, začátek animace.

Obrázek 1: Vertikální pohyb prvního hráče, začátek animace.

Autor: tisnik, podle licence: Rights Managed

Vertikální pohyb prvního hráče, přibližně polovina animace.

Obrázek 2: Vertikální pohyb prvního hráče, přibližně polovina animace.

Autor: tisnik, podle licence: Rights Managed

Vertikální pohyb prvního hráče je následován pohybem druhého hráče.

Obrázek 3: Vertikální pohyb prvního hráče je následován pohybem druhého hráče.

Autor: tisnik, podle licence: Rights Managed

Úplný zdrojový kód dnešního prvního demonstračního příkladu vypadá následovně:

; ---------------------------------------------------------------------
; Vertikální posun spritu směrem dolů.
; ---------------------------------------------------------------------
 
.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
 
 
.proc main
        lda #80                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #100                ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #120                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #140                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #0                  ; priorita hráčů a pozadí
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #8                  ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
        ldy #0                  ; počáteční vertikální pozice spritu
 
loop:
        jsr _wait_vsync         ; čekat na překreslení snímku
        jsr _wait_vsync         ; dtto
        jsr _wait_vsync         ; dtto
 
        jsr draw_at_y
        iny                     ; vertikální posun
        jmp loop
 
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #8                  ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
.proc   _wait_vsync
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 24, 60, 126, 219, 255, 36, 90, 165
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Korekce posunu spritu: „smazání stop“

Jak bylo patrné ze screenshotů, hráč se sice skutečně pohyboval vertikálním směrem, ale zanechával za sebou stopu, resp. neprovádělo se mazání jeho původní pozice. Samozřejmě by bylo možné nejdříve smazat celý blok 128 či 256 bajtů, ale to je zbytečně zdlouhavé a současně by to mohlo způsobit blikání spritu. V případě, že se hráč vždy posune o jeden řádek nahoru nebo dolů, můžeme použít malý trik: zvýšit hráče o dva řádky, přičemž tyto řádky budou obsahovat nulové pixely (bity):

; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0

Patřičně se upraví kód pro prvotní vykreslení hráčů:

        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu

A změní se i rutina pro posun, tedy pro překreslení na Y-tou pozici:

.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        tya
        pha                     ; uložit Y na zásobník

        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu

        pla
        tay                     ; obnovit Y ze zásobníku
        rts                     ; návrat z podprogramu
.endproc

Druhý demonstrační příklad: korektní automatický posun spritu směrem dolů

Po úpravách popsaných v předchozí kapitole bude pohyb spritu animován korektně:

Vertikální pohyb prvního hráče, začátek animace.

Obrázek 4: Vertikální pohyb prvního hráče, začátek animace.

Autor: tisnik, podle licence: Rights Managed

Vertikální pohyb prvního hráče, přibližně polovina animace.

Obrázek 5: Vertikální pohyb prvního hráče, přibližně polovina animace.

Autor: tisnik, podle licence: Rights Managed

Vertikální pohyb prvního hráče je ihned následován pohybem hráče druhého.

Obrázek 6: Vertikální pohyb prvního hráče je ihned následován pohybem hráče druhého.

Autor: tisnik, podle licence: Rights Managed

Následuje výpis zdrojového kódu takto upraveného příkladu:

; ---------------------------------------------------------------------
; Vertikální posun spritu dolů (korektní varianta).
; ---------------------------------------------------------------------
 
.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
 
 
.proc main
        lda #80                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #100                ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #120                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #140                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #0                  ; priorita hráčů a pozadí
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
        ldy #0                  ; počáteční vertikální pozice spritu
 
loop:
        jsr _wait_vsync         ; čekat na překreslení snímku
        jsr _wait_vsync         ; dtto
        jsr _wait_vsync         ; dtto
 
        jsr draw_at_y
        iny                     ; vertikální posun
        jmp loop
 
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
.proc   _wait_vsync
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Třetí demonstrační příklad: posun spritu směrem nahoru

Jen pro úplnost si ve třetím příkladu otestujeme, že i posun spritu směrem nahoru (tedy zmenšování y-ové složky) bude do jisté míry funkční. Vzhledem k tomu, že používáme sprity o výšce 128 řádků (a tedy 128 bajtů), bude po podtečení y-ové hodnoty posunován druhý hráč. Opět platí: oprava by byla relativně snadná, ovšem jedná se o velmi krátký příklad, takže ji prozatím do výsledného kódu nezahrneme.

Pohyb prvního hráče směrem nahoru, začátek animace.

Obrázek 7: Pohyb prvního hráče směrem nahoru, začátek animace.

Autor: tisnik, podle licence: Rights Managed

Pohyb prvního hráče směrem nahoru, přibližně první třetina animace.

Obrázek 8: Pohyb prvního hráče směrem nahoru, přibližně první třetina animace.

Autor: tisnik, podle licence: Rights Managed

Pohyb prvního hráče nahoru po podtečení počitadla.

Obrázek 9: Pohyb prvního hráče nahoru po podtečení počitadla.

Autor: tisnik, podle licence: Rights Managed

Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:

; ---------------------------------------------------------------------
; Vertikální posun spritu směrem nahoru.
; ---------------------------------------------------------------------
 
.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
 
 
.proc main
        lda #80                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #100                ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #120                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #140                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #0                  ; priorita hráčů a pozadí
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
        ldy #127                ; počáteční vertikální pozice spritu
 
loop:
        jsr _wait_vsync         ; čekat na překreslení snímku
        jsr _wait_vsync         ; dtto
        jsr _wait_vsync         ; dtto
 
        jsr draw_at_y
        dey                     ; vertikální posun
        jmp loop
 
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
.proc   _wait_vsync
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Ovládání spritu joystickem

V této chvíli již umíme spritem pohybovat jak horizontálním, tak i vertikálním směrem, takže nám zbývá maličkost – napojit tento kód na programový kód, který zjistí náklon joysticku. Připomeňme si, že náklon je zakódován do čtyřbitového čísla:

  Decimálně                   Binárně
 
       14                       1110
        |                         |
    10  | 6                 1010  | 0110
      \ |/                      \ |/
  11-- 15 ---7           1011-- 1111 --0111
      / |\                      / |\
     9  | 5                 1001  | 0101
        |                         |
       13                       1101

Celá herní smyčka (někdy nazývaná kernel) využívá index registr X pro úschovu x-ové souřadnice spritu a index registr Y pro y-ovou souřadnici. Akumulátor A obsahuje kód s náklonem joysticku, takže výsledkem je relativně dobře čitelný program nevyžadující prakticky žádnou další paměť (pouze několik bajtů na zásobníku):

loop:
        jsr _wait_vsync         ; čekání na vykreslení snímku
        jsr _wait_vsync
 
        lda STICK0              ; čtení joysticku
        cmp #11                 ; je nakloněn doleva?
        bne not_left
        dex                     ; posun hráče doleva
not_left:
        cmp #7                  ; je nakloněn doprava?
        bne not_right
        inx                     ; posun hráče doprava
not_right:
        cmp #14                 ; je nakloněn nahoru?
        bne not_up
        dey                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_up:
        cmp #13                 ; je nakloněn dolů?
        bne not_down
        iny                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_down:
        stx HPOSP0              ; změna pozice prvního hráče
        jmp loop

Čtvrtý demonstrační příklad: ovládání spritu joystickem

V dnešním čtvrtém demonstračním příkladu je ukázáno ovládání spritu (konkrétně prvního hráče) pomocí joysticku. Pro jednoduchost program nereaguje na šikmé směry. Úprava není ve skutečnosti příliš složitá (dokonce lze využít bitové operace) a prozatím ji ponechám na váženém čtenáři:

Pyhyb prvního hráče je nyní řízen joystickem.

Obrázek 10: Pohyb prvního hráče je nyní řízen joystickem.

Autor: tisnik, podle licence: Rights Managed

Pyhyb prvního hráče je nyní řízen joystickem.

Obrázek 11: Pohyb prvního hráče je nyní řízen joystickem.

Autor: tisnik, podle licence: Rights Managed

Pyhyb prvního hráče je nyní řízen joystickem.

Obrázek 12: Pohyb prvního hráče je nyní řízen joystickem.

Autor: tisnik, podle licence: Rights Managed

Zdrojový kód tohoto demonstračního příkladu vypadá takto:

; ---------------------------------------------------------------------
; Ovládání PMG joystickem.
; ---------------------------------------------------------------------
 
.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
MISSILES_OFFSET = 384
 
 
.proc main
        lda #80                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #95                 ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #110                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #125                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #146                ; horizontální pozice první střely
        sta HPOSM0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #144                ; horizontální pozice druhé střely
        sta HPOSM1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #142                ; horizontální pozice třetí střely
        sta HPOSM2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #140                ; horizontální pozice čtvrté střely
        sta HPOSM3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #HUE_YELLOWRED<<4 + 8   ; barva pátého hráče (odstín+intenzita)
        sta COLOR3              ; uložit do řídicího registru COLPF3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #16                 ; priorita hráčů a pozadí -> povolení pátého hráče
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET+50, x  ; uložit byte - první hráč
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        sta addr+MISSILES_OFFSET+50, x  ; uložit byte - střely
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
; zde začíná "herní kernel"
        ldx #80                 ; výchozí pozice prvního hráče
        ldy #60                 ; X i Y
loop:
        jsr _wait_vsync         ; čekání na vykreslení snímku
        jsr _wait_vsync
 
        lda STICK0              ; čtení joysticku
        cmp #11                 ; je nakloněn doleva?
        bne not_left
        dex                     ; posun hráče doleva
not_left:
        cmp #7                  ; je nakloněn doprava?
        bne not_right
        inx                     ; posun hráče doprava
not_right:
        cmp #14                 ; je nakloněn nahoru?
        bne not_up
        dey                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_up:
        cmp #13                 ; je nakloněn dolů?
        bne not_down
        iny                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_down:
        stx HPOSP0              ; změna pozice prvního hráče
        jmp loop
 
.endproc
 
 
.proc   _wait_vsync
        txa                     ; uložení obsahu X do akumulátoru
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        tax                     ; obnovení obsahu X z akumulátoru
        rts
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        txa
        pha                     ; uložit X na zásobník
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        pla
        tax                     ; obnovit X ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Detekce kolizí čipem GTIA

Jak jsme si již řekli v úvodní kapitole, umožňuje čip GTIA detekovat takzvané kolize, tj. překryv pixelů dvou či více hráčů, překryv střely s hráči popř. překryv libovolného spritu s herním polem. Informace o kolizích se zapisují do následujících registrů čipu GTIA. Povšimněte si, že všechny tyto registry jsou určeny pouze pro čtení:

Registr Režim Význam
P0PF R kolizní registr mezi hráčem číslo 0 a herním polem
P1PF R kolizní registr mezi hráčem číslo 1 a herním polem
P2PF R kolizní registr mezi hráčem číslo 2 a herním polem
P3PF R kolizní registr mezi hráčem číslo 3 a herním polem
     
P0PL R kolizní registr mezi hráčem číslo 0 a dalším hráčem
P1PL R kolizní registr mezi hráčem číslo 1 a dalším hráčem
P2PL R kolizní registr mezi hráčem číslo 2 a dalším hráčem
P3PL R kolizní registr mezi hráčem číslo 3 a dalším hráčem
     
M0PF R kolizní registr mezi střelou číslo 0 a herním polem
M1PF R kolizní registr mezi střelou číslo 1 a herním polem
M2PF R kolizní registr mezi střelou číslo 2 a herním polem
M3PF R kolizní registr mezi střelou číslo 3 a herním polem
     
M0PL R kolizní registr mezi střelou číslo 0 a hráčem
M1PL R kolizní registr mezi střelou číslo 1 a hráčem
M2PL R kolizní registr mezi střelou číslo 2 a hráčem
M3PL R kolizní registr mezi střelou číslo 3 a hráčem
Poznámka: informace o kolizích se nenulují. Postup pro vynulování těchto informací je popsán v dalších kapitolách.

Význam jednotlivých bitů v kolizních registrech

Kolize spritu (ať již střely nebo hráče) s herním polem, resp. s libovolnou barvou herního pole je zakódována do čtyř bitů takto:

Bit Význam
0 COLFP0 (první barva)
1 COLFP1 (druhá barva)
2 COLFP2 (třetí barva)
3 COLFP3 (čtvrtá barva)
4 nepoužito
5 nepoužito
6 nepoužito
7 nepoužito

Kolize střely s některým hráčem nebo několika hráči je opět zakódována do čtyř bitů:

Bit Význam
0 COLPM0 (první hráč)
1 COLPM1 (druhý hráč)
2 COLPM2 (třetí hráč)
3 COLPM3 (čtvrtý hráč)
4 nepoužito
5 nepoužito
6 nepoužito
7 nepoužito

Kolize mezi hráči je reprezentována třemi bity (vždy jeden bit není použit):

Bit Význam
0 COLPM0 (první hráč)
1 COLPM1 (druhý hráč)
2 COLPM2 (třetí hráč)
3 COLPM3 (čtvrtý hráč)
4 nepoužito
5 nepoužito
6 nepoužito
7 nepoužito
Poznámka: neexistují ovšem detekce kolize mezi hráčem a střelami (v tomto pořadí) nebo mezi herním polem a střelami či hráči (opět v tomto pořadí). V praxi to však příliš nevadí.

Pátý demonstrační příklad: detekce kolize prvního hráče s dalšími hráči

V dnešním pátém demonstračním příkladu je barva prvního hráče změněna ve chvíli, kdy je detekována jedna kolize nebo větší množství kolizí s jinými hráči. Realizace změny barvy je vlastně velmi jednoduchá – přečteme obsah kolizního registru, převedeme hodnotu na odstín barvy a intenzitu nastavíme na hodnotu 12:

        stx HPOSP0              ; změna pozice prvního hráče
        lda P0PL                ; načíst informace o kolizích prvního hráče
        asl                     ; posun na pozice informace o odstínu
        asl
        asl
        asl
        clc
        adc #12                 ; přidat světlost barvy

Úplný zdrojový kód tohoto demonstračního příkladu vypadá takto:

; ---------------------------------------------------------------------
; Detekce kolize prvního hráče s dalšími hráči
; ---------------------------------------------------------------------
 
.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
MISSILES_OFFSET = 384
 
 
.proc main
        lda #80                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #90                 ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #100                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #110                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #140                ; horizontální pozice první střely
        sta HPOSM0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #144                ; horizontální pozice druhé střely
        sta HPOSM1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #148                ; horizontální pozice třetí střely
        sta HPOSM2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #152                ; horizontální pozice čtvrté střely
        sta HPOSM3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #HUE_YELLOWRED<<4 + 8   ; barva pátého hráče (odstín+intenzita)
        sta COLOR3              ; uložit do řídicího registru COLPF3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #0                  ; priorita hráčů a pozadí
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET+50, x  ; uložit byte - první hráč
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #$55                ; bitmapy střel
        sta addr+MISSILES_OFFSET+55  ; uložit byte - střely
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
; zde začíná "herní kernel"
        ldx #80                 ; výchozí pozice prvního hráče
        ldy #60                 ; X i Y
loop:
        jsr _wait_vsync         ; čekání na vykreslení snímku
        jsr _wait_vsync
        jsr _wait_vsync
        jsr _wait_vsync
 
        lda STICK0              ; čtení joysticku
        cmp #11                 ; je nakloněn doleva?
        bne not_left
        dex                     ; posun hráče doleva
not_left:
        cmp #7                  ; je nakloněn doprava?
        bne not_right
        inx                     ; posun hráče doprava
not_right:
        cmp #14                 ; je nakloněn nahoru?
        bne not_up
        dey                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_up:
        cmp #13                 ; je nakloněn dolů?
        bne not_down
        iny                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_down:
        stx HPOSP0              ; změna pozice prvního hráče
        lda P0PL                ; načíst informace o kolizích prvního hráče
        asl                     ; posun na pozice informace o odstínu
        asl
        asl
        asl
        clc
        adc #12                 ; přidat světlost barvy
 
        sta PCOLR0              ; změnit barvu prvního hráče
 
        jmp loop
.endproc
 
 
.proc   _wait_vsync
        txa                     ; uložení obsahu X do akumulátoru
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        tax                     ; obnovení obsahu X z akumulátoru
        rts
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        txa
        pha                     ; uložit X na zásobník
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        pla
        tax                     ; obnovit X ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Vymazání kolizních registrů

Barva hráče se v předchozím příkladu sice skutečně při kolizi změnila, ale i když hráč „odejel“, zůstala zachována, tj. kolizní registr si stále pamatovat dřívější kolize:

Detekce kolize - bez kolize.

Obrázek 13: Detekce kolize - před kolizí. 

Autor: tisnik, podle licence: Rights Managed

Detekce kolize - stav po kolizi.

Obrázek 14: Detekce kolize - stav při kolizi. 

Autor: tisnik, podle licence: Rights Managed

Detekce kolize - stav po kolizi.

Obrázek 15: Detekce kolize - stav po kolizi. 

Autor: tisnik, podle licence: Rights Managed

Mohlo by se tedy zdát, že postačuje, aby se provedl zápis nuly do kolizního registru a dostaneme výchozí stav. Tak ovšem čip GTIA nefunguje: záznamy o kolizích je nutné vymazat zápisem do řídicího registru HITCLR. Zapsat je možné jakoukoli hodnotu (klidně i nulu) – důležitá je totiž pouze vlastní operace zápisu a nikoli zapisovaná hodnota. V praxi to tedy znamená, že po změně barvy spritu můžeme ihned záznam o kolizi vymazat:

        sta HITCLR              ; vymazat informace o kolizích

Šestý demonstrační příklad: korektní vymazání kolizních registrů

V případě, že do předchozího příkladu (viz jedenáctou kapitolu) vložíme na konec „herní smyčky“ vymazání kolizních registrů, bude hráč reagovat korektně i na situaci, kdy z kolizní situace „odjede“:

Detekce kolize - stav před kolizí.

Obrázek 16: Detekce kolize - stav před kolizí. 

Autor: tisnik, podle licence: Rights Managed

Detekce kolize - kolize.

Obrázek 17: Detekce kolize - kolize. 

Autor: tisnik, podle licence: Rights Managed

Detekce kolize - stav po kolizi.

Obrázek 18: Detekce kolize - stav po kolizi. 

Autor: tisnik, podle licence: Rights Managed

Úprava je snadná; postačuje smyčku ukončit například takto:

        sta PCOLR0              ; změnit barvu prvního hráče
        sta HITCLR              ; vymazat informace o kolizích
 
        jmp loop
Poznámka: opět platí, že je jedno, jaká hodnota se do registru HITCLR zapíše; důležitá je pouze samotná operace zápisu.

Upravený zdrojový kód příkladu nyní bude vypadat následovně:

.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
MISSILES_OFFSET = 384
 
 
.proc main
        lda #80                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #90                 ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #100                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #110                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #140                ; horizontální pozice první střely
        sta HPOSM0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #144                ; horizontální pozice druhé střely
        sta HPOSM1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #148                ; horizontální pozice třetí střely
        sta HPOSM2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #152                ; horizontální pozice čtvrté střely
        sta HPOSM3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #HUE_YELLOWRED<<4 + 8   ; barva pátého hráče (odstín+intenzita)
        sta COLOR3              ; uložit do řídicího registru COLPF3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #0                  ; priorita hráčů a pozadí
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET+50, x  ; uložit byte - první hráč
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #$55                ; bitmapy střel
        sta addr+MISSILES_OFFSET+55  ; uložit byte - střely
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
; zde začíná "herní kernel"
        ldx #80                 ; výchozí pozice prvního hráče
        ldy #60                 ; X i Y
loop:
        jsr _wait_vsync         ; čekání na vykreslení snímku
        jsr _wait_vsync
        jsr _wait_vsync
        jsr _wait_vsync
 
        lda STICK0              ; čtení joysticku
        cmp #11                 ; je nakloněn doleva?
        bne not_left
        dex                     ; posun hráče doleva
not_left:
        cmp #7                  ; je nakloněn doprava?
        bne not_right
        inx                     ; posun hráče doprava
not_right:
        cmp #14                 ; je nakloněn nahoru?
        bne not_up
        dey                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_up:
        cmp #13                 ; je nakloněn dolů?
        bne not_down
        iny                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_down:
        stx HPOSP0              ; změna pozice prvního hráče
        lda P0PL                ; načíst informace o kolizích prvního hráče
        asl                     ; posun na pozice informace o odstínu
        asl
        asl
        asl
        clc
        adc #12                 ; přidat světlost barvy
 
        sta PCOLR0              ; změnit barvu prvního hráče
        sta HITCLR              ; vymazat informace o kolizích
 
        jmp loop
 
.endproc
 
 
.proc   _wait_vsync
        txa                     ; uložení obsahu X do akumulátoru
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        tax                     ; obnovení obsahu X z akumulátoru
        rts
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        txa
        pha                     ; uložit X na zásobník
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        pla
        tax                     ; obnovit X ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Kolize střel s hráči

Připomeňme si, že čip GTIA nabízí čtyři možnosti detekce kolizí:

  1. Kolize mezi hráči.
  2. Kolize mezi hráčem a herním polem.
  3. Kolize mezi střelou a hráčem.
  4. Kolize mezi střelou a herním polem.

Z těchto čtyř možností lze odvodit i další kombinace, tedy například kolizi hráče s libovolnou střelou atd. My si ovšem ukážeme způsob detekce kolize první střely s libovolným hráčem. Tato kolize a kolize s případnými dalšími hráči je při detekci uložena do registru M0PL:

Bit Význam
0 COLPM0 (první hráč)
1 COLPM1 (druhý hráč)
2 COLPM2 (třetí hráč)
3 COLPM3 (čtvrtý hráč)
4 nepoužito
5 nepoužito
6 nepoužito
7 nepoužito

Sedmý demonstrační příklad: detekce kolize první střely s hráči

Pokusme se nyní barvu prvního hráče nastavit podle toho, zda první střela (nikoli hráč!) detekuje nějakou kolizi či kolize s libovolnou kombinací hráčů. K výpočtu barvy přičteme ještě hodnotu kolizního registru M0PL:

        stx HPOSP0              ; změna pozice prvního hráče
        lda P0PL                ; načíst informace o kolizích prvního hráče
        clc
        adc M0PL
        asl                     ; posun na pozice informace o odstínu
        asl
        asl
        asl
        clc
        adc #12                 ; přidat světlost barvy
 
        sta PCOLR0              ; změnit barvu prvního hráče
        sta HITCLR              ; vymazat informace o kolizích

Výsledky vypadají takto:

Kolize hráče se střelou - stav před kolizí.

Obrázek 19: Kolize hráče se střelou - stav před kolizí. 

Autor: tisnik, podle licence: Rights Managed

Kolize hráče se střelou - stav v době kolize.

Obrázek 20: Kolize hráče se střelou - stav v době kolize. 

Autor: tisnik, podle licence: Rights Managed

Pochopitelně si opět ukážeme úplný zdrojový kód tohoto demonstračního příkladu:

; ---------------------------------------------------------------------
; Ovládání PMG joystickem. Detekce kolize prvního hráče s dalšími hráči.
; Detekce kolize první střely s hráči.
; ---------------------------------------------------------------------
 
.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
MISSILES_OFFSET = 384
 
 
.proc main
        lda #80                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #90                 ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #100                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #110                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #140                ; horizontální pozice první střely
        sta HPOSM0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #144                ; horizontální pozice druhé střely
        sta HPOSM1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #148                ; horizontální pozice třetí střely
        sta HPOSM2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #152                ; horizontální pozice čtvrté střely
        sta HPOSM3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #HUE_YELLOWRED<<4 + 8   ; barva pátého hráče (odstín+intenzita)
        sta COLOR3              ; uložit do řídicího registru COLPF3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #0                  ; priorita hráčů a pozadí
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET+50, x  ; uložit byte - první hráč
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #$55                ; bitmapy střel
        sta addr+MISSILES_OFFSET+55  ; uložit byte - střely
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
; zde začíná "herní kernel"
        ldx #80                 ; výchozí pozice prvního hráče
        ldy #60                 ; X i Y
loop:
        jsr _wait_vsync         ; čekání na vykreslení snímku
        jsr _wait_vsync
        jsr _wait_vsync
        jsr _wait_vsync
 
        lda STICK0              ; čtení joysticku
        cmp #11                 ; je nakloněn doleva?
        bne not_left
        dex                     ; posun hráče doleva
not_left:
        cmp #7                  ; je nakloněn doprava?
        bne not_right
        inx                     ; posun hráče doprava
not_right:
        cmp #14                 ; je nakloněn nahoru?
        bne not_up
        dey                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_up:
        cmp #13                 ; je nakloněn dolů?
        bne not_down
        iny                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_down:
        stx HPOSP0              ; změna pozice prvního hráče
        lda P0PL                ; načíst informace o kolizích prvního hráče
        clc
        adc M0PL
        asl                     ; posun na pozice informace o odstínu
        asl
        asl
        asl
        clc
        adc #12                 ; přidat světlost barvy
 
        sta PCOLR0              ; změnit barvu prvního hráče
        sta HITCLR              ; vymazat informace o kolizích
 
        jmp loop
 
.endproc
 
 
.proc   _wait_vsync
        txa                     ; uložení obsahu X do akumulátoru
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        tax                     ; obnovení obsahu X z akumulátoru
        rts
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        txa
        pha                     ; uložit X na zásobník
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        pla
        tax                     ; obnovit X ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Kolize spritů s prvky herního pole

Na závěr se ještě, prozatím ovšem v krátkosti, přesvědčíme, že je možné detekovat kolizi spritu (hráče nebo střely) s herním polem. Tyto kolize se zapisují do registrů, jejichž jména končí na PF, tedy do PxPF a MxPF. Význam jednotlivých bitů těchto registrů je následující:

Bit Význam
0 COLFP0 (první barva)
1 COLFP1 (druhá barva)
2 COLFP2 (třetí barva)
3 COLFP3 (čtvrtá barva)
4 nepoužito
5 nepoužito
6 nepoužito
7 nepoužito
Poznámka: konkrétní chování závisí na použitém grafickém režimu, což je ovšem poměrně komplexní téma, kterému se budeme věnovat příště. Dnes si pouze ukážeme kolizi prvního hráče s „kurzorem“, což je ve skutečnosti znak mezery vykreslený inverzně. Hráč se při překryvu s kurzorem (znakem) obarví odlišnou barvou:
lda P0PL       ; načíst informace o kolizích prvního hráče
clc
adc M0PL
clc
adc P0PF
asl            ; posun na pozice informace o odstínu
asl
asl
asl
clc
adc #12        ; přidat světlost barvy

Osmý demonstrační příklad: realizace detekce kolize hráče s herním polem

V osmém a dnes již současně posledním demonstračním příkladu je ukázán způsob detekce kolize spritu s herním polem, konkrétně detekce dotyku či překryvu prvního hráče se znakem kurzoru. Povšimněte si, že výpočet kolize je skutečně proveden s pixelovou přesností:

Kolize hráče s herním polem - stav před kolizí.

Obrázek 21: Kolize hráče s herním polem - stav před kolizí. 

Autor: tisnik, podle licence: Rights Managed

Kolize hráče s herním polem - kolize.

Obrázek 22: Kolize hráče s herním polem - kolize.

Autor: tisnik, podle licence: Rights Managed

Kolize hráče s herním polem - ukázka přesnosti detekce kolize na jednotlivé pixely.

Obrázek 23: Kolize hráče s herním polem - ukázka přesnosti detekce kolize na jednotlivé pixely.

Autor: tisnik, podle licence: Rights Managed

Úplný zdrojový kód tohoto demonstračního příkladu je již relativně dlouhý, ovšem výsledek (binární soubor pro emulátor) je stále kratší, než 256 bajtů:

.include "atari.inc"
 
.CODE
 
PLAYER_0_OFFSET = 512
PLAYER_1_OFFSET = PLAYER_0_OFFSET + 128
PLAYER_2_OFFSET = PLAYER_1_OFFSET + 128
PLAYER_3_OFFSET = PLAYER_2_OFFSET + 128
MISSILES_OFFSET = 384
 
 
.proc main
        lda #60                 ; horizontální pozice prvního hráče
        sta HPOSP0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #90                 ; horizontální pozice druhého hráče
        sta HPOSP1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #100                ; horizontální pozice třetího hráče
        sta HPOSP2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #110                ; horizontální pozice čtvrtého hráče
        sta HPOSP3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #140                ; horizontální pozice první střely
        sta HPOSM0              ; uložit do řídicího registru HPOSP0 na čipu GTIA
 
        lda #144                ; horizontální pozice druhé střely
        sta HPOSM1              ; uložit do řídicího registru HPOSP1 na čipu GTIA
 
        lda #148                ; horizontální pozice třetí střely
        sta HPOSM2              ; uložit do řídicího registru HPOSP2 na čipu GTIA
 
        lda #152                ; horizontální pozice čtvrté střely
        sta HPOSM3              ; uložit do řídicího registru HPOSP3 na čipu GTIA
 
        lda #HUE_GREEN<<4 + 12  ; barva prvního hráče (odstín+intenzita)
        sta PCOLR0              ; uložit do řídicího registru PCOLR0 na čipu GTIA
 
        lda #HUE_YELLOW<<4 + 12 ; barva druhého hráče (odstín+intenzita)
        sta PCOLR1              ; uložit do řídicího registru PCOLR1 na čipu GTIA
 
        lda #HUE_MAGENTA<<4 + 12 ; barva třetího hráče (odstín+intenzita)
        sta PCOLR2              ; uložit do řídicího registru PCOLR2 na čipu GTIA
 
        lda #HUE_CYAN<<4 + 12   ; barva čtvrtého hráče (odstín+intenzita)
        sta PCOLR3              ; uložit do řídicího registru PCOLR3 na čipu GTIA
 
        lda #HUE_YELLOWRED<<4 + 8   ; barva pátého hráče (odstín+intenzita)
        sta COLOR3              ; uložit do řídicího registru COLPF3 na čipu GTIA
 
        lda #3                  ; bitové pole: povolení hráčů i střel
        sta GRACTL              ; uložit do řídicího registru GRACTL na čipu GTIA
 
        lda #0                  ; priorita hráčů a pozadí
        sta GPRIOR              ; uložit do řídicího registru GPRIOR na čipu GTIA
 
        lda #152                ; paměťová stránka číslo 152
        sta PMBASE
 
        addr = 152*256
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET+10, x  ; uložit byte - první hráč
        sta addr+PLAYER_1_OFFSET+50, x  ; uložit byte - druhý hráč
        sta addr+PLAYER_2_OFFSET+50, x  ; uložit byte - třetí hráč
        sta addr+PLAYER_3_OFFSET+50, x  ; uložit byte - čtvrtý hráč
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        lda #$55                ; bitmapy střel
        sta addr+MISSILES_OFFSET+55  ; uložit byte - střely
 
        lda #46                 ; povolení PMG DMA
        sta SDMCTL
 
; zde začíná "herní kernel"
        ldx #60                 ; výchozí pozice prvního hráče
        ldy #20                 ; X i Y
loop:
        jsr _wait_vsync         ; čekání na vykreslení snímku
        jsr _wait_vsync
        jsr _wait_vsync
        jsr _wait_vsync
 
        lda STICK0              ; čtení joysticku
        cmp #11                 ; je nakloněn doleva?
        bne not_left
        dex                     ; posun hráče doleva
not_left:
        cmp #7                  ; je nakloněn doprava?
        bne not_right
        inx                     ; posun hráče doprava
not_right:
        cmp #14                 ; je nakloněn nahoru?
        bne not_up
        dey                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_up:
        cmp #13                 ; je nakloněn dolů?
        bne not_down
        iny                     ; změna Y-ové souřadnice hráče
        jsr draw_at_y           ; překreslení spritu
not_down:
        stx HPOSP0              ; změna pozice prvního hráče
        lda P0PL                ; načíst informace o kolizích prvního hráče
        clc
        adc M0PL
        clc
        adc P0PF
        asl                     ; posun na pozice informace o odstínu
        asl
        asl
        asl
        clc
        adc #12                 ; přidat světlost barvy
 
        sta PCOLR0              ; změnit barvu prvního hráče
        sta HITCLR              ; vymazat informace o kolizích
 
        jmp loop
 
.endproc
 
 
.proc   _wait_vsync
        txa                     ; uložení obsahu X do akumulátoru
        ldx     RTCLOK+2        ; čekání na konec snímku
@wt:    cpx     RTCLOK+2
        beq     @wt
        tax                     ; obnovení obsahu X z akumulátoru
        rts
.endproc
 
 
.proc  draw_at_y
        addr = 152*256          ; adresa první stránky se sprity
        txa
        pha                     ; uložit X na zásobník
        tya
        pha                     ; uložit Y na zásobník
 
        ldx #10                 ; začneme na hodnotě o 1 vyšší
next_line:
        lda sprite-1, x         ; načíst
        sta addr+PLAYER_0_OFFSET, y  ; uložit byte - první hráč
        dey
        dex                     ; snížit offset + nastavit příznaky
        bne next_line           ; další byte spritu
 
        pla
        tay                     ; obnovit Y ze zásobníku
        pla
        tax                     ; obnovit X ze zásobníku
        rts                     ; návrat z podprogramu
.endproc
 
 
; data
sprite:   .byte 0, 24, 60, 126, 219, 255, 36, 90, 165, 0
 
end:
 
 
.segment "EXEHDR"
.word   $ffff                   ; uvodni sekvence bajtu v souboru XEX
.word   main                    ; zacatek kodoveho segmentu
.word   end - 1                 ; konec kodoveho segmentu
 
 
.segment "AUTOSTRT"             ; segment s pocatecni adresou
.word   RUNAD                   ; naplni se pouze adresy RUNAD a RUNAD+1
.word   RUNAD+1
.word   main                    ; adresa vstupniho bodu do programu
 
; finito

Příloha: Makefile pro překlad všech demonstračních příkladů

Všechny minule i dnes popsané demonstrační příklady, pro jejichž překlad je zapotřebí použít assembler ca65 a linker ld65, je možné přeložit s využitím souboru Makefile, jehož obsah je vypsán pod tímto odstavcem:

školení AI

execs := dummy.xex print_a.xex \
         background_color_1.xex  background_color_2.xex \
         color_computation_1.xex color_computation_2.xex \
         subroutine_1.xex        subroutine_2.xex \
         hex_number_1.xex        hex_number_2.xex \
         hex_number_3.xex        hex_number_4.xex \
         hex_number_5.xex        hex_number_6.xex \
         hex_number_7.xex        hex_number_8.xex \
         hex_number_9.xex \
         fill_block_1.xex        fill_block_2.xex \
         fill_block_3.xex        fill_block_4.xex \
         fill_block_5.xex \
         pmg_01.xex              pmg_02.xex \
         pmg_03.xex              pmg_04.xex \
         pmg_05.xex              pmg_06.xex \
         pmg_07.xex              pmg_08.xex \
         pmg_09.xex              pmg_10.xex \
         pmg_11.xex              pmg_12.xex \
         pmg_13.xex              pmg_14.xex \
         pmg_15.xex \
         pmg_stick_1.xex         pmg_stick_2.xex \
         pmg_stick_3.xex         pmg_stick_4.xex \
         pmg_stick_5.xex         pmg_stick_6.xex \
         pmg_collisions_1.xex    pmg_collisions_2.xex \
         pmg_collisions_3.xex    pmg_collisions_4.xex
 
all: $(execs)
 
clean:
        rm -f *.o
        rm -f *.xex
 
.PHONY: all clean
 
%.o: %.asm
        ca65 $< -t atari -o $@ -l $(basename $<)_list.asm --list-bytes 100
 
%.xex: %.o
        ld65 -C linker.cfg $< -o $@ -m $(basename $<).map

Výsledkem překladu jsou soubory s koncovkou .xex, které je možné přímo spustit v emulátoru osmibitových počítačů Atari.

Repositář s demonstračními příklady

Všechny demonstrační příklady, s nimiž jsme se v předchozích článcích i v článku dnešním seznámili a které jsou určeny pro překlad s využitím assembleru ca65, jsou dostupné, jak je zvykem, na GitHubu. V tabulce níže jsou uvedeny odkazy na jednotlivé zdrojové kódy příkladů psané v assembleru i „listingy“ vygenerované samotným assemblerem, ze kterých je patrné, jakým způsobem se jednotlivé příklady přeložily do výsledného XEX souboru:

# Příklad Stručný popis příkladu Adresa
1 Makefile definice cílů pro překlad všech demonstračních příkladů z této tabulky https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/Makefile
2 linker.cfg konfigurační soubor pro linker https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/linker.cfg
       
3 dummy.asm pouze nekonečná smyčka https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/dummy.asm
4 dummy_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/dummy_list.asm
5 dummy_list.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/dummy.map
       
6 background_color1.asm změna barvy pozadí – základní varianta příkladu https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color1.asm
7 background_color1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color1_list.asm
8 background_color1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color1.map
       
9 background_color2.asm změna barvy pozadí – využití předdefinovaných konstant https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color2.asm
10 background_color2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color2_list.asm
11 background_color2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/background_color2.map
       
12 print_a.asm tisk znaku přímo do obrazové paměti https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/print_a.asm
13 print_a_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/print_a_list.asm
14 print_a.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/print_a.map
       
15 color_computation1.asm výpočet barvy, varianta bez bitových posunů https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/color_computation1.asm
16 color_computation1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/color_computation1_list.asm
17 color_computation1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/color_computation1.map
       
18 color_computation2.asm výpočet barvy, varianta s bitovými posuny https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/color_computation2.asm
19 color_computation2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/color_computation2_list.asm
20 color_computation2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/color_computation2.map
       
21 subroutine1.asm skok do podprogramu bez předávání parametrů https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/subroutine1.asm
22 subroutine1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/subroutine1_list.asm
23 subroutine1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/subroutine1.map
       
24 subroutine2.asm skok do podprogramu s předáním parametru https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/subroutine2.asm
25 subroutine2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/subroutine2_list.asm
26 subroutine2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/subroutine2.map
       
27 hex_number1.asm tisk jedné hexadecimální číslice (nekorektní varianta) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number1.asm
28 hex_number1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number1_list.asm
29 hex_number1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number1.map
       
30 hex_number2.asm tisk jedné hexadecimální číslice (korektní varianta) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number2.asm
31 hex_number2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number2_list.asm
32 hex_number2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number2.map
       
33 hex_number3.asm tisk jedné hexadecimální číslice (korektní varianta po refaktoringu) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number3.asm
34 hex_number3_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number3_list.asm
35 hex_number3.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number3.map
       
36 hex_number4.asm tisk jedné hexadecimální číslice, varianta postavená na makrech https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number4.asm
37 hex_number4_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number4_list.asm
38 hex_number4.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number4.map
       
39 hex_number5.asm tisk jedné hexadecimální číslice, varianta postavená na makrech, lokální automaticky generovaná návěští https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number5.asm
40 hex_number5_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number5_list.asm
41 hex_number5.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number5.map
       
42 hex_number6.asm příprava pro tisk dvouciferné hexadecimální hodnoty https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number6.asm
43 hex_number6_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number6_list.asm
44 hex_number6.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number6.map
       
45 hex_number7.asm realizace tisku dvouciferné hexadecimální hodnoty https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number7.asm
46 hex_number7_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number7_list.asm
47 hex_number7.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number7.map
       
48 hex_number8.asm makro pro logický posun doprava o zadaný počet bitů https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number8.asm
49 hex_number8_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number8_list.asm
50 hex_number8.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number8.map
       
51 hex_number9.asm čekání na stisk klávesy https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number8.asm
52 hex_number9_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number8_list.asm
53 hex_number9.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/hex_number8.map
       
54 fill_block1.asm vyplnění bloku, varianta se dvěma index registry https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block1.asm
55 fill_block1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block1_list.asm
56 fill_block1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block1.map
       
57 fill_block2.asm vyplnění bloku, nekorektní varianta využívající jeden index registr https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block2.asm
58 fill_block2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block2_list.asm
59 fill_block2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block2.map
       
60 fill_block3.asm vyplnění bloku, korektní varianta využívající jeden index registr https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block3.asm
61 fill_block3_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block3_list.asm
62 fill_block3.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block3.map
       
63 fill_block4.asm vyplnění bloku delšího než 256 bajtů https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block4.asm
64 fill_block4_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block4_list.asm
65 fill_block4.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block4.map
       
66 fill_block5.asm vyplnění bloku, čítání směrem nahoru https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block5.asm
67 fill_block5_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block5_list.asm
68 fill_block5.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/fill_block5.map
       
69 pmg01.asm inicializace PMG, povolení PMG, nastavení pozice a tvaru prvního hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg01.asm
70 pmg01_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg01_list.asm
71 pmg01.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg01.map
       
72 pmg02.asm nastavení pozice, tvaru a barvy prvního hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg02.asm
73 pmg02_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg02_list.asm
74 pmg02.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg02.map
       
75 pmg03.asm vliv zákazu DMA na zobrazení PMG https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg03.asm
76 pmg03_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg03_list.asm
77 pmg03.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg03.map
       
78 pmg04.asm postupná změna horizontální velikosti hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg04.asm
79 pmg04_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg04_list.asm
80 pmg04.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg04.map
       
81 pmg05.asm odlišná bitová maska tvaru hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg05.asm
82 pmg05_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg05_list.asm
83 pmg05.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg05.map
       
84 pmg06.asm inicializace a zobrazení dvou hráčů, kteří se překrývají https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg06.asm
84 pmg06_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg06_list.asm
86 pmg06.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg06.map
       
87 pmg07.asm naivní způsob nastavení bitmapy prvního hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg07.asm
88 pmg07_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg07_list.asm
89 pmg07.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg07.map
       
90 pmg08.asm elegantnější způsob nastavení bitmapy prvního hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg08.asm
91 pmg08_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg08_list.asm
92 pmg08.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg08.map
       
93 pmg09.asm zobrazení všech čtyř hráčů, změna priority zobrazení https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg09.asm
94 pmg09_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg09_list.asm
95 pmg09.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg09.map
       
96 pmg10.asm nastavení bitmap všech čtyř hráčů https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg10.asm
97 pmg10_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg10_list.asm
98 pmg10.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg10.map
       
99 pmg_stick1.asm ovládání prvního hráče joystickem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick1.asm
100 pmg_stick1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick1_list.asm
101 pmg_stick1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick1.map
       
102 pmg_stick2.asm zobrazení všech čtyř střel https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick2.asm
103 pmg_stick2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick2_list.asm
104 pmg_stick2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick2.map
       
105 pmg_stick3.asm střely zdánlivě tvoří pátého hráče (ovšem stále jsou samostatné) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick3.asm
106 pmg_stick3_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick3_list.asm
107 pmg_stick3.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick3.map
       
108 pmg_stick4.asm korektní zobrazení pátého hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick4.asm
109 pmg_stick4_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick4_list.asm
110 pmg_stick4.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick4.map
       
111 pmg_stick5.asm detekce stisku tlačítka joysticku, změna barvy prvního hráče https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick5.asm
112 pmg_stick5_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick5_list.asm
113 pmg_stick5.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick5.map
       
114 pmg11.asm automatický horizontální pohyb prvního hráče, realizace zpožďovací smyčky https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg11.asm
115 pmg11_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg11_list.asm
116 pmg11.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg11.map
       
117 pmg12.asm automatický horizontální pohyb prvního hráče, čekání na další snímek https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg12.asm
118 pmg12_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg12_list.asm
119 pmg12.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg12.map
       
120 pmg13.asm vertikální posun spritu směrem dolů (nekorektní varianta) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg13.asm
121 pmg13_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg13_list.asm
122 pmg13.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg13.map
       
123 pmg14.asm vertikální posun spritu směrem dolů (korektní varianta) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg14.asm
124 pmg14_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg14_list.asm
125 pmg14.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg14.map
       
126 pmg15.asm vertikální posun spritu směrem nahoru (korektní varianta) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg15.asm
127 pmg15_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg15_list.asm
128 pmg15.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg15.map
       
129 pmg_stick6.asm ovládání PMG joystickem v horizontálním i vertikálním směru https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick6.asm
130 pmg_stick6_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick6_list.asm
131 pmg_stick6.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_stick6.map
       
132 pmg_collision1.asm ovládání PMG joystickem, detekce kolize prvního hráče s dalšími hráči https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision1.asm
133 pmg_collision1_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision1_list.asm
134 pmg_collision1.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision1.map
       
135 pmg_collision2.asm ovládání PMG joystickem, detekce kolize prvního hráče s dalšími hráči https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision2.asm
136 pmg_collision2_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision2_list.asm
137 pmg_collision2.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision2.map
       
138 pmg_collision3.asm ovládání PMG joystickem, detekce kolize prvního hráče s dalšími hráči, detekce kolize první střely s hráči https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision3.asm
139 pmg_collision3_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision3_list.asm
140 pmg_collision3.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision3.map
       
141 pmg_collision4.asm ovládání PMG joystickem, detekce kolize prvního hráče s hracím polem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision4.asm
142 pmg_collision4_list.asm „listing“ vygenerovaný assemblerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision4_list.asm
143 pmg_collision4.map mapa paměti; soubor vytvořený linkerem https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/pmg_collision4.map
       
144 chars.bas tisk všech znaků na obrazovku (varianta naprogramovaná v BASICu) https://github.com/tisnik/8bit-fame/blob/master/Atari800-ca65/chars.bas

Odkazy na Internetu

  1. MOS 6502 instruction set
    http://www.6502.org/users/o­belisk/6502/instructions.html
  2. EXE File Format Description
    https://gury.atari8.info/ref­s/file_formats_exe.php
  3. XEX Filter – A toolkit to analyze and manipulate Atari binary files
    https://www.vitoco.cl/atari/xex-filter/index.html
  4. chkxex.py
    https://raw.githubusercon­tent.com/seban-slt/tcx_tools/refs/heads/mas­ter/chkxex.py
  5. ca65 Users Guide
    https://cc65.github.io/doc/ca65.html
  6. cc65 Users Guide
    https://cc65.github.io/doc/cc65.html
  7. ld65 Users Guide
    https://cc65.github.io/doc/ld65.html
  8. da65 Users Guide
    https://cc65.github.io/doc/da65.html
  9. Překladače jazyka C pro historické osmibitové mikroprocesory
    https://www.root.cz/clanky/prekladace-jazyka-c-pro-historicke-osmibitove-mikroprocesory/
  10. Překladače programovacího jazyka C pro historické osmibitové mikroprocesory (2)
    https://www.root.cz/clanky/prekladace-programovaciho-jazyka-c-pro-historicke-osmibitove-mikroprocesory-2/
  11. Getting Started Programming in C: Coding a Retro Game with C Part 2
    https://retrogamecoders.com/getting-started-with-c-cc65/
  12. NES game development in 6502 assembly – Part 1
    https://kibrit.tech/en/blog/nes-game-development-part-1
  13. NES 6502 Programming Tutorial – Part 1: Getting Started
    https://dev.xenforo.relay­.cool/index.php?threads/nes-6502-programming-tutorial-part-1-getting-started.858389/
  14. Minimal NES example using ca65
    https://github.com/bbbradsmith/NES-ca65-example
  15. List of 6502-based Computers and Consoles
    https://www.retrocompute.co.uk/list-of-6502-based-computers-and-consoles/
  16. 6502 – the first RISC µP
    http://ericclever.com/6500/
  17. 3 Generations of Game Machine Architecture
    http://www.atariarchives.or­g/dev/CGEXPO99.html
  18. “Hello, world” from scratch on a 6502 — Part 1
    https://www.youtube.com/wat­ch?v=LnzuMJLZRdU
  19. A Tour of 6502 Cross-Assemblers
    https://bumbershootsoft.wor­dpress.com/2016/01/31/a-tour-of-6502-cross-assemblers/
  20. Adventures with ca65
    https://atariage.com/forum­s/topic/312451-adventures-with-ca65/
  21. example ca65 startup code
    https://atariage.com/forum­s/topic/209776-example-ca65-startup-code/
  22. 6502 PRIMER: Building your own 6502 computer
    http://wilsonminesco.com/6502primer/
  23. 6502 Instruction Set
    https://www.masswerk.at/6502/6502_in­struction_set.html
  24. Chip Hall of Fame: MOS Technology 6502 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor
  25. Single-board computer
    https://en.wikipedia.org/wiki/Single-board_computer
  26. www.6502.org
    http://www.6502.org/
  27. 6502 PRIMER: Building your own 6502 computer – clock generator
    http://wilsonminesco.com/6502pri­mer/ClkGen.html
  28. Great Microprocessors of the Past and Present (V 13.4.0)
    http://www.cpushack.com/CPU/cpu.html
  29. Jak se zrodil procesor?
    https://www.root.cz/clanky/jak-se-zrodil-procesor/
  30. Osmibitové mikroprocesory a mikrořadiče firmy Motorola (1)
    https://www.root.cz/clanky/osmibitove-mikroprocesory-a-mikroradice-firmy-motorola-1/
  31. Mikrořadiče a jejich použití v jednoduchých mikropočítačích
    https://www.root.cz/clanky/mikroradice-a-jejich-pouziti-v-jednoduchych-mikropocitacich/
  32. Mikrořadiče a jejich aplikace v jednoduchých mikropočítačích (2)
    https://www.root.cz/clanky/mikroradice-a-jejich-aplikace-v-jednoduchych-mikropocitacich-2/
  33. 25 Microchips That Shook the World
    https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world
  34. Comparison of instruction set architectures
    https://en.wikipedia.org/wi­ki/Comparison_of_instructi­on_set_architectures
  35. How To Start Learning Atari 8 Bit Assembly For Free
    https://forums.atariage.com/to­pic/300732-how-to-start-learning-atari-8-bit-assembly-for-free/
  36. WUDSN (Demo Group)
    https://www.wudsn.com/
  37. Machine Language For Beginners
    https://www.atariarchives.org/mlb/
  38. Assembly language: all about I/O
    https://www.atarimagazines­.com/v3n8/AllAbout_IO.html
  39. Sedmdesátiny assemblerů: lidsky čitelný strojový kód
    https://www.root.cz/clanky/sed­mdesatiny-assembleru-lidsky-citelny-strojovy-kod/
  40. Color names
    https://atariwiki.org/wiki/Wi­ki.jsp?page=Color%20names
  41. ATASCII
    https://en.wikipedia.org/wiki/ATASCII
  42. Put characters in display ram isn't ATASCII?
    https://forums.atariage.com/to­pic/359973-put-characters-in-display-ram-isnt-atascii/
  43. ATASCII And Internal Character Code Values
    https://www.atariarchives­.org/mapping/appendix10.php
  44. Reading ATASCII from the keyboard in assembly
    https://forums.atariage.com/to­pic/361733-reading-atascii-from-the-keyboard-in-assembly/
  45. Why does the 6502 JSR instruction only increment the return address by 2 bytes?
    https://retrocomputing.stac­kexchange.com/questions/19543/why-does-the-6502-jsr-instruction-only-increment-the-return-address-by-2-bytes
  46. Pushing return address to stack off by 1 byte
    https://forums.atariage.com/to­pic/378206-pushing-return-address-to-stack-off-by-1-byte/
  47. Intel x86 documentation has more pages than the 6502 has transistors
    https://www.righto.com/2013/09/intel-x86-documentation-has-more-pages.html
  48. Clearing a Section of Memory
    http://www.6502.org/source/ge­neral/clearmem.htm
  49. Practical Memory Move Routines by Bruce Clark
    http://www.6502.org/source/ge­neral/memory_move.html
  50. 6502 Assembly Programming Guide
    https://neumont-gamedev.github.io/posts/retrogamedev-6502-guide/
  51. Off-by-one error
    https://en.wikipedia.org/wiki/Off-by-one_error
  52. 6502 cycle times
    https://www.nesdev.org/wi­ki/6502_cycle_times
  53. Atari TIA
    http://www.atarihq.com/danb/tia.shtml
  54. TIA Playfield
    http://www.atarihq.com/dan­b/TIA/Playfield.shtml
  55. Atari Inc.:
    ANTIC C012296 (NTSC) Revision D
    Atari Incorporated, Sunnyvale CA, 1982
  56. Atari Inc.:
    GTIA C014805 (NTSC) Revision A
    Atari Incorporated, Sunnyvale CA, 1982
  57. Atari 5200
    http://www.atariage.com/sof­tware_search.html?SystemID=5200
  58. Atari 5200 Hardware and Accessories
    http://www.atariage.com/5200/ar­chives/hardware.html
  59. Atari 5200 Screenshots
    http://www.atariage.com/sys­tem_items.html?SystemID=5200&I­temTypeID=SCREENSHOT
  60. History of video game consoles (second generation): Wikipedia
    http://en.wikipedia.org/wi­ki/History_of_video_game_con­soles_(second_generation)
  61. Atari 5200: Wikipedia
    http://en.wikipedia.org/wi­ki/Atari_5200
  62. Player-Missile Graphics
    https://www.atariarchives­.org/agagd/chapter5.php
  63. Sprite (computer graphics)
    https://en.wikipedia.org/wi­ki/Sprite_(computer_graphic­s)
Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.



Nejnovější články