Come sviluppare oggi giochi per Gameboy. Dettaglio dell’architettura della console e descrizione dell’assembler Z80. Grafica raster. Tile, scrolling e sprite. Il sonoro. Descrizione del Bank Switching e dei chip MBC. Come creare salvataggi nella SRAM. Provare il software sull’emulatore e sull’hardware fisico.
Luigi Di Carlo, CEO & Founder @Evometrika srl – “Ruolo della computer vision ...
8 bit e 4 toni di grigio: sviluppare giochi per Gameboy by Giovanni Simotti
1. 8 bit e 4 toni di grigio: sviluppare
giochi per Gameboy
Giovanni Simotti
info@haruneko.com - Haruneko Entertainment
2. Giovanni Simotti info@haruneko.com
Il Gameboy
● 1989/1999 - 10 anni
● quasi 120 milioni di console
vendute
● oltre 800 giochi disponibili
● 9.0 x 14.8 x 3.2 cm
● 300 grammi
● 10-15 ore di autonomia
– (4x batterie AA)
3. Giovanni Simotti info@haruneko.com
Hardware
● Caratteristiche
● CPU 8-bit SHARP LR35902 @ 4.19 MHz
● 8KB di RAM
● 8KB di VideoRAM
● 32KB... 4MB di ROM (cartuccia)
● schermo monocromatico 2.6” 160x144 (4 toni di
grigio/verde)
● Hardware molto semplice ma ben progettato
● C'è tutto ciò che serve
4. Giovanni Simotti info@haruneko.com
La CPU e la MEMORIA
● CPU: esegue il programma in linguaggio
macchina e comanda l'hardware dedicato
● MEMORIA: contiene il programma e i dati
letti/scritti dalla cpu
– è organizzata in celle grandi 1 byte
– ogni cella risiede in un certo indirizzo di memoria
● Per accedere all'hardware dedicato:
– Memory mapped I/O: alcuni indirizzi di memoria non
accedono a memoria RAM/ROM, bensì ai chip
Video / chip Audio / ecc...
5. Giovanni Simotti info@haruneko.com
La CPU: dettaglio
● SHARP LR35902
– Z80 con qualche differenza
– approccio simile a Intel 8080
● Accesso alla memoria dura 2 cicli di clock, ogni
istruzione dura un multiplo di 4 cicli di clock
– 4mhz = al più 1 milione di istruzioni al secondo
– a volte si indica la durata delle istruzioni in
"cicli macchina" = "cicli di clock" / 4
● tabella Opcode: documento che elenca le istruzioni
supportate dalla CPU e quanti cicli di clock durano
6. Giovanni Simotti info@haruneko.com
La CPU: i registri
● Program Counter (PC)
– Indirizzo dell'istruzione attualmente in esecuzione
● Stack Pointer (SP)
– Indirizzo attualmente usato nell'area stack
● Accumulatore (A)
– Usato nelle operazioni aritmetico/logiche
● 6 registri 8bit general purpose (B,C,D,E,H,L)
– Usabili anche in coppia (BC, DE, HL) (16 bit)
– 6502 (c64, NES, ….) ha solo 2 registri general purpose
7. Giovanni Simotti info@haruneko.com
Grafica: Mappe
● Mappa: un'immagine grande 256x256 pixel e
realizzata usando dei blocchi ("tile") 8x8
● 32x32 = 1024 tile per mappa = 1024 byte
● 192 tile possibili (8000-97FF)
8. Giovanni Simotti info@haruneko.com
Grafica: Mappe (continua)
● Due mappe: Background e Window
– Window è sempre mostrata sopra alla mappa
background
– ogni mappa può essere disabilitata (FF40)
– i 1024 tile che compongono una mappa sono
indicati in (9800-9BFF) o (9C00-9FFF)
● Per il posizionamento:
– (FF42) e (FF43) per x,y della mappa Background
– (FF4A) e (FF4B) per x,y della mappa Window
9. Giovanni Simotti info@haruneko.com
Grafica: Mappe (continua)
● Formato dei tile:
– Ogni pixel può avere 4 colori
● 2 bit per pixel
– 16 byte per ogni tile 8x8
– Occorrono 2 byte per linea: il
primo byte contiene tutti i bit
meno significativi dei pixel di
quella linea, il secondo byte
contiene tutti i bit più significativi
– Ci sono dei tool che semplificano
la vita
10. Giovanni Simotti info@haruneko.com
Grafica: Sprite (OAM)
● Sono immagini grafiche con pixel trasparenti
– stampati sopra alle mappe
– max 40 sprite a schermo
– 8x8 oppure 8x16 pixel
– 3 colori + 1 trasparente
– sfruttano gli stessi tile usati dalle mappe (8000-8FFF)
– max 10 per linea
● 4 byte per ogni sprite (FE00-FE9F):
● Pos Y: posizione Y a schermo -16
● Pos X: posizione X a schermo -8
● Pattern number: indica il tile da usare
● Flag: mirror x, mirror y, ecc...
11. Giovanni Simotti info@haruneko.com
Grafica: Palette
● Non specifico direttamente i colori dei pixel: è
usata invece una tabella di lookup chiamata
Palette
– Se ad esempio per un pixel ho il colore “2”:
visualizzo il secondo colore specificato nella palette
utilizzata
● 1 palette da 4 colori per le mappe (FF47)
● 2 palette da 3 colori per gli sprite (FF48 - FF49)
● utili per i "fade": cambio 3 byte anzichè i bit di
tutti i tile in memoria (fino a 384 byte!)
12. Giovanni Simotti info@haruneko.com
Grafica: Timing
● Lo schermo non è disegnato tutto nello stesso
momento: è disegnato dall'alto verso il basso,
riga per riga
● per ogni riga: 456 cicli di clock
– circa 201..207 cicli “pausa” di HBlank
● Dopo l'ultima riga: 4560 cicli “pausa” di Vblank
● 70224 cicli per ogni frame
– il refresh video è 59.73hz
13. Giovanni Simotti info@haruneko.com
Grafica: Timing (continua)
● La memoria OAM e (in parte) la Video RAM
sono scrivibili solo durante il VBlank e l'HBlank!
– Il registro STAT (FF41h) ci indica quando possiamo
scrivere la memoria OAM (FE00-FE9F) e quella
Video RAM (usata per tile e mappe)
● Effetti raster
– Posso spostare gli sprite o una mappa durante
l'HBlank!
● Più di 40 sprite
● Tile "nuovi"
14. Giovanni Simotti info@haruneko.com
Grafica: Timing (continua)
● Durante l'HBlank di ogni riga, sposto la mappa
e cambio il colore della palette della mappa
– Poco più di 200 cicli di clock per l'HBlank
15. Giovanni Simotti info@haruneko.com
Le cartucce ROM
● Contengono tutto il gioco: grafica, audio e codice
sorgente compilato/assemblato
– La RAM di sistema tipicamente contiene solo variabili,
ecc...
● La memoria ROM della cartuccia ed eventuali
altre cose in essa contenute sono accedibili
tramite gli indirizzi (0000-7FFF) e (A000-BFFF)
– non tutto ciò che è contenuto nello spazio degli
indirizzi è "dentro" alla console
– ROM: le scritture non sono consentite, tranne in
alcuni casi (bank switching o memoria RAM extra)
16. Giovanni Simotti info@haruneko.com
Memory Bank Controller (MBC)
● Chip della cartuccia che permette di effettuare il Bank Switching,
ovvero selezionare quale porzione (detta "banco") della ROM della
cartuccia deve essere mostrata negli indirizzi (4000-7FFF)
● la porzione di memoria 0000-3FFF è sempre fissa al primo banco
della ROM
● ROM più grandi di 32KB: max 256 banchi per un totale di max
4MB!
● per la selezione del banco N basta scrivere il valore N in un
qualsiasi indirizzo compreso tra 2000-3FFF
● Non solo ROM nella cartuccia:
● RAM extra, generalmente con batteria tampone per i salvataggi
● Timer persistente secondi/minuti/ore/giorni
● altro
17. Giovanni Simotti info@haruneko.com
I salvataggi
● Solo su cartucce con MBC
● Funzionamento:
– attiviamo la External RAM scrivendo 0x0A in una
locazione tra 0000-1FFF
– scriviamo il save (A000-A7FF oppure A000-BFFF a
seconda di quanta RAM ha la cartuccia, 2K...8K)
– disattiviamo la External RAM scrivendo 0x00 in una
locazione tra 0000-1FFF
● Molto semplice!
18. Giovanni Simotti info@haruneko.com
L'header delle cartucce
● Contenuto nella cartuccia in (0100-014F):
● (0100-0103): è la prima locazione eseguita dalla CPU
dopo la visualizzazione del logo Nintendo. Tipicamente è
un'istruzione di salto all'indirizzo (0150)
● (0104-0133): grafica del logo Nintendo (deve essere una
sequenza precisa di byte, altrimenti il Gameboy si blocca)
● …
● (0147): tipo di MBC utilizzato + eventuale hardware extra
(ram extra per i salvataggi, rumble pack, ecc...)
● (0148): indica la capienza della cartuccia (min 32KB, max
4MB)
● ...
19. Giovanni Simotti info@haruneko.com
La mappa di memoria
0000 3FFF 16KB ROM Bank 00 (cartuccia)
4000 7FFF 16KB ROM Bank 01..NN (cartuccia)
8000 9FFF 8KB Video RAM (VRAM)
A000 BFFF [8KB External RAM Bank 01..04] (cartuccia)
C000 DFFF 8KB Work RAM (WRAM)
E000 FDFF Mirror di C000-DDFF (ECHO)
FE00 FE9F Sprite Attribute Table (OAM)
FEA0 FEFF riservato
FF00 FF7F Porte di Input / Output (sonoro, ecc...)
FF80 FFFE High RAM (HRAM - usata durante i
trasferimenti DMA per gli sprite)
FFFF FFFF Interrupt Enable Register
20. Giovanni Simotti info@haruneko.com
Sonoro
● 4 Canali:
● onda quadra + spostamento in frequenza (FF10-FF14)
● onda quadra (FF16-FF19)
● campione audio (FF1A-FF1E) (Wave RAM: FF30-FF3F, 32
campioni 4 bit)
● rumore (FF20-FF23)
● Più un canale Vin per eventuale audio generato
nella cartuccia
● Il canale 3 in teoria può suonare qualcosa di
campionato e "lungo" con qualità 8khz/4bit
● Ma non restano cicli di clock per fare altro
21. Giovanni Simotti info@haruneko.com
Per sviluppare
● Emulatore: NO$GMB
– Memory viewer, Breakpoint, Watch, BG Map viewer,
Tile viewer, OAM viewer, Palette viewer, I/O viewer,
ecc..
– L'ultima colonna del disassemblato indica (in cicli
macchina) la durata dell'istruzione!
● Consigliato l'Assembler (RGBDS)
● Buoni risultati anche con C + assembler
(GBDK)
22. Giovanni Simotti info@haruneko.com
Per sviluppare (continua)
● Ogni istruzione C viene compilata, ovvero convertita
in un certo numero di istruzioni in linguaggio
macchina
– attenzione al timing! Poco tempo per un frame, molto
poco per un vblank, pochissimo per un hblank!
● controllare il codice assemblato (file .lst)
– attenzione ai sizeof(type):
● sizeof(int*) == 2
● sizeof(char) == 1
● sizeof(int) == 2
● sizeof(long) == 4
24. Giovanni Simotti info@haruneko.com
"Hello World" GBDK (continua)
● Si poteva fare meglio in ASM (o in maniera più accorta in C):
– le righe 178...181 non servono (36 cicli di clock sprecati!)
● Analizzando il file .lst, la riga "(*p)++;" diventa
10 comandi ASM
25. Giovanni Simotti info@haruneko.com
Per testare sull'hardware
● Cartucce Flash
– molte sono troppo vecchie
● driver per OS vecchi
● interfaccia seriale o parallela
– "recenti":
● drag'n'derp cartridge
● ems 64 mb game boy smart card
● DIY:
– http://www.powerofasm.fr.st/gbkit/
– http://www.reinerziegler.de/readplus.htm#Home
%20made%20carts