blob: 681cfc37debe02163b8e41614605422895e7a06b (
plain)
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
; INES header stuff
.inesprg 1 ; 1 bank of PRG
.ineschr 2 ; 2 banks of CHR data
.inesmap 4 ; we use mapper 4 (MMC3)
.rsset $0000 ; variables
COPY_SOURCE_ADDR .rs 2
COPY_DEST_ADDR .rs 2
CHR_BANK .rs 1
FRAME .rs 1
.bank 1
.org $FFFA ; reset vectors
.dw NMI
.dw Start
.dw IRQ
.bank 0
.org $C000 ; code starts here
Start:
; disable interrupts
sei
; reset stack
ldx #$ff
txs
; disable PPU
lda #%00000000
sta PPUCTRL
lda #%00000000
sta PPUMASK
jsr waitblank_simple
; reset sound
lda #0
sta $4000
sta $4001
sta $4002
sta $4003
sta $4004
sta $4005
sta $4006
sta $4007
sta $4009
sta $400A
sta $400C
sta $400D
sta $400E
sta $400F
sta $4010
sta $4011
sta $4012
sta $4013
lda #$0F
sta $4015
lda #$40
sta $4017
; vertical mirroring
lda #0
sta $A000
load_palette:
lda #LOW(palette)
sta <COPY_SOURCE_ADDR
lda #HIGH(palette)
sta <COPY_SOURCE_ADDR+1
lda #$3F
sta $2006
lda #$00
sta $2006
ldy #$00
ldx #16
.loop:
lda [COPY_SOURCE_ADDR], y
sta $2007
iny
dex
bne .loop
load_nametable:
lda #LOW(nametable_0)
sta <COPY_SOURCE_ADDR
lda #HIGH(nametable_0)
sta <COPY_SOURCE_ADDR+1
lda #$20
sta $2006
lda #$00
sta $2006
ldy #$00
ldx #$00
.loop:
lda [COPY_SOURCE_ADDR], y
sta $2007
iny
bne .loop
inc COPY_SOURCE_ADDR+1
inx
cpx #8
bne .loop
sta $E000 ; disable MMC3 IRQ
lda #%10001000 ; enable NMI
sta PPUCTRL
jsr waitblank
lda #%00001010 ; enable BG
sta PPUMASK
cli ; enable interrupts
main_loop:
jsr waitblank
jmp main_loop
; VBlank wait subroutine
waitblank:
bit PPUSTATUS
lda #0
sta PPUSCROLL
sta PPUSCROLL
lda FRAME
.loop:
cmp FRAME
beq .loop
rts
; VBlank wait subroutine
waitblank_simple:
bit PPUSTATUS
lda #0
sta PPUSCROLL
sta PPUSCROLL
.loop:
lda PPUSTATUS ; load A with value at location PPUSTATUS
bpl .loop ; if bit 7 is not set (not VBlank) keep checking
rts
NMI:
php
pha
; signal VBlank
inc FRAME
lda FRAME
and #$40
beq .first
lda #2
jsr chr_bank_switch_left
lda #%10001001
sta PPUCTRL
jmp .end
.first:
; select bank 0
lda #0
jsr chr_bank_switch_left
lda #%10001000
sta PPUCTRL
.end:
; arm IRQ
sta $E000 ; disable scanline IRQ (and ack)
lda #127
sta $C000 ; scanline counter
sta $C001 ; reload counter
sta $E001 ; enable scanline IRQ
pla
plp
rti
IRQ:
php
pha
; disable scanline IRQ (and ack)
sta $E000
; delay
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
lda FRAME
and #$40
beq .first
lda #3
jsr chr_bank_switch_left
lda #%10001001
sta PPUCTRL
jmp .end
.first:
; select bank 0
lda #1
jsr chr_bank_switch_left
lda #%10001000
sta PPUCTRL
.end:
pla
plp
rti
chr_bank_switch_left:
pha
asl A
asl A
ldx #0
stx $8000
sta $8001
inx
ora #2
stx $8000
sta $8001
pla
rts
chr_bank_switch_right:
pha
asl A
asl A
ldx #2
stx $8000
sta $8001
inx
ora #1
stx $8000
sta $8001
inx
and #%11111110
ora #2
stx $8000
sta $8001
inx
ora #1
stx $8000
sta $8001
pla
rts
nametable_0:
.incbin "name_table_0.bin"
nametable_1:
.incbin "name_table_1.bin"
attr_table_0:
.incbin "attr_table_0.bin"
attr_table_1:
.incbin "attr_table_1.bin"
nametable_2:
.incbin "name_table_2.bin"
nametable_3:
.incbin "name_table_3.bin"
attr_table_2:
.incbin "attr_table_2.bin"
attr_table_3:
.incbin "attr_table_3.bin"
palette:
.incbin "palette_0.bin"
.incbin "palette_1.bin"
.incbin "palette_2.bin"
.incbin "palette_3.bin"
.bank 2
.org $0000
.incbin "pattern_0.bin"
.org $1000
.incbin "pattern_1.bin"
.bank 3
.org $0000
.incbin "pattern_2.bin"
.org $1000
.incbin "pattern_3.bin"
|