Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/home/serial.asm
1270 views
1
Serial::
2
push af
3
push bc
4
push de
5
push hl
6
ldh a, [hSerialConnectionStatus]
7
inc a
8
jr z, .connectionNotYetEstablished
9
ldh a, [rSB]
10
ldh [hSerialReceiveData], a
11
ldh a, [hSerialSendData]
12
ldh [rSB], a
13
ldh a, [hSerialConnectionStatus]
14
cp USING_INTERNAL_CLOCK
15
jr z, .done
16
; using external clock
17
ld a, SC_START | SC_EXTERNAL
18
ldh [rSC], a
19
jr .done
20
.connectionNotYetEstablished
21
ldh a, [rSB]
22
ldh [hSerialReceiveData], a
23
ldh [hSerialConnectionStatus], a
24
cp USING_INTERNAL_CLOCK
25
jr z, .usingInternalClock
26
; using external clock
27
xor a
28
ldh [rSB], a
29
ld a, $3
30
ldh [rDIV], a
31
.waitLoop
32
ldh a, [rDIV]
33
bit 7, a ; wait until rDIV has incremented from $3 to $80 or more
34
jr nz, .waitLoop
35
ld a, SC_START | SC_EXTERNAL
36
ldh [rSC], a
37
jr .done
38
.usingInternalClock
39
xor a
40
ldh [rSB], a
41
.done
42
ld a, $1
43
ldh [hSerialReceivedNewData], a
44
ld a, SERIAL_NO_DATA_BYTE
45
ldh [hSerialSendData], a
46
pop hl
47
pop de
48
pop bc
49
pop af
50
reti
51
52
; hl = send data
53
; de = receive data
54
; bc = length of data
55
Serial_ExchangeBytes::
56
ld a, 1
57
ldh [hSerialIgnoringInitialData], a
58
.loop
59
ld a, [hl]
60
ldh [hSerialSendData], a
61
call Serial_ExchangeByte
62
push bc
63
ld b, a
64
inc hl
65
ld a, 48
66
.waitLoop
67
dec a
68
jr nz, .waitLoop
69
ldh a, [hSerialIgnoringInitialData]
70
and a
71
ld a, b
72
pop bc
73
jr z, .storeReceivedByte
74
dec hl
75
cp SERIAL_PREAMBLE_BYTE
76
jr nz, .loop
77
xor a
78
ldh [hSerialIgnoringInitialData], a
79
jr .loop
80
.storeReceivedByte
81
ld [de], a
82
inc de
83
dec bc
84
ld a, b
85
or c
86
jr nz, .loop
87
ret
88
89
Serial_ExchangeByte::
90
xor a
91
ldh [hSerialReceivedNewData], a
92
ldh a, [hSerialConnectionStatus]
93
cp USING_INTERNAL_CLOCK
94
jr nz, .loop
95
ld a, SC_START | SC_INTERNAL
96
ldh [rSC], a
97
.loop
98
ldh a, [hSerialReceivedNewData]
99
and a
100
jr nz, .ok
101
ldh a, [hSerialConnectionStatus]
102
cp USING_EXTERNAL_CLOCK
103
jr nz, .doNotIncrementUnknownCounter
104
call IsUnknownCounterZero
105
jr z, .doNotIncrementUnknownCounter
106
call WaitLoop_15Iterations
107
push hl
108
ld hl, wUnknownSerialCounter + 1
109
inc [hl]
110
jr nz, .noCarry
111
dec hl
112
inc [hl]
113
.noCarry
114
pop hl
115
call IsUnknownCounterZero
116
jr nz, .loop
117
jp SetUnknownCounterToFFFF
118
.doNotIncrementUnknownCounter
119
ldh a, [rIE]
120
and IE_SERIAL | IE_TIMER | IE_STAT | IE_VBLANK
121
cp IE_SERIAL
122
jr nz, .loop
123
ld a, [wUnknownSerialCounter2]
124
dec a
125
ld [wUnknownSerialCounter2], a
126
jr nz, .loop
127
ld a, [wUnknownSerialCounter2 + 1]
128
dec a
129
ld [wUnknownSerialCounter2 + 1], a
130
jr nz, .loop
131
ldh a, [hSerialConnectionStatus]
132
cp USING_EXTERNAL_CLOCK
133
jr z, .ok
134
ld a, 255
135
.waitLoop
136
dec a
137
jr nz, .waitLoop
138
.ok
139
xor a
140
ldh [hSerialReceivedNewData], a
141
ldh a, [rIE]
142
and IE_SERIAL | IE_TIMER | IE_STAT | IE_VBLANK
143
sub IE_SERIAL
144
jr nz, .skipReloadingUnknownCounter2
145
ld [wUnknownSerialCounter2], a
146
ld a, $50
147
ld [wUnknownSerialCounter2 + 1], a
148
.skipReloadingUnknownCounter2
149
ldh a, [hSerialReceiveData]
150
cp SERIAL_NO_DATA_BYTE
151
ret nz
152
call IsUnknownCounterZero
153
jr z, .done
154
push hl
155
ld hl, wUnknownSerialCounter + 1
156
ld a, [hl]
157
dec a
158
ld [hld], a
159
inc a
160
jr nz, .noBorrow
161
dec [hl]
162
.noBorrow
163
pop hl
164
call IsUnknownCounterZero
165
jr z, SetUnknownCounterToFFFF
166
.done
167
ldh a, [rIE]
168
and IE_SERIAL | IE_TIMER | IE_STAT | IE_VBLANK
169
cp IE_SERIAL
170
ld a, SERIAL_NO_DATA_BYTE
171
ret z
172
ld a, [hl]
173
ldh [hSerialSendData], a
174
call DelayFrame
175
jp Serial_ExchangeByte
176
177
WaitLoop_15Iterations::
178
ld a, 15
179
.waitLoop
180
dec a
181
jr nz, .waitLoop
182
ret
183
184
IsUnknownCounterZero::
185
push hl
186
ld hl, wUnknownSerialCounter
187
ld a, [hli]
188
or [hl]
189
pop hl
190
ret
191
192
; a is always 0 when this is called
193
SetUnknownCounterToFFFF::
194
dec a
195
ld [wUnknownSerialCounter], a
196
ld [wUnknownSerialCounter + 1], a
197
ret
198
199
; This is used to exchange the button press and selected menu item on the link menu.
200
; The data is sent thrice and read twice to increase reliability.
201
Serial_ExchangeLinkMenuSelection::
202
ld hl, wLinkMenuSelectionSendBuffer
203
ld de, wLinkMenuSelectionReceiveBuffer
204
ld c, 2 ; number of bytes to save
205
ld a, 1
206
ldh [hSerialIgnoringInitialData], a
207
.loop
208
call DelayFrame
209
ld a, [hl]
210
ldh [hSerialSendData], a
211
call Serial_ExchangeByte
212
ld b, a
213
inc hl
214
ldh a, [hSerialIgnoringInitialData]
215
and a
216
ld a, 0
217
ldh [hSerialIgnoringInitialData], a
218
jr nz, .loop
219
ld a, b
220
ld [de], a
221
inc de
222
dec c
223
jr nz, .loop
224
ret
225
226
Serial_PrintWaitingTextAndSyncAndExchangeNybble::
227
call SaveScreenTilesToBuffer1
228
callfar PrintWaitingText
229
call Serial_SyncAndExchangeNybble
230
jp LoadScreenTilesFromBuffer1
231
232
Serial_SyncAndExchangeNybble::
233
vc_hook Wireless_WaitLinkTransfer
234
ld a, $ff
235
ld [wSerialExchangeNybbleReceiveData], a
236
.loop1
237
call Serial_ExchangeNybble
238
call DelayFrame
239
call IsUnknownCounterZero
240
jr z, .next1
241
push hl
242
ld hl, wUnknownSerialCounter + 1
243
dec [hl]
244
jr nz, .next2
245
dec hl
246
dec [hl]
247
jr nz, .next2
248
pop hl
249
xor a
250
jp SetUnknownCounterToFFFF
251
.next2
252
pop hl
253
.next1
254
ld a, [wSerialExchangeNybbleReceiveData]
255
inc a
256
jr z, .loop1
257
vc_patch Wireless_net_delay_3
258
IF DEF(_RED_VC) || DEF(_BLUE_VC)
259
ld b, 26
260
ELSE
261
ld b, 10
262
ENDC
263
vc_patch_end
264
.loop2
265
call DelayFrame
266
call Serial_ExchangeNybble
267
dec b
268
jr nz, .loop2
269
vc_patch Wireless_net_delay_4
270
IF DEF(_RED_VC) || DEF(_BLUE_VC)
271
ld b, 26
272
ELSE
273
ld b, 10
274
ENDC
275
vc_patch_end
276
.loop3
277
call DelayFrame
278
call Serial_SendZeroByte
279
dec b
280
jr nz, .loop3
281
ld a, [wSerialExchangeNybbleReceiveData]
282
ld [wSerialSyncAndExchangeNybbleReceiveData], a
283
vc_hook Wireless_WaitLinkTransfer_ret
284
ret
285
286
Serial_ExchangeNybble::
287
call .doExchange
288
ld a, [wSerialExchangeNybbleSendData]
289
add $60
290
ldh [hSerialSendData], a
291
ldh a, [hSerialConnectionStatus]
292
cp USING_INTERNAL_CLOCK
293
jr nz, .doExchange
294
ld a, SC_START | SC_INTERNAL
295
ldh [rSC], a
296
.doExchange
297
ldh a, [hSerialReceiveData]
298
ld [wSerialExchangeNybbleTempReceiveData], a
299
and $f0
300
cp $60
301
ret nz
302
xor a
303
ldh [hSerialReceiveData], a
304
ld a, [wSerialExchangeNybbleTempReceiveData]
305
and $f
306
ld [wSerialExchangeNybbleReceiveData], a
307
ret
308
309
Serial_SendZeroByte::
310
xor a
311
ldh [hSerialSendData], a
312
ldh a, [hSerialConnectionStatus]
313
cp USING_INTERNAL_CLOCK
314
ret nz
315
ld a, SC_START | SC_INTERNAL
316
ldh [rSC], a
317
ret
318
319
Serial_TryEstablishingExternallyClockedConnection::
320
ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK
321
ldh [rSB], a
322
xor a
323
ldh [hSerialReceiveData], a
324
ld a, SC_START | SC_EXTERNAL
325
ldh [rSC], a
326
ret
327
328