-
Notifications
You must be signed in to change notification settings - Fork 1
/
scene_twister.z80
219 lines (184 loc) · 3.74 KB
/
scene_twister.z80
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
INCLUDE "Hardware.inc"
INCLUDE "rgbgrafx/rgbgrafx.inc"
Section "Twister Data",DATA
INCLUDE "imagedata/twister.inc"
Section "Twister scene",CODE
scene_twister::
di
call initialize_interrupts
ei
; Set all palette colors to black for the duration of loading image data
RGBG_WaitForVRAM
ld A, $FF
ld [rBGP], A
; Initialize high byte of the tileset starting address
ld A, $80
ld [RGBG_tileset], A
; Load tile patterns to VRAM
ld BC, twister_image_tile_data
ld D, $FF
ld E, 0
RGBG_WaitForVRAM
call RGBG_LoadTiles
; Initialize high byte of the tilemap starting address
ld A, $98
ld [RGBG_tilemap], A
; Set tilemap offset to zero
xor A
ld [RGBG_map_offset], A
; Load tile map
RGBG_WaitForVRAM
ld BC, twister_image_map_data
ld H, $0
ld L, $0
ld E, twister_image_tile_map_width
ld D, twister_image_tile_map_height
call RGBG_SetTileMap
; Reset background scroll registers
xor A
ld [rSCX], A
ld [rSCY], A
di
; When timer interrupt triggers, load 0 to TIMA
ld [rTMA], A
; Initialize timer variable to zero
ld [timer], A
; Set timer to increment 4096 times a second
ld A, 4
ld [rTAC], A
; Set proper values for LCDC register
ld A, (LCDCF_ON | LCDCF_WINOFF | LCDCF_BG8000 | LCDCF_BG9800 | LCDCF_BGON)
ld [rLCDC], A
; Set LCDC interrupt to trigger when LYC == LY
ld A, (STATF_LYC)
ld [rSTAT], A
; Enable VBlank, LCDC and Timer interrupts
ld A, (IEF_LCDC | IEF_VBLANK | IEF_TIMER)
ld [rIE], A
ei
; Set V-blank interrupt
ld BC, twister_vblank
call set_vblank_interrupt
; Set LCDC interrupt
ld BC, twister_lcdc
call set_lcdc_interrupt
; Set timer interrupt
ld BC, twister_timer
call set_timer_interrupt
; Initialize LYC to $00
xor A
ld [rLYC], A
; Set twister_offset to zero at start
ld [twister_offset], A
.fade_in_loop1:
halt
ld A, [timer]
cp 2
jr nz, .fade_in_loop1
RGBG_WaitVBL
ld A, %11111110
ld [rBGP], A
ld [rOBP0], A
ld [rOBP1], A
.fade_in_loop2:
halt
ld A, [timer]
cp 4
jr nz, .fade_in_loop2
RGBG_WaitVBL
ld A, %11111001
ld [rBGP], A
ld [rOBP0], A
ld [rOBP1], A
.fade_in_loop3:
halt
ld A, [timer]
cp 6
jr nz, .fade_in_loop3
RGBG_WaitVBL
ld A, %11100100
ld [rBGP], A
ld [rOBP0], A
ld [rOBP1], A
.loop:
halt
ld A, [timer]
; Start fading out after 160 / 16 = 10 seconds
cp 160
jr nz, .loop
.fade1_loop:
halt
ld A, [timer]
cp 162
jr nz, .fade1_loop
call fade_to_black
.fade2_loop:
halt
ld A, [timer]
cp 164
jr nz, .fade2_loop
call fade_to_black
.fade3_loop:
halt
ld A, [timer]
cp 168
jr nz, .fade3_loop
call fade_to_black
ret
twister_timer:
ei
ld HL, timer
inc [HL]
ret
twister_vblank:
; Increment twister_offset
ld HL, twister_offset
inc [HL]
ret
twister_lcdc:
; Load raster line number to A
ld A, [rLY]
; Store raster line in B
ld B, A
; Load per-frame offset to A
ld A, [twister_offset]
; Add offset to raster line number
add B
; Get sine(rasterline + offset) and store in A
ld H, $30
ld L, A
ld A, [HL]
; Keep sine in range 0-63
cp 63
jr c, .in_range
sub 64
.in_range:
; Jump 64 lines down every 8 lines to create checkerboard
sub B
bit 3, B
jr z, .no_flip
add 64
.no_flip:
; Store result in Y scroll register
ld [rSCY], A
; Increment LYC to trigger interrupt again at next scanline
ld HL, rLYC
inc [HL]
ld A, [HL]
cp 144
jr c, .in_frame
; If at row 144, set LYC to 0
ld [HL], 0
.in_frame:
ret
Section "Sine LUT",HOME[$3000] ; Alignment to 00 important
; This LUT contains one 256-byte sine period varying between 0 and 32
sine_lut:
ANGLE=0.0
REPT 256
DB (MUL(62.0, SIN(ANGLE))+62.0)>>16
ANGLE=ANGLE+256.0
ENDR
Section "Twister variables",BSS
twister_offset: DS 1
timer: DS 1