HRA

Exolon
Herní styl Platformer (Multi Screen)
Multiplayer Bez multiplayeru
Rok vydání 1987
Programátor Nick Jones
Grafik (Unknown)

INTRO

Programování 512Kb Cartridge - C64 Game System, System 3

Všechny ukázky programu pro C64 jsou psány pro Turboassembler 1.5
turboassembler: https://sourceforge.net/projects/tass64/
manuál : http://tass64.sourceforge.net/

1. Výběr typu, popis a hlavně bez stresu

Při vytváření programů na Commodore 64 se není problém dostat do potíží s pamětí. Externí data lze dotáhnout z diskety či nedej bože z kazety. Existuje ale krásný, dostupný nástroj oplývající pamětí, což jsou cartridge. Formát souboru CRT jste již určitě viděli a mimo jiné, cartridge jsou s námi již od počátku věků počítačů.

Ve zkratce. CRT mohou mít velikost od 8Kb do 512Kb s jednou vyjímkou, a to Easyflash, která má velikost 1Mb. Existuje okolo 20 typů cartridge, kde takřka každá má svůj odlišný formát dat a způsob práce s ní. Ovládání a práce s některými je opravdu na palici.

Má volba padla na „C64 Game System, System3 „ s kapacirou 512Kb, která obsahuje 64 hlaviček a 64 pameťových banků. Vybral jsem jeden z nejčitelnějších a dle mého názoru jednodušších formátů. Kromě toho se jedná o standard, který rozběháte nejen v emulátorech, ale i na skutečné C64 spuštěné klidně přes 1541 Ultimate, kde tuto cartridge namontujete a spustíte naprosto bez problémů. A protože jsme se množstvím hardwarem prokousali vcelku rychle, jdeme na softwarovou část.

2. Jak se CRT chová po startu v Commodore 64

Po resetu nebo zapnutí C64 se cartridge, resp. její bank č.0 namapuje do paměti od adres $8000 do $9FFF. C64 si osahá adresy $8004-$8008 a pokud na těchto adresách nalezne text „CBM80“, z hodnot na adresách $8000 a $8001, resp. $8002 a $8003 složí adresu, na kterou provede skok na adresu v CRT a spustí zde to, co se na této adrese nachází.

3. Schéma CRT a pak už je to ízy pízy ! ( neplést si s ízyfleš )

Pro správnou funkci CRT je nutné (!!) dodržet absolutně přesné datové schéma, jinak se CRT nespustí a nebude funkční. A jak vypadá struktura souboru CRT ? Vždy je to hlavička ( header ) o určité velikosti a následuje bank paměti. ( zde $8000 bytes). Naše CRT se skládá z 64 hlaviček a 64 bloků o velikosti $8000. Vytvoříme si super věcičku, kde pomocí příkazového řádku ve Windows z jednotlivých souborů složíme a uložíme výslednou kartridž.

Jak jsem již psal výše, naše CRT se skládá ze 64 hlaviček a 64 paměťových bloků. Paměťové bloky musí mít vždy přesnou velikost , a to je $8000 bytes. V paměti C64 se vybraný blok „připojí“ od adresy $8000 - $9FFF. Každému bloku předchází hlavička. První blok ( zavaděč ) má hlavičku dlouhou 80 bytů a všechny ostatní banky mají hlavičku dlouhou 16 bytů. A pokud si vytvoříme jak jsem již dříve psal v adresáři pro každou hlavičku a pameť soubor, výpis filesystému může vypadat následovně:

0_head  bin	 80	 ($50)
0_mem   bin	 8192  ($8000)
1_head  bin	 16	 ($10)
1_mem   bin	 8192  ($8000)
2_head  bin	 16
2_mem   bin	 8192
....
63_head bin	 16
63_mem  bin	 8192

V případě, že máme všechny soubory přichystány na disku, můžeme složit celou cartridge pomocí příkazu copy v binárním formátu ve Windows. Vytvoříme soubor : sloz_crt.bat a do něj napíšeme následující příkaz. ( a bude zatraceně dlouhý :) )

copy /b c:/cesta/0_head.bin+c:/cesta/0_mem.bin+c:/cesta/+1_head.bin+c:/cesta/1_mem.bin+c:/cesta/+2_head.bin+c:/cesta/2_mem.bin+ ...................... +c:/cesta/+63_head.bin+c:/cesta/63_mem.bin c:/vystup/cartridge.crt

Cestu si upravíte podle svého umístnění na disku, přeskočil jsem v zápisu banky 3-62, takže je jasné, že zápis bude přes desítky řádků vašeho textového editoru. Ovšem výsledek stojí za to. Příkaz copy s příznakem "/b" - binarní kopírování spojí všechny zadané soubory do jednoho binárního blobu o přesné velikosti CRT catridge a máte hotovo !

4. Přepínání banků

Přepínání banků se provádí na každém typu CRT trochu jinak a zde probíhá přepínání následovně. Pro přepnutí slouží adresy $DE00 - $DE40 a zápisem hodnoty 1 do tohoto rozsahu aktivujete odpovídající bank. Zapíšete-li na adresu $DE05 hodnotu 1, z 512Kb souboru bude dostupný pátý bank. Zápisem hodnoty 0 na adresu se automaticky nastaví jako aktivní bank 0.
! Pozor ! Přepínání jednotlivých banků není okamžitě a pro přepnutí potřebujete pozdržet program pár cyklů

5. Formát hlaviček

Hlavička prvního banku v pořadí ( zde značeno 0 ) má pevně danou strukturu a nic v ní nebudete měnit.

.byte $43,$36,$34,$20,$43,$41,$52,$54,$52,$49,$44,$47,$45,$20,$20,$20
.byte $00,$00,$00,$40,$01,$00,$00,$0F,$00,$01,$00,$00,$00,$00,$00,$00
.byte $43,$36,$34,$47,$53,$20,$43,$61,$72,$74,$72,$69,$64,$67,$65,$00		
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $43,$48,$49,$50,$00,$00,$20,$10,$00,$00,$00,$00,$80,$00,$20,$00 

V této hlavičče dlouhé 80 bytů se nachází textové řetězce „; CRT CARTRIDGE“, „C64GS Cartridge“, ale pro správný chod výsledné CRT vás můžou nechat data klidná.
Hlavičky druhého až šesedáttřetího banku mají formát následovný :

.byte $43,$48,$49,$50,$00,$00,$20,$10,$00,$00,$00,$01,$80,$00,$20,$00

Tyto hlavičky nesou označení banku ke kterému patří na zvýrazněné pozici, takže zde musí v každém souboru být patřičné pořadové číslo změněno. Zde je jasné, proč jsem čísloval banky od hodnoty 0, protože první bank nenese pořadové číslo a druhý v pořadí nese jedničku atd ... Na disku budete mít uloženo 63 hlaviček, které se budou lišit pouze touto hodnotou. Formát hlavičky má samozřejmě své vlastnosti, ale pro výsledek není vůbec nutné se tím zaobírat, protože případná změna vesměs znefunkční catridge a k běhu to nemá vliv.

6. Formát paměťových bloků

Paměťový blok musí být dlouhý přesně 8192 bytů, proto pozor při kompilaci ! Kompilátory běžně kompilují i se spustitelnou adresou, kterou zde nepotřebujeme, takže uložíte li paměť od $8000 do $9fff, na disku uvidíte soubor s velikostí 8194 bytů !! Proto, pokud to jde, při kompilaci zkuste zakázat přikládání startovací adresy nebo ...
... nebo ji musíte ručně odstranit v nějakém HEX editoru.

Nezapomínejte na to, že vám CRT povolí přístup vždy pouze do paměti od $8000 do $9FFF, takže pokud potřebujete program překopírovat do paměti C64 na nějakou jinou adresu a tam má běžet,musíte s tím počítat a buď používat logickou adresu při kompilaci ( která převede všechny absolutní adresy na vámi označené ) nebo si ručně poradit s již zkompilovaným kódem a uložit si bank z paměti ( např .emulátoru ) a zase pozor na startadresu, která se připojuje při každém uložení ! (odstraňte ji)

7. Programujeme zavaděč = bank 0

Zde již čistý kus kódu, který provede následující :

1. Po resetu C64 načte vektor startu programu adresu $8040 ( CBM80 )
2. Na adresu $0100 si zkopíruje z banku „univerzální kopírák dat“ a spustí jej
3. Tomuto kopíráku předhodíme číslo banku (60) , HI adresu kam do C64 kopírovat ($4000) a počet bloků 256 bytů dlouhých ( 32 ) a po provedení kopírování spustíme z adresy $4000 program.

A nyní slibovaný program zavaděče ( paměť - bank 0 ):

                * = $8000
	 
.byte $40,$80,$40,$80,$C3,$C2,$CD,$38,$30,$4C,$CB,$80,$4C,$CB,$80,$4C   ;lo hi lo hi CBM80
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00

                * = $8040

                sei
                jsr $fda3            ;prepare irq
                jsr $fd50            ;init memory
                jsr $fd15            ;init i/o
                jsr $ff5b            ;init video
                ldx #$fb
                txs
                cli

                ldx #$00	
label1          lda $8200,x         ; z adresy $8200 prekopiruje
                sta $0100,x         ; na adresu $0100 program
                inx
                bne label1
                jmp $0100

                * = $8200           ; tento program se zkopiruje 
                .logical $0100      ; jako by lezel na adrese $0100


copy_mem        sty kolikBloku+1    ; nastavi pocet bloku po 256 bytes
                sta hiRamC64+2      ; nastavi HI ram kam zapisovat v C64
                stx setBankAdr+1    ; nastavi bank pro zapnutí
                stx clrBankAdr+1    ; nastavi bank pro vypnutí
                lda hiMemCrtRead    ; nastavim HI bank z aktivního banku CRT
                sta hiMemCrtRead+2

                lda #1              ; vlozenim hodnoty 1 na adresu $de00-$de40
setBankAdr      sta $de00           ; zapnu vybrany bank (selfmod)
                jsr delay           ; zpozdeni kvuli prepnuti cart !! 
                                    ; Pozor C64 neprepina banky okamzite !

                ldy #$00            ; kopirovaci rutina, ktera
                ldx #$00            ; kopiruje po 256-ti bytech 
hiMemCrtRead    lda $8000,x         ; z pameti CRT ( priple na adrese $8000-$a000)
hiRamC64        sta $2000,x         ; do pameti C64
                inx
                bne hiMemCrtRead
                inc hiMemCrtRead+2
                inc hiRamC64+2
                iny
kolikBloku      cpy #00
                bne hiMemCrtRead-2

                lda #0              ; vypnu bank
clrBankAdr      sta $de00
                jsr delay
                rts

delay           ldy #5              ; Nutné zpoždění pro přepnutí banku !
                dey
                bne *-1
                rts

hiMemCrt        .byte $80           ; HI-byte z jakeho mista bloku kopirovat

                .endlogical

                end = *

               .fill ($2000 - (end-start)),0 
                                  ;tento syntax dopocita počet bytů do bloku 8Kb!

A to je vlastně úplně vše, co by jste měli znát. Díky zavaděči a univerzální kopírovací rutině ( napište si klidně svoji ) můžete již i v C64 zapínat a kopírovat data z CRT do C64 jak potřebujete.

Na konec si ukážeme kopírování grafického obrázku většího než jeden bank.

Příklad: Chci načíst z CRT grafiku, formát Art Sudio, Koala ... atd ... v paměti C64 musí být : Grafika od $2000-$3FFF, VideoRAM od $4000-$43FF, ColorRAM od $4400-$47FF Použijeme dva bloky, v banku 62 budou čistá grafická data a v banku 63 video a color ram :

              lda #$80           ; načtu data z CRT od adresy $8000
              sta hiMemCrt
              ldx #61            ; z banku 61
              ldy #$20           ; Zkopíruju 20x256 bytes = $2000
              lda #$20           ; na adresu $2000 v C64
              jsr copy_mem
              
              lda #$80           ; načtu data z CRT od adresy  $8000
              sta hiMemCrt
              ldx #62            ; z banku 62
              ldy #$4            ; Zkopíruju 4x256 bytes = $0400
              lda #$40           ; na adresu $4000 v C64
              jsr copy_mem
              
              lda #$84           ; načtu data z CRT od adresy  $8400
              sta hiMemCrt
              ldx #62            ; z banku 62
              ldy #$4            ; Zkopíruju 4x256 bytes = $0400
              lda #$44           ; na adresu $4400 v C64
              jsr copy_mem

              ... a zde provedeme zobrazení grafiky.

V příkladu jsme mohli ušetřit poslední kopírování a druhým jsme mohli přenést zrovna $800 bytů, ale pro ukázku možností kopíráku jsem zvolil rozepsanou možnost.A hlavně. Díky hardwarovému „namontování“ je to opravdu rychlé :)

no ... a teď už vám nic nebrání napsat třeba Princ of Persia 2. Místa máte dost :)

PCH / Unreal 2022

Nový příspěvek k článku

podpis :
První znak podpisu musí být vykřičník, jinak se příspěvek neodešle (ochrana proti spamu)

14.02.2023 - kolemjdouci

Neztratil, Josef hnidopichuje. Treba nema do ceho pichnout a tak picha do lidi, co se snazi neco delat :) $ se pouziva pro hex vsude mozne preci, ne jen na c64... Za mne je $8000 citelnejsi nez 32768.

13.02.2023 - PCH

No. Snažil jsem se v těch $8000, #8192, 32768 neztratit a to se doufám nestalo :)

13.02.2023 - kolemjdouci

Co mas proti $8000 ? Dyk je to to same jako 32768 a dava to vetsi smysl, kdyz se udava base $8000 (hex) ne ?

13.02.2023 - Josef

Díky za článek!! Jen bych asi opravil tuhle větu na začátku článku " Paměťové bloky musí mít vždy přesnou velikost , a to je $8000 bytes. " mělo by být 8192 bytes.

Advert

Hardcode and datamining by PCH of UNREAL, Hardware guru by RAY of UNREAL, Bugs report by SILLICON of UNREAL
UNREAL 2014-2021 Czech republic