-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.asm
177 lines (145 loc) · 3.47 KB
/
main.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
175
176
include "constants.asm"
include "longcalc.asm"
include "hram.asm"
include "ioregs.asm"
include "debug.asm"
include "macros.asm"
Section "Core Stack", WRAM0
CoreStackBase:
ds CORE_STACK_SIZE
CoreStack::
Section "Core Functions", ROM0
; Temporary code for testing task switching
Start::
; Disable LCD and audio.
; Disabling LCD must be done in VBlank.
; On hardware start, we have about half a normal vblank, but this may depend on the hardware variant.
; So this has to be done quick!
; Note we save the A register to C before clearing it, as we need to save its initial value
; for GB hardware detection below.
ld C, A
xor A
ld [SoundControl], A
ld [LCDControl], A
; Initial state of A (stored in C) and B registers can be used to detect GB hardware variant
; ie. GB/CGB/GBA/SGB.
ld A, C
cp $11 ; A = $11 means CGB or GBA
jr nz, .notCGB
; To distinguish between CGB and GBA, we further check bit 0 of B
rrc B ; push lowest bit of B into carry flag
ld A, 2
jr nc, .setHardwareVariant ; leave A = 2 if CGB
inc A ; otherwise set A = 3
jr .setHardwareVariant
.notCGB
cp $01 ; A = $01 means original GB or SGB
jr nz, .notOriginalOrSGB
xor A
jr .setHardwareVariant
.notOriginalOrSGB
cp $ff ; A = $ff means Pocket GB or SGB2
jr nz, .notPGBorSGB2
ld A, 1
jr .setHardwareVariant
.notPGBorSGB2
; if we've made it here, it means none of the known hardware indicators match.
; this probably means a badly-written emulator which initialized everything to random or zero.
ld A, 4
.setHardwareVariant
ld [HardwareVariant], A
Debug "Debug messages enabled. Detected hardware: %A%"
; Use core stack
ld SP, CoreStack
; Set up timer
ld A, TimerEnable | TimerFreq18
ld [TimerControl], A
xor A
ld [Uptime], A
ld [Uptime+1], A
ld [Uptime+2], A
ld [Uptime+3], A
; Init things
call TaskInit
call SchedInit
call GraphicsInit
call JoyInit
ld HL, GeneralDynMem
ld B, GENERAL_DYN_MEM_SIZE
call DynMemInit
DisableSwitch
ld A, %10000011 ; background map on + sprites
ld [LCDControl], A
; Set default palettes mapping 0-3 -> 0-3
ld A, %11100100
ld [TileGridPalette], A
ld [SpritePalette0], A
ld [SpritePalette1], A
xor A
ld [TimerCounter], A ; Uptime timer starts from here
ld [InterruptFlags], A ; Reset pending interrupts now that we're properly set up
ld A, IntEnableTimer | IntEnableVBlank | IntEnableJoypad
ld [InterruptsEnabled], A
ei ; note we've still got switching disabled until we switch into our first task
ld C, 0
SetTaskNewEntryPoint TaskPaintMain
call TaskNewDynStack
SetTaskNewEntryPoint TaskClockMain
call TaskNewDynStack
jp SchedLoadNext ; does not return
Task1::
ld A, 1
ld B, 2
ld C, 3
ld D, 4
ld E, 5
ld HL, $face
.loop
inc A
jr .loop
Task2::
ld B, 10
call Fib
.loop
jr .loop
; return Bth fibbonacci number in DE
; clobbers A
Fib:
ld A, B
cp 2
jr nc, .noUnderflow
ld D, 0
ld E, 1
ret ; return 1
.noUnderflow
dec B
call Fib ; DE = Fib(n-1)
dec B
push DE
call Fib ; DE = Fib(n-2)
ld H, D
ld L, E
pop DE
LongAdd DE, HL, DE ; DE += HL, ie. DE = Fib(n-1) + Fib(n-2)
inc B
inc B ; return B to initial value
call T_TaskYield ; demonstrate yielding. Fib(B) should equal DE.
ret
Task3::
; write to screen in a loop, writing i'th tile to value (i+offset)%256 with changing offset
ld C, 0
.outer
inc C ; makes value 1 more out of phase with index
ld DE, 50
call T_SchedSleepTask ; sleep for 50ms
ld DE, 0
.inner
call T_GraphicsWriteTile
inc C
inc E
jr nz, .inner
inc D
ld A, D
cp 4 ; set z if DE = $0400
jr nz, .inner
jr .outer