Files
pico-loader/arm9/source/patches/platform/supercard/SuperCardCommon.s
2025-11-23 17:14:17 +01:00

120 lines
2.5 KiB
ArmAsm

.cpu arm7tdmi
.syntax unified
.section "scsd_common", "ax"
#include "asminc.h"
@ void sc_change_mode(uint16_t mode);
BEGIN_THUMB_FUNCTION sccmn_changeMode
ldr r2,= 0x09FFFFFE
ldr r3,= 0xA55A
strh r3, [r2]
strh r3, [r2]
strh r0, [r2]
strh r0, [r2]
mov pc,lr
@ this function will trash r4 but leave r0 and r1 untouched
@ void SDSendClock10(void)
BEGIN_THUMB_FUNCTION sccmn_sdSendClock10
movs r3, #0x10
@ loads reg_scsd_cmd
movs r2, #0x98
lsls r2, r2, #20
1:
ldrh r4, [r2]
subs r3, r3, #1
bne 1b
mov pc, lr
@ static uint64_t inline calSingleCRC16(uint64_t crc, uint32_t data_in){
@ // Shift out 8 bits for each line
@ uint32_t data_out = crc >> 32;
@ crc <<= 32;
@
@ // XOR outgoing data to itself with 4 bit delay
@ data_out ^= (data_out >> 16);
@
@ // XOR incoming data to outgoing data with 4 bit delay
@ data_out ^= (data_in >> 16);
@
@ // XOR outgoing and incoming data to accumulator at each tap
@ uint64_t xorred = data_out ^ data_in;
@ crc ^= xorred;
@ crc ^= xorred << (5 * 4);
@ crc ^= xorred << (12 * 4);
@ return crc;
@ }
@ uint64_t sdio_crc16_4bit_checksum(void* dataBuf)
@ {
@ uint32_t num_words = 512 / sizeof(uint32_t);
@ uint64_t crc = 0;
@ auto* data = static_cast<uint32_t*>(dataBuf);
@ auto* end = data + num_words;
@ while (data < end)
@ {
@ uint32_t data_in = __builtin_bswap32(*data++);
@ crc = calSingleCRC16(crc, data_in);
@ }
@
@ return __builtin_bswap64(crc);
@ }
@ uint64_t sdio_crc16_4bit_checksum(void*)
@ r0 and r1 are left untouched, the result is returned in r2-r3 instead
BEGIN_THUMB_FUNCTION sccmn_sdio4BitCrc16
push {r0,r1,r4-r5,lr}
movs r4, #0 @ r4 = crc_lo
movs r5, #0 @ r5 = crc_hi
movs r1, #128
1:
@ r5 = data_out
lsrs r3, r5, #16
eors r5, r3
ldmia r0!, {r2}
bl byteSwap32
@ r2 = data_in
lsrs r3, r2, #16
eors r5, r3
eors r2, r5 // r2 = xorred
movs r5, r4 // r5 = crc_hi
movs r4, r2 // r4 = crc_lo
lsls r3, r2, #20
eors r4, r3
lsrs r3, r2, #12
eors r5, r3
lsls r3, r2, #16
eors r5, r3
subs r1, #1
bne 1b
movs r2, r4
bl byteSwap32
movs r3, r2
movs r2, r5
@falls through to perform a "final" byteSwap32 call
b byteSwap32_nopush
byteSwap32:
push {r0,r1,r4-r5,lr}
byteSwap32_nopush:
movs r5, #16
ldr r4,= 0xFF00FF
rors r2, r5 // ror 16
ands r4, r2
bics r2, r4
lsls r4, r4, #8
lsrs r2, r2, #8
orrs r2, r4
pop {r0,r1,r4-r5,pc}
.balign 4
.pool