/
example08.asm
174 lines (125 loc) · 4.8 KB
/
example08.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
; ---------------------------------------------------------------------
; Kostra programu pro herní konzoli NES
; Vynulování barvové palety, zvýšení intenzity zvolené barvové složky
;
; Založeno na příkladu https://github.com/depp/ctnes/tree/master/nesdev/01
; Viz též článek na https://www.moria.us/blog/2018/03/nes-development
; Audio https://raw.githubusercontent.com/iliak/nes/master/doc/apu_ref.txt
;
; Tento zdrojový kód je součástí seriálu Vývoj her pro herní konzoli NES
; https://www.root.cz/serialy/vyvoj-her-pro-herni-konzoli-nes/
; ---------------------------------------------------------------------
; Jména řídicích registrů použitých v kódu
PPUCTRL = $2000
PPUMASK = $2001
PPUSTATUS = $2002
PPUADDR = $2006
PPUDATA = $2007
; Další důležité adresy
PALETTE = $3f00
; ---------------------------------------------------------------------
; Definice maker
; ---------------------------------------------------------------------
.macro setup_cpu
; nastavení stavu CPU
sei ; zákaz přerušení
cld ; vypnutí dekadického režimu (není podporován)
ldx #$ff
txs ; vrchol zásobníku nastaven na 0xff (první stránka)
.endmacro
.macro wait_for_frame
: bit PPUSTATUS ; test obsahu registru PPUSTATUS
bpl :- ; skok, pokud je příznak N nulový
.endmacro
.macro clear_ram
lda #$00 ; vynulování registru A
: sta $000, x ; vynulování X-tého bajtu v nulté stránce
sta $100, x
sta $200, x
sta $300, x
sta $400, x
sta $500, x
sta $600, x
sta $700, x ; vynulování X-tého bajtu v sedmé stránce
inx ; přechod na další bajt
bne :- ; po přetečení 0xff -> 0x00 konec smyčky
.endmacro
; ---------------------------------------------------------------------
; Definice hlavičky obrazu ROM
; ---------------------------------------------------------------------
; Size of PRG in units of 16 KiB.
prg_npage = 1
; Size of CHR in units of 8 KiB.
chr_npage = 1
; INES mapper number.
mapper = 0
; Mirroring (0 = horizontal, 1 = vertical)
mirroring = 1
.segment "HEADER"
.byte $4e, $45, $53, $1a
.byte prg_npage
.byte chr_npage
.byte ((mapper & $0f) << 4) | (mirroring & 1)
.byte mapper & $f0
; ---------------------------------------------------------------------
; Blok paměti s definicí dlaždic 8x8 pixelů
; ---------------------------------------------------------------------
.segment "CHR0a"
.segment "CHR0b"
.code
; ---------------------------------------------------------------------
; Programový kód rutin pro NMI, RESET a IRQ volaných automaticky CPU
;
; viz též https://www.pagetable.com/?p=410
; ---------------------------------------------------------------------
; Obslužná rutina pro NMI (nemaskovatelné přerušení, vertical blank)
.proc nmi
rti ; návrat z přerušení
.endproc
; Obslužná rutina pro IRQ (maskovatelné přerušení)
.proc irq
rti ; návrat z přerušení
.endproc
; Obslužná rutina pro RESET
.proc reset
; nastavení stavu CPU
setup_cpu
; nastavení řídicích registrů
ldx #$00
stx PPUCTRL ; nastavení PPUCTRL = 0
stx PPUMASK ; nastavení PPUMASK = 0
; čekání na vnitřní inicializaci PPU (dva snímky)
wait_for_frame
wait_for_frame
; vymazání obsahu RAM
clear_ram
; čekání na další snímek
wait_for_frame
; vynulování barvové palety
lda PPUSTATUS ; reset záchytného registru
lda #>PALETTE ; nastavení adresy pro barvovou paletu $3f00
sta PPUADDR
lda #<PALETTE ; nižší bajt adresy
sta PPUADDR
ldx #$20 ; počitadlo barev v paletě: 16+16
lda #$00 ; vynulování každé barvy
:
sta PPUDATA ; zápis barvy
dex ; snížení hodnoty počitadla
bne :-
lda #%10000000 ; vysoká intenzita modré barvy
sta PPUMASK
; vlastní herní smyčka je prozatím prázdná
game_loop:
jmp game_loop ; nekonečná smyčka (později rozšíříme)
.endproc
; ---------------------------------------------------------------------
; Tabulka vektorů CPU
; ---------------------------------------------------------------------
.segment "VECTORS"
.addr nmi
.addr reset
.addr irq
; ---------------------------------------------------------------------
; Finito
; ---------------------------------------------------------------------