pokered/home/serial.asm

327 lines
6.1 KiB
NASM
Raw Normal View History

2016-06-12 00:24:04 +00:00
Serial::
2015-06-02 03:13:46 +00:00
push af
push bc
push de
push hl
ldh a, [hSerialConnectionStatus]
2015-06-02 03:13:46 +00:00
inc a
jr z, .connectionNotYetEstablished
ldh a, [rSB]
ldh [hSerialReceiveData], a
ldh a, [hSerialSendData]
ldh [rSB], a
ldh a, [hSerialConnectionStatus]
2015-06-02 03:13:46 +00:00
cp USING_INTERNAL_CLOCK
jr z, .done
; using external clock
ld a, START_TRANSFER_EXTERNAL_CLOCK
ldh [rSC], a
2015-06-02 03:13:46 +00:00
jr .done
.connectionNotYetEstablished
ldh a, [rSB]
ldh [hSerialReceiveData], a
ldh [hSerialConnectionStatus], a
2015-06-02 03:13:46 +00:00
cp USING_INTERNAL_CLOCK
jr z, .usingInternalClock
; using external clock
xor a
ldh [rSB], a
2015-06-02 03:13:46 +00:00
ld a, $3
ldh [rDIV], a
2015-06-02 03:13:46 +00:00
.waitLoop
ldh a, [rDIV]
bit 7, a ; wait until rDIV has incremented from $3 to $80 or more
2015-06-02 03:13:46 +00:00
jr nz, .waitLoop
ld a, START_TRANSFER_EXTERNAL_CLOCK
ldh [rSC], a
2015-06-02 03:13:46 +00:00
jr .done
.usingInternalClock
xor a
ldh [rSB], a
2015-06-02 03:13:46 +00:00
.done
ld a, $1
ldh [hSerialReceivedNewData], a
2015-06-02 03:13:46 +00:00
ld a, SERIAL_NO_DATA_BYTE
ldh [hSerialSendData], a
2015-06-02 03:13:46 +00:00
pop hl
pop de
pop bc
pop af
reti
; hl = send data
; de = receive data
; bc = length of data
2016-06-12 00:24:04 +00:00
Serial_ExchangeBytes::
2015-06-02 03:13:46 +00:00
ld a, 1
ldh [hSerialIgnoringInitialData], a
2015-06-02 03:13:46 +00:00
.loop
ld a, [hl]
ldh [hSerialSendData], a
2015-06-02 03:13:46 +00:00
call Serial_ExchangeByte
push bc
ld b, a
inc hl
ld a, 48
.waitLoop
dec a
jr nz, .waitLoop
ldh a, [hSerialIgnoringInitialData]
2015-06-02 03:13:46 +00:00
and a
ld a, b
pop bc
jr z, .storeReceivedByte
dec hl
cp SERIAL_PREAMBLE_BYTE
jr nz, .loop
xor a
ldh [hSerialIgnoringInitialData], a
2015-06-02 03:13:46 +00:00
jr .loop
.storeReceivedByte
ld [de], a
inc de
dec bc
ld a, b
or c
jr nz, .loop
ret
2016-06-12 00:24:04 +00:00
Serial_ExchangeByte::
2015-06-02 03:13:46 +00:00
xor a
ldh [hSerialReceivedNewData], a
ldh a, [hSerialConnectionStatus]
2015-06-02 03:13:46 +00:00
cp USING_INTERNAL_CLOCK
2016-06-12 18:35:21 +00:00
jr nz, .loop
2015-06-02 03:13:46 +00:00
ld a, START_TRANSFER_INTERNAL_CLOCK
ldh [rSC], a
2016-06-12 18:35:21 +00:00
.loop
ldh a, [hSerialReceivedNewData]
2015-06-02 03:13:46 +00:00
and a
2016-06-12 18:35:21 +00:00
jr nz, .ok
ldh a, [hSerialConnectionStatus]
2015-06-02 03:13:46 +00:00
cp USING_EXTERNAL_CLOCK
2016-06-12 18:35:21 +00:00
jr nz, .doNotIncrementUnknownCounter
2015-06-02 03:13:46 +00:00
call IsUnknownCounterZero
2016-06-12 18:35:21 +00:00
jr z, .doNotIncrementUnknownCounter
2015-06-02 03:13:46 +00:00
call WaitLoop_15Iterations
push hl
ld hl, wUnknownSerialCounter + 1
inc [hl]
2016-06-12 18:35:21 +00:00
jr nz, .noCarry
2015-06-02 03:13:46 +00:00
dec hl
inc [hl]
2016-06-12 18:35:21 +00:00
.noCarry
2015-06-02 03:13:46 +00:00
pop hl
call IsUnknownCounterZero
2016-06-12 18:35:21 +00:00
jr nz, .loop
2015-06-02 03:13:46 +00:00
jp SetUnknownCounterToFFFF
2016-06-12 18:35:21 +00:00
.doNotIncrementUnknownCounter
ldh a, [rIE]
2015-06-02 03:13:46 +00:00
and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
cp (1 << SERIAL)
2016-06-12 18:35:21 +00:00
jr nz, .loop
2015-06-02 03:13:46 +00:00
ld a, [wUnknownSerialCounter2]
dec a
ld [wUnknownSerialCounter2], a
2016-06-12 18:35:21 +00:00
jr nz, .loop
2015-06-02 03:13:46 +00:00
ld a, [wUnknownSerialCounter2 + 1]
dec a
ld [wUnknownSerialCounter2 + 1], a
2016-06-12 18:35:21 +00:00
jr nz, .loop
ldh a, [hSerialConnectionStatus]
2015-06-02 03:13:46 +00:00
cp USING_EXTERNAL_CLOCK
2016-06-12 18:35:21 +00:00
jr z, .ok
2015-06-02 03:13:46 +00:00
ld a, 255
.waitLoop
dec a
jr nz, .waitLoop
2016-06-12 18:35:21 +00:00
.ok
2015-06-02 03:13:46 +00:00
xor a
ldh [hSerialReceivedNewData], a
ldh a, [rIE]
2015-06-02 03:13:46 +00:00
and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
sub (1 << SERIAL)
2016-06-12 18:35:21 +00:00
jr nz, .skipReloadingUnknownCounter2
2015-06-02 03:13:46 +00:00
ld [wUnknownSerialCounter2], a
ld a, $50
ld [wUnknownSerialCounter2 + 1], a
2016-06-12 18:35:21 +00:00
.skipReloadingUnknownCounter2
ldh a, [hSerialReceiveData]
2015-06-02 03:13:46 +00:00
cp SERIAL_NO_DATA_BYTE
ret nz
call IsUnknownCounterZero
2016-06-12 18:35:21 +00:00
jr z, .done
2015-06-02 03:13:46 +00:00
push hl
ld hl, wUnknownSerialCounter + 1
ld a, [hl]
dec a
ld [hld], a
inc a
2016-06-12 18:35:21 +00:00
jr nz, .noBorrow
2015-06-02 03:13:46 +00:00
dec [hl]
2016-06-12 18:35:21 +00:00
.noBorrow
2015-06-02 03:13:46 +00:00
pop hl
call IsUnknownCounterZero
jr z, SetUnknownCounterToFFFF
2016-06-12 18:35:21 +00:00
.done
ldh a, [rIE]
2015-06-02 03:13:46 +00:00
and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
cp (1 << SERIAL)
ld a, SERIAL_NO_DATA_BYTE
ret z
ld a, [hl]
ldh [hSerialSendData], a
2015-06-02 03:13:46 +00:00
call DelayFrame
jp Serial_ExchangeByte
2016-06-12 00:24:04 +00:00
WaitLoop_15Iterations::
2015-06-02 03:13:46 +00:00
ld a, 15
.waitLoop
dec a
jr nz, .waitLoop
ret
2016-06-12 00:24:04 +00:00
IsUnknownCounterZero::
2015-06-02 03:13:46 +00:00
push hl
ld hl, wUnknownSerialCounter
ld a, [hli]
or [hl]
pop hl
ret
; a is always 0 when this is called
2016-06-12 00:24:04 +00:00
SetUnknownCounterToFFFF::
2015-06-02 03:13:46 +00:00
dec a
ld [wUnknownSerialCounter], a
ld [wUnknownSerialCounter + 1], a
ret
; This is used to exchange the button press and selected menu item on the link menu.
; The data is sent thrice and read twice to increase reliability.
2016-06-12 00:24:04 +00:00
Serial_ExchangeLinkMenuSelection::
2015-06-02 03:13:46 +00:00
ld hl, wLinkMenuSelectionSendBuffer
ld de, wLinkMenuSelectionReceiveBuffer
ld c, 2 ; number of bytes to save
ld a, 1
ldh [hSerialIgnoringInitialData], a
2015-06-02 03:13:46 +00:00
.loop
call DelayFrame
ld a, [hl]
ldh [hSerialSendData], a
2015-06-02 03:13:46 +00:00
call Serial_ExchangeByte
ld b, a
inc hl
ldh a, [hSerialIgnoringInitialData]
2015-06-02 03:13:46 +00:00
and a
ld a, 0
ldh [hSerialIgnoringInitialData], a
2015-06-02 03:13:46 +00:00
jr nz, .loop
ld a, b
ld [de], a
inc de
dec c
jr nz, .loop
ret
2016-06-12 00:24:04 +00:00
Serial_PrintWaitingTextAndSyncAndExchangeNybble::
2015-06-02 03:13:46 +00:00
call SaveScreenTilesToBuffer1
callfar PrintWaitingText
2015-06-02 03:13:46 +00:00
call Serial_SyncAndExchangeNybble
jp LoadScreenTilesFromBuffer1
2016-06-12 00:24:04 +00:00
Serial_SyncAndExchangeNybble::
vc_hook Wireless_WaitLinkTransfer
2015-06-02 03:13:46 +00:00
ld a, $ff
ld [wSerialExchangeNybbleReceiveData], a
.loop1
call Serial_ExchangeNybble
call DelayFrame
call IsUnknownCounterZero
jr z, .next1
push hl
ld hl, wUnknownSerialCounter + 1
dec [hl]
jr nz, .next2
dec hl
dec [hl]
jr nz, .next2
pop hl
xor a
jp SetUnknownCounterToFFFF
.next2
pop hl
.next1
ld a, [wSerialExchangeNybbleReceiveData]
inc a
jr z, .loop1
vc_patch Wireless_net_delay_3
IF DEF(_RED_VC) || DEF(_BLUE_VC)
ld b, 26
ELSE
2015-06-02 03:13:46 +00:00
ld b, 10
ENDC
vc_patch_end
2015-06-02 03:13:46 +00:00
.loop2
call DelayFrame
call Serial_ExchangeNybble
dec b
jr nz, .loop2
vc_patch Wireless_net_delay_4
IF DEF(_RED_VC) || DEF(_BLUE_VC)
ld b, 26
ELSE
2015-06-02 03:13:46 +00:00
ld b, 10
ENDC
vc_patch_end
2015-06-02 03:13:46 +00:00
.loop3
call DelayFrame
call Serial_SendZeroByte
dec b
jr nz, .loop3
ld a, [wSerialExchangeNybbleReceiveData]
ld [wSerialSyncAndExchangeNybbleReceiveData], a
vc_hook Wireless_WaitLinkTransfer_ret
2015-06-02 03:13:46 +00:00
ret
2016-06-12 00:24:04 +00:00
Serial_ExchangeNybble::
2015-06-02 03:13:46 +00:00
call .doExchange
ld a, [wSerialExchangeNybbleSendData]
add $60
ldh [hSerialSendData], a
ldh a, [hSerialConnectionStatus]
2015-06-02 03:13:46 +00:00
cp USING_INTERNAL_CLOCK
jr nz, .doExchange
ld a, START_TRANSFER_INTERNAL_CLOCK
ldh [rSC], a
2015-06-02 03:13:46 +00:00
.doExchange
ldh a, [hSerialReceiveData]
2015-06-02 03:13:46 +00:00
ld [wSerialExchangeNybbleTempReceiveData], a
and $f0
cp $60
ret nz
xor a
ldh [hSerialReceiveData], a
2015-06-02 03:13:46 +00:00
ld a, [wSerialExchangeNybbleTempReceiveData]
and $f
ld [wSerialExchangeNybbleReceiveData], a
ret
2016-06-12 00:24:04 +00:00
Serial_SendZeroByte::
2015-06-02 03:13:46 +00:00
xor a
ldh [hSerialSendData], a
ldh a, [hSerialConnectionStatus]
2015-06-02 03:13:46 +00:00
cp USING_INTERNAL_CLOCK
ret nz
ld a, START_TRANSFER_INTERNAL_CLOCK
ldh [rSC], a
2015-06-02 03:13:46 +00:00
ret
2016-06-12 00:24:04 +00:00
Serial_TryEstablishingExternallyClockedConnection::
2015-06-02 03:13:46 +00:00
ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK
ldh [rSB], a
2015-06-02 03:13:46 +00:00
xor a
ldh [hSerialReceiveData], a
2015-06-02 03:13:46 +00:00
ld a, START_TRANSFER_EXTERNAL_CLOCK
ldh [rSC], a
2015-06-02 03:13:46 +00:00
ret