2023-10-14 17:49:00 +08:00

149 lines
4.5 KiB
ArmAsm

/*
* This file is part of open_agb_firm
* Copyright (C) 2021 derrek, profi200
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "asm_macros.h"
#include "mem_map.h"
.syntax unified
.cpu mpcore
.fpu vfpv2
@ void lgyLinkRecv16(u16 *dst, u32 size)
BEGIN_ASM_FUNC lgyLinkRecv16
add r1, r0, r1 @ r1 = r0 + r1;
ldr r12, =0x10141100 @ r12 = &REG_LGY11_MODE; // Base address.
mov r2, #0 @ All buttons pressed (start signal).
mov r3, #0xFFFFFFFF @ Override all buttons. Should be 0x3FF but his works too.
strh r2, [r12, #0x12] @ REG_LGY11_PAD_VAL = r2;
cpsid i @ Disable IRQs. Timing is critical.
strh r3, [r12, #0x10] @ REG_LGY11_PAD_SEL = r3;
lgyLinkRecv16_byte1_lp:
ldrh r2, [r12, #0x0A] @ r2 = REG_LGY11_PADCNT;
tst r2, #1<<8
beq lgyLinkRecv16_byte1_lp @ while(!(r2 & 1u<<8));
uxtb r2, r2 @ r2 = r2 & 0xFFu;
lgyLinkRecv16_byte2_lp:
ldrh r3, [r12, #0x0A] @ r3 = REG_LGY11_PADCNT;
tst r3, #1<<8
bne lgyLinkRecv16_byte2_lp @ while(r3 & 1u<<8);
orr r2, r2, r3, lsl #8 @ r2 = r3<<8 | r2;
strh r2, [r0], #2 @ *r0++ = r2;
cmp r1, r0
bhi lgyLinkRecv16_byte1_lp @ while(r0 < r1);
cpsie i @ Enable IRQs.
bx lr
END_ASM_FUNC
@ void lgyLinkRecv32(u32 *dst, u32 size)
BEGIN_ASM_FUNC lgyLinkRecv32
add r1, r0, r1 @ r1 = r0 + r1;
ldr r12, =0x10141100 @ r12 = &REG_LGY11_MODE; // Base address.
mov r2, #0 @ All buttons pressed (start signal).
mov r3, #0xFFFFFFFF @ Override all buttons. Should be 0x3FF but his works too.
strh r2, [r12, #0x12] @ REG_LGY11_PAD_VAL = r2;
cpsid i @ Disable IRQs. Timing is critical.
strh r3, [r12, #0x10] @ REG_LGY11_PAD_SEL = r3;
lgyLinkRecv32_byte1_lp:
ldrh r2, [r12, #0x0A] @ r2 = REG_LGY11_PADCNT;
tst r2, #1<<8
beq lgyLinkRecv32_byte1_lp @ while(!(r2 & 1u<<8));
uxtb r2, r2 @ r2 = r2 & 0xFFu;
lgyLinkRecv32_byte2_lp:
ldrh r3, [r12, #0x0A] @ r3 = REG_LGY11_PADCNT;
tst r3, #1<<8
bne lgyLinkRecv32_byte2_lp @ while(r3 & 1u<<8);
orr r2, r2, r3, lsl #8 @ r2 = r3<<8 | r2;
lgyLinkRecv32_byte3_lp:
ldrh r3, [r12, #0x0A] @ r3 = REG_LGY11_PADCNT;
tst r3, #1<<8
beq lgyLinkRecv32_byte3_lp @ while(!(r3 & 1u<<8));
bic r3, r3, #1<<8 @ r3 &= ~(1u<<8);
orr r2, r2, r3, lsl #16 @ r2 = r3<<16 | r2;
lgyLinkRecv32_byte4_lp:
ldrh r3, [r12, #0x0A] @ r3 = REG_LGY11_PADCNT;
tst r3, #1<<8
bne lgyLinkRecv32_byte4_lp @ while(r3 & 1u<<8);
orr r2, r2, r3, lsl #24 @ r2 = r3<<24 | r2;
str r2, [r0], #4 @ *r0++ = r2;
cmp r1, r0
bhi lgyLinkRecv32_byte1_lp @ while(r0 < r1);
cpsie i @ Enable IRQs.
bx lr
END_ASM_FUNC
@ void lgyLinkSend32(const u32 *src, u32 size)
BEGIN_ASM_FUNC lgyLinkSend32
add r1, r0, r1 @ r1 = r0 + r1;
ldr r12, =0x10141100 @ r12 = &REG_LGY11_MODE; // Base address.
mov r2, #0 @ All buttons pressed (start signal).
mov r3, #0xFFFFFFFF @ Override all buttons. Should be 0x3FF but his works too.
strh r2, [r12, #0x12] @ REG_LGY11_PAD_VAL = r2;
cpsid i @ Disable IRQs. Timing is critical.
strh r3, [r12, #0x10] @ REG_LGY11_PAD_SEL = r3;
lgyLinkSend32_word_lp:
ldr r2, [r0], #4
strh r2, [r12, #0x12]
lsr r2, r2, #8
lgyLinkSend32_byte1_lp:
ldrh r3, [r12, #0x0A]
cmp r3, #0xFF
bne lgyLinkSend32_byte1_lp
strh r2, [r12, #0x12]
lsr r2, r2, #8
lgyLinkSend32_byte2_lp:
ldrh r3, [r12, #0x0A]
cmp r3, #0xFF
beq lgyLinkSend32_byte2_lp
strh r2, [r12, #0x12]
lsr r2, r2, #8
lgyLinkSend32_byte3_lp:
ldrh r3, [r12, #0x0A]
cmp r3, #0xFF
bne lgyLinkSend32_byte3_lp
strh r2, [r12, #0x12]
lsr r2, r2, #8
lgyLinkSend32_byte4_lp:
ldrh r3, [r12, #0x0A]
cmp r3, #0xFF
beq lgyLinkSend32_byte4_lp
cmp r1, r0
bhi lgyLinkSend32_word_lp @ while(r0 < r1);
bx lr
END_ASM_FUNC