Tak jsem si dnes "pohrál", testoval jsem a psal některé věci po svém
.include "atari.inc"
posXP0=200 ;pameti pozice hracu
posXP1=201
posXP2=202
posXP3=203
posYP0=204
posYP1=205
posYP2=206
posYP3=207
posXM0=208 ;pameti pozice strel
posXM1=209
posXM2=210
posXM3=211
posYM0=212
posYM1=213
posYM2=214
posYM3=215
;-----------------------------------------------------------------------------
XMIN=48
XMAX=200
YMIN=16
YMAX=104
;-----------------------------------------------------------------------------
X0P0=80 ;pocatecni pozice hracu
Y0P0=30
X0P1=100
Y0P1=50
X0P2=120
Y0P2=70
X0P3=140
Y0P3=90
;-----------------------------------------------------------------------------
X0M0=160 ;pocatecni pozice strel
Y0M0=40
X0M1=170
Y0M1=40
X0M2=180
Y0M2=40
X0M3=190
Y0M3=40
;-----------------------------------------------------------------------------
barva0=5*16+8 ;barvy hracu
barva1=12*16+8
barva2=3*16+8
barva3=15*16+8
PM_page=152 ;stranka pro hrace
off_hrac0=512 ;offesety pro hrace
off_hrac1=off_hrac0+128
off_hrac2=off_hrac1+128
off_hrac3=off_hrac2+128
off_strela=384
adr_hrac0= PM_page*256+off_hrac0
adr_hrac1= PM_page*256+off_hrac1
adr_hrac2= PM_page*256+off_hrac2
adr_hrac3= PM_page*256+off_hrac3
adr_strela= PM_page*256+off_strela
.CODE
;==============================================================================
.proc main
jsr sprite_init ; inicializace spritu
lda #3 ; bitové pole: povolení hráčů i střel
sta GRACTL ; rídicí registr GRACTL na čipu GTIA
lda #1 ; priorita hráčů a pozadí
sta GPRIOR ; řídicí registr GPRIOR na čipu GTIA
lda #PM_page ; paměťová stránka pro hrace
sta PMBASE
lda #46 ; povolení PMG DMA
sta SDMCTL
;-----------------------------------------------------------------------------
cyklus:
jsr vsync
;-----------------------------------------------------------------------------
lda STICK0 ; čtení joysticku 0
c00:
cmp #11 ; L0
bne c01
jsr movLP0
c01:
cmp #7 ; R0
bne c02
jsr movRP0
c02:
cmp #14 ; U0
bne c03
jsr movUP0
c03:
cmp #13 ; D0
bne c04
jsr movDP0
c04:
cmp #6 ; RU0
bne c05
jsr movRP0
jsr movUP0
c05:
cmp #5 ; RDU0
bne c06
jsr movRP0
jsr movDP0
c06:
cmp #10 ; LU0
bne c07
jsr movLP0
jsr movUP0
c07:
cmp #9 ; LD0
bne c08
jsr movLP0
jsr movDP0
c08:
;-----------------------------------------------------------------------------
lda STICK1 ; čtení joysticku 1
c10:
cmp #11 ; L1
bne c11
jsr movLP1
c11:
cmp #7 ; R1
bne c12
jsr movRP1
c12:
cmp #14 ; U1
bne c13
jsr movUP1
c13:
cmp #13 ; D1
bne c14
jsr movDP1
c14:
cmp #6 ; RU1
bne c15
jsr movRP1
jsr movUP1
c15:
cmp #5 ; RDU1
bne c16
jsr movRP1
jsr movDP1
c16:
cmp #10 ; LU1
bne c17
jsr movLP1
jsr movUP1
c17:
cmp #9 ; LD1
bne c18
jsr movLP1
jsr movDP1
c18:
;-----------------------------------------------------------------------------
c40: lda STRIG0 ; cteni tlacitka 0
bne c41
lda #barva0+6 ; barva hráče
sta PCOLR0
jmp c43
c41: lda P0PL ;test kolize
beq c42
lda #barva0+4 ; barva hráče
sta PCOLR0
jmp c43
c42: lda #barva0 ; barva hráče
sta PCOLR0
c43:
;-----------------------------------------------------------------------------
c50: lda STRIG1 ; cteni tlacitka 0
bne c51
lda #barva1+6 ; barva hráče
sta PCOLR1
jmp c53
c51: lda P1PL ;test kolize
beq c52
lda #barva1+4 ; barva hráče
sta PCOLR1
jmp c53
c52: lda #barva1 ; barva hráče
sta PCOLR1
c53:
;-----------------------------------------------------------------------------
c60: lda STRIG0 ; cteni tlacitka 0
bne c61
lda #barva2+6 ; barva hráče
sta PCOLR2
jmp c63
c61: lda P2PL ;test kolize
beq c62
lda #barva2+4 ; barva hráče
sta PCOLR2
jmp c63
c62: lda #barva2 ; barva hráče
sta PCOLR2
c63:
;-----------------------------------------------------------------------------
c70: lda STRIG1 ; cteni tlacitka 0
bne c71
lda #barva3+6 ; barva hráče
sta PCOLR3
jmp c73
c71: lda P3PL ;test kolize
beq c72
lda #barva3+4 ; barva hráče
sta PCOLR3
jmp c73
c72: lda #barva3 ; barva hráče
sta PCOLR3
c73:
;-----------------------------------------------------------------------------
c99: sta HITCLR ; vymazat informace o kolizích
jmp cyklus
.endproc
;==============================================================================
.proc movLP0
ldx posXP0 ;nacteno aktualni pozice
cpx #XMIN ;test okraje
beq mKLP0
dex ;posun
stx posXP0 ;ulozeni pozice
stx HPOSP0 ;nastaveni pozice
mKLP0: rts
.endproc
;-----------------------------------------------------------------------------
.proc movRP0
ldx posXP0 ;nacteno aktualni pozice
cpx #XMAX ;test okraje
beq mKRP0
inx ;posun
stx posXP0 ;ulozeni pozice
stx HPOSP0 ;nastaveni pozice
mKRP0: rts
.endproc
;-----------------------------------------------------------------------------
.proc movUP0
pha
ldy posYP0 ;nacteno aktualni pozice
cpy #YMIN ;test okraje
beq mKUP0
dey ;posun
sty posYP0 ;ulozeni pozice
ldx #9 ;pocitadlo
mUP0: lda adr_hrac0+1, y ;nacteni byte
sta adr_hrac0, y ;uložit byte
iny
dex ;snizeni pocitadla
bne mUP0
mKUP0: pla
rts
.endproc
;-----------------------------------------------------------------------------
.proc movDP0
pha
ldy posYP0 ;nacteno aktualni pozice
cpy #YMAX ;test okraje
beq mKDP0
iny ;posun
sty posYP0 ;ulozeni pozice
tya
clc
adc #7
tay
ldx #9 ;pocitadlo
mDP0: lda adr_hrac0-1, y ;nacteni byte
sta adr_hrac0, y ;uložit byte
dey
dex ;snizeni pocitadla
bne mDP0
mKDP0: pla
rts
.endproc
;-----------------------------------------------------------------------------
.proc movLP1
ldx posXP1 ;nacteno aktualni pozice
cpx #XMIN ;test okraje
beq mKLP1
dex ;posun
stx posXP1 ;ulozeni pozice
stx HPOSP1 ;nastaveni pozice
mKLP1: rts
.endproc
;-----------------------------------------------------------------------------
.proc movRP1
ldx posXP1 ;nacteno aktualni pozice
cpx #XMAX ;test okraje
beq mKRP1
inx ;posun
stx posXP1 ;ulozeni pozice
stx HPOSP1 ;nastaveni pozice
mKRP1: rts
.endproc
;-----------------------------------------------------------------------------
.proc movUP1
pha
ldy posYP1 ;nacteno aktualni pozice
cpy #YMIN ;test okraje
beq mKUP1
dey ;posun
sty posYP1 ;ulozeni pozice
ldx #9 ;pocitadlo
mUP1: lda adr_hrac1+1, y ;nacteni byte
sta adr_hrac1, y ;uložit byte
iny
dex ;snizeni pocitadla
bne mUP1
mKUP1: pla
rts
.endproc
;-----------------------------------------------------------------------------
.proc movDP1
pha
ldy posYP1 ;nacteno aktualni pozice
cpy #YMAX ;test okraje
beq mKDP1
iny ;posun
sty posYP1 ;ulozeni pozice
tya
clc
adc #7
tay
ldx #9 ;pocitadlo
mDP1: lda adr_hrac1-1, y ;nacteni byte
sta adr_hrac1, y ;uložit byte
dey
dex ;snizeni pocitadla
bne mDP1
mKDP1: pla
rts
.endproc
;==============================================================================
.proc sprite_init
ldx #X0P0 ; horizontální pozice hráče
stx posXP0
stx HPOSP0 ;
lda #barva0 ; barva hráče
sta PCOLR0 ;
ldx #X0P1 ; horizontální pozice hráče
stx posXP1
stx HPOSP1 ;
lda #barva1 ; barva hráče
sta PCOLR1 ;
ldx #X0P2 ; horizontální pozice hráče
stx posXP2
stx HPOSP2 ;
lda #barva2 ; barva hráče
sta PCOLR2 ;
ldx #X0P3 ; horizontální pozice hráče
stx posXP3
stx HPOSP3 ;
lda #barva3 ; barva hráče
sta PCOLR3 ;
ldx #X0M0 ; horizontální pozice strely
stx posXM0
stx HPOSM0
ldx #X0M1 ; horizontální pozice strely
stx posXM1
stx HPOSM1
ldx #X0M2 ; horizontální pozice strely
stx posXM2
stx HPOSM2
ldx #X0M3 ; horizontální pozice strely
stx posXM3
stx HPOSM3
;-----------------------------------------------------------------------------
ldy #Y0P0
sty posYP0
ldy #Y0P0+7
ldx #8 ; pocet o 1 vyšší
si0: lda sprite0-1, x ; načíst
sta adr_hrac0, y ; uložit byte
dey
dex ; snížit offset + nastavit příznaky
bne si0 ; další byte spritu
;-----------------------------------------------------------------------------
ldy #Y0P1
sty posYP1
ldy #Y0P1+7
ldx #8 ; pocet o 1 vyšší
si1: lda sprite1-1, x ; načíst
sta adr_hrac1, y ; uložit byte
dey
dex ; snížit offset + nastavit příznaky
bne si1 ; další byte spritu
;-----------------------------------------------------------------------------
ldy #Y0P2
sty posYP2
ldy #Y0P2+7
ldx #8 ; pocet o 1 vyšší
si2: lda sprite2-1, x ; načíst
sta adr_hrac2, y ; uložit byte
dey
dex ; snížit offset + nastavit příznaky
bne si2 ; další byte spritu
;-----------------------------------------------------------------------------
ldy #Y0P3
sty posYP3
ldy #Y0P3+7
ldx #8 ; pocet o 1 vyšší
si3: lda sprite3-1, x ; načíst
sta adr_hrac3, y ; uložit byte
dey
dex ; snížit offset + nastavit příznaky
bne si3 ; další byte spritu
;-----------------------------------------------------------------------------
ldy #Y0M0
sty posYM0
ldx #0 ; pocet o 1 vyšší
lda #$ff
sta adr_strela, y ; uložit byte
iny
sta adr_strela, y ; uložit byte
iny
sta adr_strela, y ; uložit byte
iny
sta adr_strela, y ; uložit byte
rts
.endproc
;------------------------------------------------------------------------------
.proc get_key
pg1: lda 53279
cmp #$07
bne pg1
pg2: lda 53279
cmp #$07
beq pg2
rts
.endproc
;------------------------------------------------------------------------------
.proc vsync
ldx RTCLOK+2 ; čekání na konec snímku
vs: cpx RTCLOK+2
beq vs
rts
.endproc
;==============================================================================
sprite0: .byte $81, $99, $bd, $ff, $ff, $bd, $99, $81
sprite1: .byte $81, $99, $a5, $e7, $e7, $a5, $99, $81
sprite2: .byte 24, 60, 126, 219, 255, 36, 90, 165
sprite3: .byte $7e, 60, 126, 219, 255, 36, 90, 255
end:
;-----------------------------------------------------------------------------
; systemove segnmmenty pro XEX
.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
;-----------------------------------------------------------------------------
Pěkné! Líbí se mi ta simulace jakoby mohly sprajty jen po grafickém poli - tj. jako by to bylo připravené pro nějakou hru, např....
Pro zajímavost uvedu "strojákovou" variantu testování joysticku - takto stačí tyto jednoduché bitové testy a i šikmé směry se vyhodnotí automaticky tím, že "matchnou" oba příslušné bity:
lda STICK0 ; čtení joysticku 0
lsr
bcs mc00
jsr movUP0
mc00: lsr
bcs mc01
jsr movDP0
mc01: lsr
bcs mc02
jsr movLP0
mc02: lsr
bcs mc03
jsr movRP0
mc03:
A podobně pro STICK1.
Samozřejmě, že by to šlo ještě přepsat ve stylu vyšších jazyků, tj. mít jen jednu univerzální metodu pro čtení joysticku, volanou dvakrát s hodnotou akumulátoru 0 a 1. Podle mě se to nevyplatí kvůli časové náročnosti všech těch složitějších adresních módů, ale jako cvičení na využití "LDA addr,X", "LDA (zeropage),Y", "JSR (zeropage,Y)" apod. by to mohlo být zajímavé. (ano, ty závorky jsou pokaždé jinak u LDA a JSR, protože jde o jiný výpočet!)
Mimochodem, při hraní si s touto "hrou" jsem zjistil, že emulátor atari800 neumí správně rozeznat stav joysticku s protilehlými tlačítky naráz sepnutými, tj. např. rozezná "up"+"right", ale už nerozezná "up"+"down". To je nepříjemný rozdíl oproti reálnému HW. Obzvlášť když na to člověk spolehne a z lenosti svůj testovací prográmek zakončí následujícím testem (pamětníci vědí, na jaký uživatelův vstup se čeká :) )
...
...
wait4keys: lda STICK0
bne wait4keys
rts
Na obranu své lenosti musím uvést, že když pro autentičtější zážitek člověk píše přímo v monitoru paměti v (emulátoru) Atari a ne v žádném cross-assembleru na PC, tak se podobné rychlé triky hodí. Akorát když pak nezaberou a počítač zatuhne, musí si člověk vzpomenout na úžasný vynález tehdejší doby, tj. že zaseknutý program se řeší (teplým) resetem počítače, protože při něm se NEMAŽE RAM! Ano, počítač zresetuju, z cartridge se znova spustí monitor paměti a normálně pokračuju v ladění svého programu v RAM. Jo, to byly doby... :D
A fungovalo to samozřejmě pro (skoro) všechno, tj. např. i v BASICu: po resetu byl program dál na svém místě. A dokonce i když člověk v BASICu psal nějaké kusy strojáku pomocí příkazů DATA a (pochopitelně) se na první pokus nezdařílo, stačil opět jen reset...
14. 4. 2026, 16:48 editováno autorem komentáře
https://github.com/atari800/atari800/issues/267
Ale díky za popostrčení, pořád jsem to oddaloval, protože jsem chtěl nejdřív naprogramovat to či ono...