499 lines
25 KiB
Plaintext
499 lines
25 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////
|
|
ROM functions used:
|
|
0x8000 dsp reset
|
|
0x8078 wait for CMBH & 0x8000
|
|
0x807e wait for DMBH & 0x8000
|
|
0x808b dump DRAM/IRAM to mainmem
|
|
0x80b5 boot new ucode
|
|
0x80bc boot new ucode without ACC clearing by ROM
|
|
|
|
For the rest, this ucode is just calling the last few instructions
|
|
from huge functions in irom - some kind of obfuscation
|
|
Perhaps someone thought the irom would never be dumped? ;p
|
|
|
|
Similarly, drom is used pretty extensively as a source of what is intended to
|
|
be "mystery" numbers. Usually a word will be fetched, and masked to create a
|
|
simple value. No problem! :)
|
|
|
|
0x81f4
|
|
mulxac'mv $AX0.H, $AX1.L, $ACC1 : $AX1.H, $AC0.M
|
|
asr16'ir $ACC1 : $AR1
|
|
srri @$AR3, $AC1.M
|
|
clr's $ACC0 : @$AR3, $AC1.L
|
|
0x8458
|
|
mulxac'mv $AX0.H, $AX1.L, $ACC1 : $AX1.H, $AC0.M
|
|
asr16 $ACC1
|
|
srri @$AR3, $AC1.M
|
|
clr's $ACC0 : @$AR3, $AC1.L
|
|
0x8723
|
|
xorr $AC1.M, $AX1.H
|
|
srrd @$AR2, $AC1.M
|
|
0x8809
|
|
orr'sn $AC1.M, $AX0.H : @$AR2, $AC1.L
|
|
srri @$AR2, $AC1.M
|
|
0x88e5
|
|
orr'l $AC0.M, $AX0.H : $AC1.M, @$AR2
|
|
lrrd $AC1.L, @$AR2
|
|
add'dr $ACC0, $ACC1 : $AR1
|
|
srri @$AR2, $AC0.M
|
|
srr @$AR2, $AC0.L
|
|
|
|
struct sec_params_t
|
|
{
|
|
u32 key; // from gba
|
|
u32 unk1; // normally 2
|
|
u32 unk2; // normally 2
|
|
u32 length; // size of data transferred to gba
|
|
u32 dest_addr; // addr to store result in mram
|
|
u32 pad[3];
|
|
}
|
|
|
|
// exception vector
|
|
0000 0000 nop
|
|
0001 0000 nop
|
|
0002 0000 nop
|
|
0003 0000 nop
|
|
0004 0000 nop
|
|
0005 0000 nop
|
|
0006 0000 nop
|
|
0007 0000 nop
|
|
0008 0000 nop
|
|
0009 0000 nop
|
|
000a 0000 nop
|
|
000b 0000 nop
|
|
000c 0000 nop
|
|
000d 0021 halt
|
|
000e 02ff rti
|
|
000f 0021 halt
|
|
|
|
// entry point
|
|
void 0010_main()
|
|
{
|
|
0010 1306 sbset #0x06
|
|
0011 1203 sbclr #0x03
|
|
0012 1204 sbclr #0x04
|
|
0013 1305 sbset #0x05
|
|
0014 0092 00ff lri $CR, #0x00ff
|
|
0016 0088 ffff lri $WR0, #0xffff
|
|
0018 0089 ffff lri $WR1, #0xffff
|
|
001a 008a ffff lri $WR2, #0xffff
|
|
001c 008b ffff lri $WR3, #0xffff
|
|
001e 8f00 set40
|
|
001f 8b00 m0
|
|
0020 8c00 clr15
|
|
0021 02bf 807e call 0x807e // loop until dsp->cpu mailbox is empty
|
|
0023 16fc dcd1 si @DMBH, #0xdcd1
|
|
0025 16fd 0000 si @DMBL, #0x0000 // sendmail 0xdcd10000
|
|
0027 16fb 0001 si @DIRQ, #0x0001
|
|
|
|
// wait for cpu mail == 0xabbaxxxx
|
|
0029 02bf 8078 call 0x8078 // wait for cpu mail
|
|
002b 24ff lrs $AC0.L, @CMBL
|
|
002c 0280 abba cmpi $AC0.M, #0xabba
|
|
002e 0294 0029 jnz 0x0029
|
|
|
|
// wait for cpu mail
|
|
0030 8e00 set16
|
|
0031 02bf 8078 call 0x8078
|
|
|
|
0033 20ff lrs $AX0.L, @CMBL
|
|
0034 0240 0fff andi $AC0.M, #0x0fff
|
|
0036 1f5e mrr $AX0.H, $AC0.M
|
|
0037 009b 0000 lri $AX1.H, #0x0000 // DSP-dram addr
|
|
0039 0099 0020 lri $AX1.L, #0x0020 // length (20 bytes = 10 words, word 9 and 10 are addr where result should DMA'd to in main mem)
|
|
003b 0087 0000 lri $IX3, #0x0000 // there will be no ucode/iram upload
|
|
003d 0080 0041 lri $AR0, #0x0041 // return addr after dram upload
|
|
003f 029f 80bc jmp 0x80bc // DRAM upload !!
|
|
// $AX0.H-$AX0.L - CPU(PPC) addr = mail & 0x0fffffff
|
|
// upload data from mainmem do dsp dram and jump to 0x41 after that
|
|
|
|
0041 02bf 008c call 008c_BigCrazyFunction()
|
|
0043 02bf 807e call 0x807e // loop until dsp->cpu mailbox is empty
|
|
|
|
0045 16fc dcd1 si @DMBH, #0xdcd1
|
|
0047 16fd 0003 si @DMBL, #0x0003 // sendmail 0xdcd10003 (aka... calc is over, result is in main mem now)
|
|
0049 16fb 0001 si @DIRQ, #0x0001
|
|
004b 8f00 set40
|
|
|
|
004c 02bf 8078 call 0x8078
|
|
004e 0280 cdd1 cmpi $AC0.M, #0xcdd1
|
|
0050 0294 004c jnz 0x004c
|
|
|
|
0052 26ff lrs $AC0.M, @CMBL
|
|
0053 0280 0001 cmpi $AC0.M, #0x0001
|
|
0055 0295 005e jz 0x005e // if cpu->dsp mail was 0xcdd10001 -> 005e_PrepareBootUcode()
|
|
|
|
0057 0280 0002 cmpi $AC0.M, #0x0002
|
|
0059 0295 8000 jz 0x8000 // if cpu->dsp mail was 0xcdd10002 -> dsp reset ( jmp to irom(0x8000))
|
|
|
|
005b 029f 004c jmp 0x004c // wait for next mail from cpu
|
|
005d 0021 halt
|
|
}
|
|
|
|
void 005e_PrepareBootUcode()
|
|
{
|
|
005e 8e00 set16
|
|
005f 02bf 8078 call 0x8078
|
|
0061 24ff lrs $AC0.L, @CMBL // ???
|
|
0062 02bf 8078 call 0x8078
|
|
0064 24ff lrs $AC0.L, @CMBL // ???
|
|
0065 02bf 8078 call 0x8078
|
|
0067 24ff lrs $AC0.L, @CMBL // ???
|
|
0068 02bf 8078 call 0x8078
|
|
006a 00c5 ffff lr $IX1, @CMBL
|
|
006c 0240 0fff andi $AC0.M, #0x0fff
|
|
006e 1c9e mrr $IX0, $AC0.M // mram addr for iram
|
|
006f 02bf 8078 call 0x8078
|
|
0071 00c7 ffff lr $IX3, @CMBL // iram upload length. upload skipped if 0
|
|
0073 02bf 8078 call 0x8078
|
|
0075 00c6 ffff lr $IX2, @CMBL // iram dest
|
|
0077 02bf 8078 call 0x8078
|
|
0079 00c0 ffff lr $AR0, @CMBL // startpc / return addr
|
|
007b 02bf 8078 call 0x8078
|
|
007d 20ff lrs $AX0.L, @CMBL
|
|
007e 0240 0fff andi $AC0.M, #0x0fff
|
|
0080 1f5e mrr $AX0.H, $AC0.M // mram addr for dram
|
|
0081 02bf 8078 call 0x8078
|
|
0083 21ff lrs $AX1.L, @CMBL // dram upload length. upload skipped if 0
|
|
0084 02bf 8078 call 0x8078
|
|
0086 23ff lrs $AX1.H, @CMBL // dram dest
|
|
0087 1205 sbclr #0x05
|
|
0088 1206 sbclr #0x06
|
|
0089 029f 80b5 jmp 80b5_BootUcode()
|
|
008b 0021 halt
|
|
}
|
|
|
|
// does some crazy stuff with data at dram @0x3/0x5/0x6/0x7 with help of some values from drom :)
|
|
// result is @0x22,@0x23 and written back to main memory to dmem-0x08:dmem-0x09
|
|
void 008c_BigCrazyFunction()
|
|
{
|
|
// 008c 8100 clr $ACC0
|
|
// 008d 0081 0010 lri $AR1, #0x0010
|
|
// 008f 1020 loopi #0x20
|
|
// 0090 1b3e srri @$AR1, $AC0.M
|
|
memset(0x10, 0, 0x20 * sizeof(dsp_word));
|
|
|
|
// 0091 00df 1456 lr $AC1.M, @0x1456 // drom 102f
|
|
// 0093 0340 ffd0 andi $AC1.M, #0xffd0 // -> 0x1000
|
|
// 0095 8417 clrp'mv : $AX1.L, $AC1.M // clrp, ax1.l = 0x1000
|
|
IMPORTANT: "confusing" section relies on prod being cleared, and ax1.l == 0x1000
|
|
|
|
// 0096 0080 0000 lri $AR0, #0x0000
|
|
// 0098 0086 0000 lri $IX2, #0x0000
|
|
// 009a 0082 001f lri $AR2, #0x001f
|
|
// 009c 00de 15f6 lr $AC0.M, @0x15f6 // drom 7f65
|
|
// 009e 1408 lsl $ACC0, #8 // -> 0x7f_6500
|
|
// 009f 00df 1766 lr $AC1.M, @0x1766 // drom 0273
|
|
// 00a1 0340 00ff andi $AC1.M, #0x00ff // -> 0x73
|
|
// 00a3 1f5f mrr $AX0.H, $AC1.M // ax0.h = 0x73
|
|
// 00a4 02bf 88e5 call 0x88e5 // ar2 = 0x1f, ar1 = 0x30
|
|
// orr'l $AC0.M, $AX0.H : $AC1.M, @$AR2 // acc0 = 0x7f_6573, ac1.m = 0, ar2 = 0x20
|
|
// lrrd $AC1.L, @$AR2 // ac1.l = 0, ar2 = 0x1f
|
|
// add'dr $ACC0, $ACC1 : $AR1
|
|
// srri @$AR2, $AC0.M // *0x1f = 0x6573, ar2 = 0x20
|
|
// srr @$AR2, $AC0.L // *0x20 = 0
|
|
// 00a6 1f1c mrr $AX0.L, $AC0.L // ax0.l = 0
|
|
// 00a7 811e clr'mv $ACC0 : $AX1.H, $AC0.M // acc0 = 0, ax1.h = 0x6573
|
|
// 00a8 191e lrri $AC0.M, @$AR0 // ac0.m = sec_params.key[0], ar1 = 1
|
|
// 00a9 1478 lsr $ACC0, #-8 // acc0 0x00_00.._..00
|
|
// 00aa 1ffc mrr $AC1.M, $AC0.L // ac1.m = sec_params.key[0] & 0x00ff
|
|
// 00ab 1f5e mrr $AX0.H, $AC0.M // ax0.h = sec_params.key[0] >> 8
|
|
// 00ac 02bf 8809 call 0x8809
|
|
// orr'sn $AC1.M, $AX0.H : @$AR2, $AC1.L // ac1.m |= ax0.h ..tricky tricky :D
|
|
// srri @$AR2, $AC1.M // *0x20 = bswap(sec_params.key[0]), ar2 = 0x21
|
|
// 00ae 02bf 8723 call 0x8723
|
|
// xorr $AC1.M, $AX1.H // ac1.m = sec_params.key[0] ^ 0x6573
|
|
// srrd @$AR2, $AC1.M // *0x21 = bswap(sec_params.key[0]) ^ 0x6573, ar2 = 0x20
|
|
// Initialize 0x21
|
|
*0x1f = 0x6573
|
|
*0x20 = bswap(sec_params.key[0])
|
|
*0x21 = bswap(sec_params.key[0]) ^ 0x6573
|
|
|
|
// 00b0 0006 dar $AR2 // ar2 = 0x1f
|
|
// 00b1 8106 clr'dr $ACC0 : $AR2 // acc0 = 0, ar2 = 0x1e
|
|
// 00b2 00de 166c lr $AC0.M, @0x166c // drom 06f2
|
|
// 00b4 1404 lsl $ACC0, #4
|
|
// 00b5 0240 ff00 andi $AC0.M, #0xff00 // -> 0x6f00
|
|
// 00b7 00df 1231 lr $AC1.M, @0x1231 // drom 64fc
|
|
// 00b9 1578 lsr $ACC1, #-8
|
|
// 00ba 0340 00ff andi $AC1.M, #0x00ff // -> 0x64
|
|
// 00bc 1f5f mrr $AX0.H, $AC1.M // ax0.h = 0x64
|
|
// 00bd 02bf 88e5 call 0x88e5
|
|
// orr'l $AC0.M, $AX0.H : $AC1.M, @$AR2 // ac0.m = 0x6f64, ac1.m = 0, ar2 = 0x1f
|
|
// lrrd $AC1.L, @$AR2 // ac1.l = 0x6573, ar2 = 0x1e
|
|
// add'dr $ACC0, $ACC1 : $AR1 // acc0 = 0x00_6f64_6573
|
|
// srri @$AR2, $AC0.M // *0x1e = 0x6f64, ar2 = 0x1f
|
|
// srr @$AR2, $AC0.L // *0x1f = 0x6573
|
|
// 00bf 1f1c mrr $AX0.L, $AC0.L
|
|
// 00c0 811e clr'mv $ACC0 : $AX1.H, $AC0.M // acc0 = 0, ax1.h = 0x6f64
|
|
// 00c1 191e lrri $AC0.M, @$AR0 // ac0.m = sec_params.key[1]
|
|
// 00c2 1478 lsr $ACC0, #-8 // acc0 = 0x00_00.._..00
|
|
// 00c3 1ffc mrr $AC1.M, $AC0.L // ac1.m = sec_params.key[1] & 0xff
|
|
// 00c4 1f5e mrr $AX0.H, $AC0.M // ax0.h = sec_params.key[1] >> 8
|
|
// 00c5 02bf 8809 call 0x8809
|
|
// orr'sn $AC1.M, $AX0.H : @$AR2, $AC1.L // ac1.m |= ax0.h
|
|
// srri @$AR2, $AC1.M // *0x1f = bswap(sec_params.key[1]), ar2 = 0x20
|
|
// 00c7 02bf 8723 call 0x8723
|
|
// xorr $AC1.M, $AX1.H
|
|
// srrd @$AR2, $AC1.M // *0x20 = bswap(sec_params.key[1]) ^ 0x6f64
|
|
// Initialize 0x20
|
|
*0x1e = 0x6f64
|
|
*0x1f = bswap(sec_params.key[1])
|
|
*0x20 = bswap(sec_params.key[1]) ^ 0x6f64
|
|
|
|
// Initialize 0x11
|
|
// 00c9 8100 clr $ACC0
|
|
// 00ca 8900 clr $ACC1
|
|
// 00cb 00d1 0005 lr $AC1.H, @0x0005
|
|
// 00cd 9900 asr16 $ACC1 // s16 unk2 = (s8)(sec_params.unk2[1])
|
|
// 00ce 8200 cmp
|
|
// 00cf 0295 00e5 jz 0x00e5
|
|
// 00d1 0291 00f3 jl 0x00f3
|
|
if (unk2 < 0) {
|
|
// 00d3 0082 0010 lri $AR2, #0x0010
|
|
// 00d5 0086 0001 lri $IX2, #0x0001 // 'sn will inc ar2 by 1
|
|
// 00d7 00d0 171b lr $AC0.H, @0x171b // drom ff03
|
|
// 00d9 9100 asr16 $ACC0 // -> 0x00_0003_0000
|
|
// 00da 7d00 neg $ACC1
|
|
// 00db 4d00 add $ACC1, $ACC0
|
|
// 00dc 1501 lsl $ACC1, #1
|
|
// 00dd 1f5f mrr $AX0.H, $AC1.M // ax0.h = ((~unk2 + 3) << 1) & 0xffff
|
|
// 00de 00df 0003 lr $AC1.M, @0x0003 // sec_params.unk1[1]
|
|
// 00e0 1504 lsl $ACC1, #4
|
|
// 00e1 02bf 8809 call 0x8809
|
|
// orr'sn $AC1.M, $AX0.H : @$AR2, $AC1.L // ac1.m = (((~unk2 + 3) << 1) & 0xffff) | (sec_params.unk1[1] << 4), ar2 = 0x11
|
|
// srri @$AR2, $AC1.M
|
|
// 00e3 029f 0102 jmp 0x0102
|
|
*0x11 = (((~unk2 + 3) << 1) | (sec_params.unk1[1] << 4)) & 0xffff
|
|
|
|
} else if (unk2 == 0) {
|
|
// unk2 is unused
|
|
// 00e5 0082 0011 lri $AR2, #0x0011
|
|
// 00e7 00df 0003 lr $AC1.M, @0x0003 // sec_params.unk1[1]
|
|
// 00e9 1501 lsl $ACC1, #1
|
|
// 00ea 1f5f mrr $AX0.H, $AC1.M // ax0.h = sec_params.unk1[1] << 1
|
|
// 00eb 00de 1043 lr $AC0.M, @0x1043 // drom 0076
|
|
// 00ed 0240 fff0 andi $AC0.M, #0xfff0 // -> 0x70
|
|
// 00ef 02bf 88e5 call 0x88e5
|
|
// orr'l $AC0.M, $AX0.H : $AC1.M, @$AR2 // ac0.m = (sec_params.unk1[1] << 1) | 0x70, ac1.m = 0, ar2 = 0x12
|
|
// lrrd $AC1.L, @$AR2 // ar2 = 0x11
|
|
// add'dr $ACC0, $ACC1 : $AR1 // acc1 must be 0
|
|
// srri @$AR2, $AC0.M // *0x11 = (sec_params.unk1[1] << 1) | 0x70, ar2 = 0x12
|
|
// srr @$AR2, $AC0.L // *0x12 = 0 // just a side effect, it's already 0 anyways
|
|
// 00f1 029f 0102 jmp 0x0102
|
|
*0x11 = ((sec_params.unk1[1] << 1) | 0x70) & 0xffff
|
|
|
|
} else if (unk2 > 0) {
|
|
// 00f3 0082 0010 lri $AR2, #0x0010
|
|
// 00f5 0086 0001 lri $IX2, #0x0001 // 'sn will inc ar2 by 1
|
|
// 00f7 00d0 1285 lr $AC0.H, @0x1285 // drom 5aff (0xffff because of .h)
|
|
// 00f9 9100 asr16 $ACC0 // -> 0xff_ffff_0000 = -1
|
|
// 00fa 4d00 add $ACC1, $ACC0 // ac1.m = unk2 - 1
|
|
// 00fb 1501 lsl $ACC1, #1 // ac1.m <<= 1 ..in the normal case, this makes it 2 again...
|
|
// 00fc 00de 0003 lr $AC0.M, @0x0003 // sec_params.unk1[1]
|
|
// 00fe 1404 lsl $ACC0, #4
|
|
// 00ff 1f5e mrr $AX0.H, $AC0.M // ax0.h = sec_params.unk1[1] << 4
|
|
// 0100 02bf 8809 call 0x8809
|
|
// orr'sn $AC1.M, $AX0.H : @$AR2, $AC1.L // ac1.m = ((unk2 - 1) << 1) | (sec_params.unk1[1] << 4), ar2 = 0x11
|
|
// srri @$AR2, $AC1.M
|
|
*0x11 = (((unk2 - 1) << 1) | (sec_params.unk1[1] << 4)) & 0xffff
|
|
}
|
|
|
|
// This just clears acc1
|
|
// 0102 0083 0013 lri $AR3, #0x0013
|
|
// 0104 1b7e srri @$AR3, $AC0.M // *0x13 = intermediate from above -> unused
|
|
// 0105 8923 clr's $ACC1 : @$AR3, $AC0.L // acc1 = 0, *0x14 = intermediate from above -> unused
|
|
|
|
// The "confusion"
|
|
// 0106 0083 0013 lri $AR3, #0x0013
|
|
// 0108 00df 0007 lr $AC1.M, @0x0007 // ac1.m = sec_params.length[1]
|
|
// 010a 00de 11b8 lr $AC0.M, @0x11b8 // drom 007f
|
|
// 010c 0240 fff0 andi $AC0.M, #0xfff0 // -> 0x70
|
|
// 010e 1f5e mrr $AX0.H, $AC0.M // ax0.h = 0x70
|
|
// 010f 02bf 81f4 call 0x81f4
|
|
// mulxac'mv $AX0.H, $AX1.L, $ACC1 : $AX1.H, $AC0.M// prod = 0x70 * 0x1000 : .m1 = 7
|
|
// asr16'ir $ACC1 : $AR1 // ac1.l = sec_params.length[1], the rest of acc1 must be 0
|
|
// srri @$AR3, $AC1.M // *0x13 = 0, ar3 = 0x14
|
|
// clr's $ACC0 : @$AR3, $AC1.L // acc0 = 0, *0x14 = sec_params.length[1], ar3 = 0x15
|
|
//
|
|
// 0111 f100 lsl16 $ACC1 // ac1.m = sec_params.length[1]
|
|
// 0112 02bf 8458 call 0x8458 // this is the same routine, just adds 7 and stores to different location
|
|
// mulxac'mv $AX0.H, $AX1.L, $ACC1 : $AX1.H, $AC0.M// acc1 += 7 // last prod has 7 in the mid
|
|
// asr16 $ACC1 // ac1.l = sec_params.length[1] + 7
|
|
// srri @$AR3, $AC1.M // *0x15 = 0, ar3 = 0x16
|
|
// clr's $ACC0 : @$AR3, $AC1.L // *0x16 = sec_params.length[1] + 7
|
|
*0x13 = 0
|
|
*0x14 = sec_params.length[1]
|
|
*0x15 = 0
|
|
*0x16 = sec_params.length[1] + 7
|
|
|
|
// 0114 8f00 set40 // SIGN EXTENSION IN EFFECT!!
|
|
// 0115 0082 0015 lri $AR2, #0x0015
|
|
// 0117 00de 0006 lr $AC0.M, @0x0006 // ac0.m = sec_params.length[0] ..always 0? // sign extended
|
|
// 0119 00da 165b lr $AX0.H, @0x165b // drom 0000
|
|
// 011b 02bf 88e5 call 0x88e5
|
|
// orr'l $AC0.M, $AX0.H : $AC1.M, @$AR2 // ac0.m = sec_params.length[0], effectively clears acc1 (*0x15 == 0), ar2 = 0x16
|
|
// lrrd $AC1.L, @$AR2 // ac1.l = sec_params.length[1] + 7, ar2 = 0x15
|
|
// add'dr $ACC0, $ACC1 : $AR1 // ac0.m = sec_params.length[0], ac0.l = sec_params.length[1] + 7
|
|
// srri @$AR2, $AC0.M // *0x15 = sec_params.length[0], ar2 = 0x16
|
|
// srr @$AR2, $AC0.L // *0x16 = sec_params.length[1] + 7
|
|
// 011d 14fd asr $ACC0, #-3
|
|
// 011e 1403 lsl $ACC0, #3 // ((acc0 + 7) & ~7) (round up) // consider .length rounded from here on out
|
|
// 011f 1b5e srri @$AR2, $AC0.M // *0x16 = sec_params.length[0], ar2 = 0x17
|
|
// 0120 1b5c srri @$AR2, $AC0.L // *0x17 = sec_params.length[1], ar2 = 0x18
|
|
// 0121 0082 0016 lri $AR2, #0x0016
|
|
// 0123 00de 1723 lr $AC0.M, @0x1723 // drom ffe0 // obviously sign extended
|
|
// 0125 14f4 asr $ACC0, #-12 // -> 0xff_ffff_fe00 = -1, -0x200
|
|
// 0126 00da 166b lr $AX0.H, @0x166b // drom 0000
|
|
// 0128 02bf 88e5 call 0x88e5
|
|
// orr'l $AC0.M, $AX0.H : $AC1.M, @$AR2 // ac1.m = sec_params.length[0] // sign extended
|
|
// lrrd $AC1.L, @$AR2 // ac1.l = sec_params.length[1]
|
|
// add'dr $ACC0, $ACC1 : $AR1 // acc0 = sec_params.length - 0x200 // this is a proper signed operation :)
|
|
// srri @$AR2, $AC0.M // *0x16 = sec_params.length - 0x200 HIGH
|
|
// srr @$AR2, $AC0.L // *0x17 = sec_params.length - 0x200 LOW
|
|
// The above block just does 40bit subtraction...so annoying :p
|
|
*0x15 = sec_params.length[0]
|
|
*0x16 = sec_params.length - 0x200 HIGH
|
|
*0x17 = sec_params.length - 0x200 LOW
|
|
|
|
// 012a b100 tst $ACC0
|
|
// 012b 0290 012e jge 0x012e
|
|
// 012d 8100 clr $ACC0
|
|
if (acc0 < 0) acc0 = 0
|
|
|
|
// At this point, ACC0 = max40bit(0, sec_params.length - 0x200)
|
|
|
|
// 012e 14fd asr $ACC0, #-3 // taken into account at 013f
|
|
// 012f 8e00 set16 // back to sanity
|
|
|
|
// voodoo
|
|
0130 00df 1491 lr $AC1.M, @0x1491 // drom 6a0f
|
|
0132 0340 d0f0 andi $AC1.M, #0xd0f0 // -> 0x4000
|
|
0134 1cbf mrr $IX1, $AC1.M // ix1 = 0x4000
|
|
0135 00df 1468 lr $AC1.M, @0x1468 // drom f808
|
|
0137 00d1 11fc lr $AC1.H, @0x11fc // drom 0003
|
|
0139 157c lsr $ACC1, #-4 // -> 0x00_3f80_8000
|
|
013a 1cdf mrr $IX2, $AC1.M // ix2 = 0x3f80
|
|
013b 00d1 11b8 lr $AC1.H, @0x11b8 // drom 007f
|
|
013d 9900 asr16 $ACC1 // -> 0x00_007f_3f80
|
|
013e 1418 lsl $ACC0, #24
|
|
013f 1478 lsr $ACC0, #-8 // (((ACC0 >> 3) << 24) >> 8)
|
|
same as ((ACC0 >> 3) << 16) & 0x00_ffff_0000 -> ac0.m = (u16)((sec_params.length - 0x200) >> 3)
|
|
u16 size = (u16)((sec_params.length - 0x200) >> 3)
|
|
0140 1f5e mrr $AX0.H, $AC0.M // ax0.h = size
|
|
0141 1ffe mrr $AC1.M, $AC0.M // ac1.m = size
|
|
0142 1f65 mrr $AX1.H, $IX1 // ax1.h = 0x4000
|
|
0143 3600 andr $AC0.M, $AX1.H // ac0.m = size & 0x4000
|
|
0144 1402 lsl $ACC0, #2 // acc0 <<= 2 // t = (0x00_size_0000 & 0x00_4000_ffff) << 2
|
|
0145 1f66 mrr $AX1.H, $IX2 // ax1.h = 0x3f80
|
|
0146 3700 andr $AC1.M, $AX1.H // ac1.m = size & 0x3f80
|
|
0147 1501 lsl $ACC1, #1 // acc1 <<= 1 // u = (0x00_size_3f80 & 0x00_3f80_ffff) << 1
|
|
0148 4c00 add $ACC0, $ACC1 // acc0 += acc1 // t += u
|
|
0149 1518 lsl $ACC1, #24
|
|
014a 9900 asr16 $ACC1 // signed cast (s16)ac1.l (ends up in ac1.m)
|
|
014b 3500 andr $AC1.M, $AX0.H // ac1.m = (s16)u & size
|
|
014c 4c00 add $ACC0, $ACC1 // acc0 += acc1 // t += (s16)u & size
|
|
014d 00df 0012 lr $AC1.M, @0x0012
|
|
014f 3f00 orc $AC1.M, $AC0.M // ac1.m = acc0 | 0x00_ffff_0000
|
|
0150 00ff 0012 sr @0x0012, $AC1.M // *0x12 = ac1.m
|
|
0152 1470 lsr $ACC0, #-16 // // t >>= 16 unsigned
|
|
0153 00df 0011 lr $AC1.M, @0x0011
|
|
0155 3f00 orc $AC1.M, $AC0.M
|
|
0156 00ff 0011 sr @0x0011, $AC1.M // *0x11 |= previous ac0.h, now at ac0.m <- so ac0.m = unsigned ac0.h
|
|
0158 1fa5 mrr $AC1.L, $IX1 // ac1.l = 0x4000
|
|
0159 1501 lsl $ACC1, #1 // ac1.l = 0x8000
|
|
015a 1fe6 mrr $AC1.M, $IX2 // ac1.m = 0x3f80 0x00_3f80_8000
|
|
015b f100 lsl16 $ACC1 // ((acc1 << 16) >> 8) << 16
|
|
015c 15f8 asr $ACC1, #-8
|
|
015d f500 lsr16 $ACC1 // acc1 = 0x00_00ff_8080
|
|
015e 1f5f mrr $AX0.H, $AC1.M // ax0.h = 0xff
|
|
015f 1f7d mrr $AX1.H, $AC1.L // ax1.h = 0x8080
|
|
0160 8100 clr $ACC0
|
|
0161 00de 0011 lr $AC0.M, @0x0011
|
|
0163 3400 andr $AC0.M, $AX0.H // ac0.m = *0x11 & 0xff
|
|
0164 8900 clr $ACC1 // so it was all to setup ax0.h and ax1.h...
|
|
0165 00df 0012 lr $AC1.M, @0x0012
|
|
0167 3500 andr $AC1.M, $AX0.H // ac1.m = *0x12 & 0xff
|
|
0168 4c00 add $ACC0, $ACC1
|
|
0169 00df 0012 lr $AC1.M, @0x0012
|
|
016b 1578 lsr $ACC1, #-8
|
|
016c 4c00 add $ACC0, $ACC1 // acc0 = ((*0x11 & 0xff) << 16) + ((*0x12 & 0xff) << 16) + (*0x12 << 8)
|
|
016d 8900 clr $ACC1
|
|
016e 1ffe mrr $AC1.M, $AC0.M
|
|
016f 1508 lsl $ACC1, #8
|
|
0170 3b00 orr $AC1.M, $AX1.H // ac1.m = (ac0.m << 8) | 0x8080
|
|
0171 00de 0011 lr $AC0.M, @0x0011
|
|
0173 3e00 orc $AC0.M, $AC1.M // final11 = *0x11 | (ac0.m << 8) | 0x8080
|
|
0174 00df 0012 lr $AC1.M, @0x0012
|
|
0176 3b00 orr $AC1.M, $AX1.H
|
|
0177 1cbf mrr $IX1, $AC1.M // final12 = *0x12 | 0x8080
|
|
|
|
// write the final values @22 and @23
|
|
// 0178 00da 15f1 lr $AX0.H, @0x15f1 // drom 0200
|
|
// 017a 3500 andr $AC1.M, $AX0.H
|
|
// 017b 0295 0192 jz 0x0192
|
|
if (final12 & 0x200 != 0) {
|
|
|
|
// 017d 00df 10e2 lr $AC1.M, @0x10e2 // drom 376f
|
|
// 017f 1508 lsl $ACC1, #8 // -> 0x37_6f00
|
|
// 0180 1f5f mrr $AX0.H, $AC1.M
|
|
// 0181 00df 103b lr $AC1.M, @0x103b // drom 0065
|
|
// 0183 7900 decm $AC1.M // -> 0x64
|
|
// 0184 3900 orr $AC1.M, $AX0.H
|
|
// 0185 3080 xorc $AC0.M, $AC1.M
|
|
// 0186 00fe 0022 sr @0x0022, $AC0.M // *0x22 = final11 ^ 0x6f64
|
|
// 0188 00dc 1229 lr $AC0.L, @0x1229 // drom 657c
|
|
// 018a 00dd 11f8 lr $AC1.L, @0x11f8 // drom 0009
|
|
// 018c 5c00 sub $ACC0, $ACC1
|
|
// 018d f000 lsl16 $ACC0
|
|
// 018e 1fe5 mrr $AC1.M, $IX1
|
|
// 018f 3080 xorc $AC0.M, $AC1.M // *0x23 = final12 ^ 0x6573
|
|
// 0190 029f 01a5 jmp 0x01a5
|
|
*0x22 = final11 ^ 0x6f64
|
|
*0x23 = final12 ^ 0x6573
|
|
|
|
} else {
|
|
// 0192 00df 10ca lr $AC1.M, @0x10ca // drom 3461
|
|
// 0194 1508 lsl $ACC1, #8 // -> 0x34_6100
|
|
// 0195 1f5f mrr $AX0.H, $AC1.M
|
|
// 0196 00df 1043 lr $AC1.M, @0x1043 // drom 0076
|
|
// 0198 7500 incm $AC1.M // -> 0x77
|
|
// 0199 3900 orr $AC1.M, $AX0.H
|
|
// 019a 3080 xorc $AC0.M, $AC1.M
|
|
// 019b 00fe 0022 sr @0x0022, $AC0.M // *0x22 = final11 ^ 0x6177
|
|
// 019d 00dc 1259 lr $AC0.L, @0x1259 // drom 6143
|
|
// 019f 00dd 16fe lr $AC1.L, @0x16fe // drom 0008
|
|
// 01a1 4c00 add $ACC0, $ACC1
|
|
// 01a2 f000 lsl16 $ACC0
|
|
// 01a3 1fe5 mrr $AC1.M, $IX1
|
|
// 01a4 3080 xorc $AC0.M, $AC1.M // *0x23 = final12 ^ 0x614b
|
|
*0x22 = final11 ^ 0x6177
|
|
*0x23 = final12 ^ 0x614b
|
|
}
|
|
// 01a5 00fe 0023 sr @0x0023, $AC0.M // taken care of above
|
|
|
|
// this is where result is written to main memory
|
|
// dsp mem 0x20-0x23 (8 bytes) are written back - only values @22 and @23 were modified, so result is 32bit
|
|
01a7 00da 0008 lr $AX0.H, @0x0008 // sec_params.dest_addr[0]
|
|
01a9 00d8 0009 lr $AX0.L, @0x0009 // sec_params.dest_addr[1]
|
|
01ab 009b 0020 lri $AX1.H, #0x0020 // dsp addr
|
|
01ad 0099 0008 lri $AX1.L, #0x0008 // length
|
|
01af 0087 0000 lri $IX3, #0x0000 // there will be no iram dma
|
|
01b1 02bf 808b call 0x808b // do it!
|
|
|
|
01b3 02df ret
|
|
}
|
|
|
|
01b4 0000 nop
|
|
01b5 0000 nop
|
|
01b6 0000 nop
|
|
01b7 0000 nop
|
|
01b8 0000 nop
|
|
01b9 0000 nop
|
|
01ba 0000 nop
|
|
01bb 0000 nop
|
|
01bc 0000 nop
|
|
01bd 0000 nop
|
|
01be 0000 nop
|
|
01bf 0000 nop
|