123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- Serial::
- push af
- push bc
- push de
- push hl
- ld a, [hSerialConnectionStatus]
- inc a
- jr z, .connectionNotYetEstablished
- ld a, [rSB]
- ld [hSerialReceiveData], a
- ld a, [hSerialSendData]
- ld [rSB], a
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK
- jr z, .done
- ; using external clock
- ld a, START_TRANSFER_EXTERNAL_CLOCK
- ld [rSC], a
- jr .done
- .connectionNotYetEstablished
- ld a, [rSB]
- ld [hSerialReceiveData], a
- ld [hSerialConnectionStatus], a
- cp USING_INTERNAL_CLOCK
- jr z, .usingInternalClock
- ; using external clock
- xor a
- ld [rSB], a
- ld a, $3
- ld [rDIV], a
- .waitLoop
- ld a, [rDIV]
- bit 7, a
- jr nz, .waitLoop
- ld a, START_TRANSFER_EXTERNAL_CLOCK
- ld [rSC], a
- jr .done
- .usingInternalClock
- xor a
- ld [rSB], a
- .done
- ld a, $1
- ld [hSerialReceivedNewData], a
- ld a, SERIAL_NO_DATA_BYTE
- ld [hSerialSendData], a
- pop hl
- pop de
- pop bc
- pop af
- reti
- ; hl = send data
- ; de = receive data
- ; bc = length of data
- Serial_ExchangeBytes::
- ld a, 1
- ld [hSerialIgnoringInitialData], a
- .loop
- ld a, [hl]
- ld [hSerialSendData], a
- call Serial_ExchangeByte
- push bc
- ld b, a
- inc hl
- ld a, 48
- .waitLoop
- dec a
- jr nz, .waitLoop
- ld a, [hSerialIgnoringInitialData]
- and a
- ld a, b
- pop bc
- jr z, .storeReceivedByte
- dec hl
- cp SERIAL_PREAMBLE_BYTE
- jr nz, .loop
- xor a
- ld [hSerialIgnoringInitialData], a
- jr .loop
- .storeReceivedByte
- ld [de], a
- inc de
- dec bc
- ld a, b
- or c
- jr nz, .loop
- ret
- Serial_ExchangeByte::
- xor a
- ld [hSerialReceivedNewData], a
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK
- jr nz, .loop
- ld a, START_TRANSFER_INTERNAL_CLOCK
- ld [rSC], a
- .loop
- ld a, [hSerialReceivedNewData]
- and a
- jr nz, .ok
- ld a, [hSerialConnectionStatus]
- cp USING_EXTERNAL_CLOCK
- jr nz, .doNotIncrementUnknownCounter
- call IsUnknownCounterZero
- jr z, .doNotIncrementUnknownCounter
- call WaitLoop_15Iterations
- push hl
- ld hl, wUnknownSerialCounter + 1
- inc [hl]
- jr nz, .noCarry
- dec hl
- inc [hl]
- .noCarry
- pop hl
- call IsUnknownCounterZero
- jr nz, .loop
- jp SetUnknownCounterToFFFF
- .doNotIncrementUnknownCounter
- ld a, [rIE]
- and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
- cp (1 << SERIAL)
- jr nz, .loop
- ld a, [wUnknownSerialCounter2]
- dec a
- ld [wUnknownSerialCounter2], a
- jr nz, .loop
- ld a, [wUnknownSerialCounter2 + 1]
- dec a
- ld [wUnknownSerialCounter2 + 1], a
- jr nz, .loop
- ld a, [hSerialConnectionStatus]
- cp USING_EXTERNAL_CLOCK
- jr z, .ok
- ld a, 255
- .waitLoop
- dec a
- jr nz, .waitLoop
- .ok
- xor a
- ld [hSerialReceivedNewData], a
- ld a, [rIE]
- and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
- sub (1 << SERIAL)
- jr nz, .skipReloadingUnknownCounter2
- ld [wUnknownSerialCounter2], a
- ld a, $50
- ld [wUnknownSerialCounter2 + 1], a
- .skipReloadingUnknownCounter2
- ld a, [hSerialReceiveData]
- cp SERIAL_NO_DATA_BYTE
- ret nz
- call IsUnknownCounterZero
- jr z, .done
- push hl
- ld hl, wUnknownSerialCounter + 1
- ld a, [hl]
- dec a
- ld [hld], a
- inc a
- jr nz, .noBorrow
- dec [hl]
- .noBorrow
- pop hl
- call IsUnknownCounterZero
- jr z, SetUnknownCounterToFFFF
- .done
- ld a, [rIE]
- and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
- cp (1 << SERIAL)
- ld a, SERIAL_NO_DATA_BYTE
- ret z
- ld a, [hl]
- ld [hSerialSendData], a
- call DelayFrame
- jp Serial_ExchangeByte
- WaitLoop_15Iterations::
- ld a, 15
- .waitLoop
- dec a
- jr nz, .waitLoop
- ret
- IsUnknownCounterZero::
- push hl
- ld hl, wUnknownSerialCounter
- ld a, [hli]
- or [hl]
- pop hl
- ret
- ; a is always 0 when this is called
- SetUnknownCounterToFFFF::
- 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.
- Serial_ExchangeLinkMenuSelection::
- ld hl, wLinkMenuSelectionSendBuffer
- ld de, wLinkMenuSelectionReceiveBuffer
- ld c, 2 ; number of bytes to save
- ld a, 1
- ld [hSerialIgnoringInitialData], a
- .loop
- call DelayFrame
- ld a, [hl]
- ld [hSerialSendData], a
- call Serial_ExchangeByte
- ld b, a
- inc hl
- ld a, [hSerialIgnoringInitialData]
- and a
- ld a, 0
- ld [hSerialIgnoringInitialData], a
- jr nz, .loop
- ld a, b
- ld [de], a
- inc de
- dec c
- jr nz, .loop
- ret
- Serial_PrintWaitingTextAndSyncAndExchangeNybble::
- call SaveScreenTilesToBuffer1
- callab PrintWaitingText
- call Serial_SyncAndExchangeNybble
- jp LoadScreenTilesFromBuffer1
- Serial_SyncAndExchangeNybble::
- 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
- ld b, 10
- .loop2
- call DelayFrame
- call Serial_ExchangeNybble
- dec b
- jr nz, .loop2
- ld b, 10
- .loop3
- call DelayFrame
- call Serial_SendZeroByte
- dec b
- jr nz, .loop3
- ld a, [wSerialExchangeNybbleReceiveData]
- ld [wSerialSyncAndExchangeNybbleReceiveData], a
- ret
- Serial_ExchangeNybble::
- call .doExchange
- ld a, [wSerialExchangeNybbleSendData]
- add $60
- ld [hSerialSendData], a
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK
- jr nz, .doExchange
- ld a, START_TRANSFER_INTERNAL_CLOCK
- ld [rSC], a
- .doExchange
- ld a, [hSerialReceiveData]
- ld [wSerialExchangeNybbleTempReceiveData], a
- and $f0
- cp $60
- ret nz
- xor a
- ld [hSerialReceiveData], a
- ld a, [wSerialExchangeNybbleTempReceiveData]
- and $f
- ld [wSerialExchangeNybbleReceiveData], a
- ret
- Serial_SendZeroByte::
- xor a
- ld [hSerialSendData], a
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK
- ret nz
- ld a, START_TRANSFER_INTERNAL_CLOCK
- ld [rSC], a
- ret
- Serial_TryEstablishingExternallyClockedConnection::
- ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK
- ld [rSB], a
- xor a
- ld [hSerialReceiveData], a
- ld a, START_TRANSFER_EXTERNAL_CLOCK
- ld [rSC], a
- ret
|