diff options
| author | hrydgard <hrydgard@gmail.com> | 2008-10-08 17:27:43 +0000 |
|---|---|---|
| committer | hrydgard <hrydgard@gmail.com> | 2008-10-08 17:27:43 +0000 |
| commit | e94820ea7db556befd0db0cc2cc7c71052a606be (patch) | |
| tree | c88ad21af3fad4d99b6d4465e290cc1a61ced9cc | |
| parent | 5f0ea50453880224479fb5cf6acf9c4fbc3f28e8 (diff) | |
Beginnings of a new Docs folder - for RE stuff only! Don't go posting leaked things or anything like that here.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@795 8ced0084-cf51-0410-be5f-012b33b47a6e
| -rw-r--r-- | Docs/DSP/AX.c | 204 | ||||
| -rw-r--r-- | Docs/DSP/SrcSelect_.c | 226 | ||||
| -rw-r--r-- | Docs/DSP/Zelda.txt | 45 | ||||
| -rw-r--r-- | Docs/DSP/wwdsp.c | 423 | ||||
| -rw-r--r-- | Docs/DSP/zeldaNotes.txt | 34 |
5 files changed, 932 insertions, 0 deletions
diff --git a/Docs/DSP/AX.c b/Docs/DSP/AX.c new file mode 100644 index 0000000000..2033ec4329 --- /dev/null +++ b/Docs/DSP/AX.c @@ -0,0 +1,204 @@ +//
+// Pseudo C
+//
+
+//
+// DSP:
+//
+
+// Memory USAGE
+
+0x0B31 to 0x0B33 some kind of JMP-Table to handle srcSelect ???
+0x0B34 to 0x0B36 some kind of JMP-Table to handle coefSelect ???
+0x0B11 to 0x0B1F some kind of JMP-Table to handle mixerCtrl ???
+0x0B80 to 0x0C40 CurrentPB
+
+0x0E15 SrcSelectFunction // perhaps CMD0 setups some kind of jmp table at this addresses
+0x0E16 CoefFunction
+0x0E14 MixCtrlFunction
+
+
+void CMD2()
+{
+// 0x1BC
+ int_addrPB = (*r00 << 16) | *(r00+1)
+ DMA_From_Memory(0x0B80, _addrPB, 0xC0); // read first PB to 0x0B80
+
+// 0x1C7
+ *0x0E08 = 0x0000
+ *0x0E09 = 0x0140
+ *0x0E0A = 0x0280
+ *0x0E0B = 0x0400
+ *0x0E0C = 0x0540
+ *0x0E0D = 0x0680
+ *0x0E0E = 0x07C0
+ *0x0E0F = 0x0900
+ *0x0E10 = 0x0A40
+
+// 0x1E4
+ WaitForDMATransfer()
+
+// 0x1E6
+ Addr = (*0x0BA7 << 16) | *0x0BA8
+ DMA_From_Memory(0x03C0, Addr, 0x80); // Copy Update Data to 0x03C0 (AXPBUPDATE dataHi, dataLo)
+
+// 0x1F4
+ R03 = (*0x0B84) + 0x0B31 // AXPB->srcSelect + 0x0B31 ??? some kind of flag handling ??? SRCSEL can be 0x0 to 0x2
+ AC0.M = *R03
+ *0x0E15 = *AC0.M
+
+// 0x1FD
+ R03 = (*0x0B85) + 0x0B34 // AXPB->coefSelect + 0x0B34 ??? some kind of flag handling ??? COEF can be 0x0 to 0x2
+ AC0.M = *R03
+ *0x0E16 = *AC0.M
+
+// 0x206
+ R03 = (*0x0B86) + 0x0B11 // AXPB->mixerCtrl + 0x0B36 ??? some kind of flag handling ??? MIXCTRL can be 0x0 to 0xE
+ AC0.M = *R03
+ *0x0E14 = *AC0.M
+
+// 0x20F
+ if (*0x0B9B == 0) // AXPBITD->flag (on or off for this voice)
+ {
+ // jmp to 0x23a
+ *0x0E42 = 0x0CE0
+ *0x0E40 = 0x0CE0
+ *0x0E41 = 0x0CE0
+ *0x0E43 = 0x0CE0
+
+ WaitForDMATransfer()
+ }
+ else
+ {
+ // code at 0x216
+ *0x0E40 = *0x0B9E + 0x0CC0 // AXPBITD->shiftL
+ *0x0E41 = *0x0B9F + 0x0CC0 // AXPBITD->shiftR
+ *0x0E42 = 0xCE0
+ *0x0E43 = 0xCE0
+
+ WaitForDMATransfer()
+
+ // 0x22a
+ Addr = (*0x0B9C << 16) | *0x0B9D
+ DMA_From_Memory(0x0CC0, Addr, 0x40); // (AXPBITD->bufferHi << 16 | AXPBITD->bufferLo) -> 0xCC0
+ WaitForDMATransfer()
+ }
+
+}
+
+void CMD0()
+{
+
+}
+
+
+void CMD2()
+{
+
+ 0x0E07 = R00
+ R00 = 0x0BA2 // AXPBUPDATE->updNum
+ R01 = 0x03C0
+ *0x0E04 = 0x05
+
+ AC1 = 0
+ AC0 = 0
+ AX0.H = *R00++ // AXPBUPDATE->updNum[0]
+ AC1.M = 0x0B80
+
+// 0x256
+ for (i=0; i<AX0.H; i++)
+ {
+ AC0.M = *R01++
+ AC0.M = AC0.M + AC1.M
+ AX1.L = *R01++
+ R02 = AC0.M
+ *R02 = AX1.L
+ }
+
+// 0x25c
+ R03 = 0x0E05
+ *R03++ = R01
+ *R03++ = R02
+
+// 0x260
+ AC0.M = *0x0B87 // AXPB->state
+
+ if (AC0.M == 1)
+ {
+ // JMP 0x267 (AX_PB_STATE_RUN)
+ *0x0E1C = *0x0E42
+
+ CALLR *0x0E15 // Load Sample (SrcSelectFunction)
+
+ // 0x270
+ AC0.M = *0xBB3 // AXPBVE->currentDelta (.15 volume at start of frame)
+ AC1.M = *0xBB2 // AXPBVE->currentVolume
+
+ // 0x278
+ AX0.L = AC1.M
+ AC1.M = AC1.M + AC0.M
+ AC0.M = AC0.M << 1
+
+ SET15 // ????
+
+ AX1.H = AC0.M
+ AC0.M = AX0.L
+
+ AX0.L = 0x8000
+ R00 = 0x0E44
+
+// 0x27f
+ // scale volume table
+ .
+ .
+ .
+/* for (int i=0; i<32; i++)
+ {
+ *R00++ = AC0.M;
+ prod = AX0.L * AX1.H
+
+ *R00++ = AC1.M;
+ AC0 = AC0 + prod
+ prod = AX0.L * AX1.H
+
+ *R00++ = AC0.M;
+ AC1 = AC1 + prod
+ prod = AX0.L * AX1.H
+ }*/
+
+// 0x29f
+ *0xBB2 = CurrentVolume
+
+
+// 0x2a1
+ // mutiply volume with sample
+ .
+ .
+ .
+
+
+// 0x2ea
+ // Call mixer
+
+// 0x02f0
+
+
+
+ }
+ else
+ {
+ // JMP 0x332
+ .
+ .
+ .
+ .
+ }
+
+}
+
+// ===============================================================
+void Func_0x065D()
+{
+
+
+}
\ No newline at end of file diff --git a/Docs/DSP/SrcSelect_.c b/Docs/DSP/SrcSelect_.c new file mode 100644 index 0000000000..c813592013 --- /dev/null +++ b/Docs/DSP/SrcSelect_.c @@ -0,0 +1,226 @@ + +// Init Hardware PCM decoder + + /* + 06a3 0082 0bb8 LRI $R02, #0x0bb8 + 06a5 195e LRRI $AC0.M, @$R02 + 06a6 2ed1 SRS @SampleFormat, $AC0.M + 06a7 195e LRRI $AC0.M, @$R02 + 06a8 2ed4 SRS @ACSAH, $AC0.M + 06a9 195e LRRI $AC0.M, @$R02 + 06aa 2ed5 SRS @ACSAL, $AC0.M + 06ab 195e LRRI $AC0.M, @$R02 + 06ac 2ed6 SRS @ACEAH, $AC0.M + 06ad 195e LRRI $AC0.M, @$R02 + 06ae 2ed7 SRS @ACEAL, $AC0.M + 06af 195e LRRI $AC0.M, @$R02 + 06b0 2ed8 SRS @ACCAH, $AC0.M + 06b1 195e LRRI $AC0.M, @$R02 + 06b2 2ed9 SRS @ACCAL, $AC0.M + 06b3 195e LRRI $AC0.M, @$R02 + 06b4 2ea0 SRS @COEF_A1_0, $AC0.M + 06b5 195e LRRI $AC0.M, @$R02 + 06b6 2ea1 SRS @COEF_A2_0, $AC0.M + 06b7 195e LRRI $AC0.M, @$R02 + 06b8 2ea2 SRS @COEF_A1_1, $AC0.M + 06b9 195e LRRI $AC0.M, @$R02 + 06ba 2ea3 SRS @COEF_A2_1, $AC0.M + 06bb 195e LRRI $AC0.M, @$R02 + 06bc 2ea4 SRS @COEF_A1_2, $AC0.M + 06bd 195e LRRI $AC0.M, @$R02 + 06be 2ea5 SRS @COEF_A2_2, $AC0.M + 06bf 195e LRRI $AC0.M, @$R02 + 06c0 2ea6 SRS @COEF_A1_3, $AC0.M + 06c1 195e LRRI $AC0.M, @$R02 + 06c2 2ea7 SRS @COEF_A2_3, $AC0.M + 06c3 195e LRRI $AC0.M, @$R02 + 06c4 2ea8 SRS @COEF_A1_4, $AC0.M + 06c5 195e LRRI $AC0.M, @$R02 + 06c6 2ea9 SRS @COEF_A2_4, $AC0.M + 06c7 195e LRRI $AC0.M, @$R02 + 06c8 2eaa SRS @COEF_A1_5, $AC0.M + 06c9 195e LRRI $AC0.M, @$R02 + 06ca 2eab SRS @COEF_A2_5, $AC0.M + 06cb 195e LRRI $AC0.M, @$R02 + 06cc 2eac SRS @COEF_A1_6, $AC0.M + 06cd 195e LRRI $AC0.M, @$R02 + 06ce 2ead SRS @COEF_A2_6, $AC0.M + 06cf 195e LRRI $AC0.M, @$R02 + 06d0 2eae SRS @COEF_A1_7, $AC0.M + 06d1 195e LRRI $AC0.M, @$R02 + 06d2 2eaf SRS @COEF_A2_7, $AC0.M + 06d3 195e LRRI $AC0.M, @$R02 + 06d4 2ede SRS @GAIN, $AC0.M + 06d5 195e LRRI $AC0.M, @$R02 + 06d6 2eda SRS @pred_scale, $AC0.M + 06d7 195e LRRI $AC0.M, @$R02 + 06d8 2edb SRS @yn1, $AC0.M + 06d9 195e LRRI $AC0.M, @$R02 + 06da 2edc SRS @yn2, $AC0.M + */ + +/// hmmmmmm +/* + 06db 8c00 CLR15 + 06dc 8a00 M2 + 06dd 8e00 S40 +*/ + +/// + + AX0.L = *0xe16 + AX1.H = ratioHi // sample ratio from AXPBSRC + AX1.L = ratioLo // sample ratio from AXPBSRC + + AC0 = 0 + AC0.L = currentAddressFrac // AXPBSRC + + *0x0e48 = last_samples[0] + *0x0e49 = last_samples[1] + *0x0e4A = last_samples[2] + *0x0e4B = last_samples[3] + + AC1.M = AX1.L + ACC = ACC >> 0x05 + AC1 = AC1 + AC0 + + R04 = AC1.M + R05 = AC1.L + + AC1 = AC1 + 0xe0 // ?????? AC1 = AC1 - 2097152 (because 0xe0 is converted to signed and shift << 16) + AC1 = AC1 >> 16 + AC1 = -AC1 + + R06 = -AC1 + +////////////// + AC1 = 0 + AC1.L = R05 + AC1 = AC1 << 2 + R05 = AC1.M + + +// 0x06fc + + AX.0 = 0x1fc + AC0 = 0xe48 + R01 = 0xFFDD + R03 = 0x0D80 + +// 0x0704 + for (i=0; i<R04; i++) + { + AC0 = AC0 + AX1 + *R03++ = AC0.M + + AC1.M = AC0.L + LSR $AC1.M, #0x79 + AC1 = AC1 & AX0.H + AC1 += AX0.L + *R03++ = AC1 + + *R00++ = *ADPCM_DECODER + *R00++ = *ADPCM_DECODER + *R00++ = *ADPCM_DECODER + *R00++ = *ADPCM_DECODER + } + +/* +0704 0064 0715 BLOOP $R04, 0x0715 +0706 1827 LRR $R07, @$R01 +0707 1b07 SRRI @$R00, $R07 +0708 4a00 ADDAX $AC0.M, $AX1.L +0709 1ffc MRR $AC1.M, $AC0.L +070a 1827 LRR $R07, @$R01 +070b 1b07 SRRI @$R00, $R07 +070c 1579 LSR $AC1.M, #0x79 +070d 3500 ANDR $AC1.M, $R00 +070e 1827 LRR $R07, @$R01 +070f 1b07 SRRI @$R00, $R07 +0710 4100 ADDR $AC1.M, $AX0.L +0711 1b7e SRRI @$R03, $AC0.M +0712 1827 LRR $R07, @$R01 +0713 1b07 SRRI @$R00, $R07 +0714 1b7f SRRI @$R03, $AC1.M +0715 0000 NOP */ + +// 0x0715 +// prolly copies the "rest" + + for (i=0; i<r05; i++) + { + R07 = *ADPCM_DECODER + *R00++ = R07 + } + + // 0x71c + R03-- + AC1 = *R03 + +/* 071c 0007 DAR $R03 +071d 187f LRR $AC1.M, @$R03 */ + + for (i<0; i<r06; i++) + { + AC0 = AX1 + *R03++ = AC1.M + + } + +/* +071e 0066 0724 BLOOP $R06, 0x0724 +0720 4a3b ADDAXÌS $AC0.M, $AX1.L : @$R03, $AC1.M +0721 1ffc MRR $AC1.M, $AC0.L +0722 1579 LSR $AC1.M, #0x79 +0723 3533 ANDRÌS $AC1.M, $R00 : @$R03, $AC0.M +0724 4100 ADDR $AC1.M, $AX0.L +*/ + +0725 1b7f SRRI @$R03, $AC1.M +0726 0004 DAR $R00 +0727 189f LRRD $AC1.M, @$R00 +0728 1adf SRRD @$R02, $AC1.M +0729 189f LRRD $AC1.M, @$R00 +072a 1adf SRRD @$R02, $AC1.M +072b 189f LRRD $AC1.M, @$R00 +072c 1adf SRRD @$R02, $AC1.M +072d 189f LRRD $AC1.M, @$R00 +072e 1adf SRRD @$R02, $AC1.M +072f 1adc SRRD @$R02, $AC0.L +0730 0082 0bd2 LRI $R02, #0x0bd2 +0732 27dc LRS $AC1.M, @yn2 +0733 1adf SRRD @$R02, $AC1.M +0734 27db LRS $AC1.M, @yn1 +0735 1adf SRRD @$R02, $AC1.M +0736 27da LRS $AC1.M, @pred_scale +0737 1adf SRRD @$R02, $AC1.M +0738 0082 0bbe LRI $R02, #0x0bbe +073a 27d9 LRS $AC1.M, @ACCAL +073b 1adf SRRD @$R02, $AC1.M +073c 27d8 LRS $AC1.M, @ACCAH +073d 1adf SRRD @$R02, $AC1.M + + +073e 8f00 S16 +073f 00c1 0e42 LR $R01, @0x0e42 +0741 0082 0d80 LRI $R02, #0x0d80 +0743 1940 LRRI $R00, @$R02 +0744 1943 LRRI $R03, @$R02 +0745 80f0 NXÌLDX : $AX1.L, $AX1.H, @$R01 +0746 b8c0 MULXÌLDX $AX0.H, $AX1.H : $AX0.L, $AX0.H, @$R00 +0747 111f 074f BLOOPI #0x1f, 0x074f +0749 a6f0 MULXMVÌLDX $AX0.L, $AX1.L, $AC0.M : $AX1.L, $AX1.H, @$R01 +074a bcf0 MULXACÌLDX $AX0.H, $AX1.H, $AC0.M : $AX1.L, $AX1.H, @$R01 +074b 1940 LRRI $R00, @$R02 +074c 1943 LRRI $R03, @$R02 +074d bcf0 MULXACÌLDX $AX0.H, $AX1.H, $AC0.M : $AX1.L, $AX1.H, @$R01 +074e 4ec0 ADDPÌLDX $AC0.M : $AX0.L, $AX0.H, @$R00 +074f b831 MULXÌS $AX0.H, $AX1.H : @$R01, $AC0.M +0750 a6f0 MULXMVÌLDX $AX0.L, $AX1.L, $AC0.M : $AX1.L, $AX1.H, @$R01 +0751 bcf0 MULXACÌLDX $AX0.H, $AX1.H, $AC0.M : $AX1.L, $AX1.H, @$R01 +0752 bc00 MULXAC $AX0.H, $AX1.H, $AC0.M +0753 4e00 ADDP $AC0.M +0754 1b3e SRRI @$R01, $AC0.M +0755 00e1 0e42 SR @0x0e42, $R01 +0757 02df RET + diff --git a/Docs/DSP/Zelda.txt b/Docs/DSP/Zelda.txt new file mode 100644 index 0000000000..f4a490e58a --- /dev/null +++ b/Docs/DSP/Zelda.txt @@ -0,0 +1,45 @@ +CPU:
+---------------------------------------------------------------------------------------
+
+void DSPSendCommands2(_pBuffer, _NumberOfMessages, _StartWork)
+{
+
+ while (!DSP_Running_Check());
+
+ OldInterrupts = OSDisableInterrupts();
+
+ if (DSPCheckMailToDSP() != 0)
+ {
+ OSRestoreInterrupts();
+ return -1;
+ }
+
+ DSPSendMailToDSP(_NumberOfMessages)
+
+ DSPAssertInt()
+
+ while (DSPCheckMailToDSP() != 0) {}
+
+ if (_NumberOfMessages == 0)
+ _NumberOfMessages = 1
+
+
+ if (_StartWork != 0)
+ {
+ r28 = DSPStartWork(*_pBuffer, _StartWork)
+ }
+ _StartWork = 0
+
+
+ while(Count != _NumberOfMessages)
+ {
+ DSPSendMailToDSP(Buffer[Count])
+ while (DSPCheckMailToDSP() != 0) {}
+ Count++
+ }
+
+ OSRestoreInterrupts(OldInterrupts)
+
+ return r28;
+}
+
diff --git a/Docs/DSP/wwdsp.c b/Docs/DSP/wwdsp.c new file mode 100644 index 0000000000..36a00ce35d --- /dev/null +++ b/Docs/DSP/wwdsp.c @@ -0,0 +1,423 @@ +/* important variables */ +short mem[0x1000]; +#define v_0341 mem[0x0341] /* op#2 saves a copy of 344 here */ +#define v_0343 mem[0x0343] /* message type? */ +#define v_0344 mem[0x0344] /* low byte of first word of message */ +#define v_0345 mem[0x0345] /* copy of second word of message */ +#define a_0346 mem[0x0346] /* buffer for message contents, size unknown */ +#define v_034e mem[0x034e] /* init to 0, later set to most recent value written in a_04fc */ + +#define v_0350 mem[0x0350] /* init to 0x0280 (write location of messages) */ +#define v_0351 mem[0x0351] /* init to 0x0280 (read location?) */ +#define v_0352 mem[0x0352] /* init to 0 (number of messages pending?) */ +#define v_0355 mem[0x0355] /* used by op#2, init to 0 */ +#define a_0356 (mem+0x0356) /* message contents */ + +#define a_0388 (mem+0x388) /* where op 2 keeps its message */ +#define a_038e (mem+0x38e) /* op#2 saves a copy of 345 here */ + +#define a_03a8 (mem+0x3a8) /* where op#2 dmas in its data, at least 0x80 */ + +#define v_03fa mem[0x03fa] /* temp for ax0.h during exception */ +#define v_03fb mem[0x03fb] /* temp for ar0 during exception */ +#define v_03fc mem[0x03fc] /* temp for r08 during exception */ +#define v_03fd mem[0x03fd] /* temp for ac0.h during exception */ +#define v_03fe mem[0x03fe] /* temp for ac0.m during exception */ +#define v_03ff mem[0x03ff] /* temp for ac0.l during exception */ + +#define a_04e8 (mem+0x04e8) /* 4 element array */ +#define a_04ec (mem+0x04ec) /* 4 element array (empty) */ +#define a_04f0 (mem+0x04f0) /* 4 element array */ +#define a_04f4 (mem+0x04f4) /* 4 element array (empty) */ +#define a_04fc (mem+0x04fc) /* 16 element array, written by messages */ +#define a_09a0 (mem+0x09a0) /* 0x50 element array, used by op#2, cleared */ +#define a_0a00 (mem+0x0a00) /* 0x50 element array, used by op#2, cleared */ +#define a_0b00 (mem+0x0b00) /* array from 0x0b00-0x0bff, involves accelerator? */ +#define a_0ca0 (mem+0x0ca0) /* 0x50 element array, used by op#2, cleared */ +#define a_0d00 (mem+0x0d00) /* 0x50 element array, used by op#2, cleared */ +#define a_0d60 (mem+0x0d60) /* 0x50 element array, used by op#2, cleared */ +#define a_0f40 (mem+0x0f40) /* 0x50 element array, used by op#2, cleared */ + + + +/* reset exception vector 0x0000 */ +void main() { + /* JMP 0x0012 */ + /* various inits */ + SBCLR(5); /* disable interrupts? */ + fcn_0057(); /* init hardware stuff */ + for(ac1.m=0x1000,ac0.m=0;ac1.m>0;ac1.m--) mem[ac0.m++]=0; /* clear all vars */ + fcn_0688(); /* init some vars */ + fcn_04c0(); /* set something up related to the accelerator at a_0b00 */ + fcn_0e14(); /* set up a table */ + fcn_066a(0); /* send a message */ + fcn_0674(0x1111); /* send a message */ + v_034e=0; + SBSET(5); /* enable interrupts? */ + + /* jump to 0x06c5 */ +mainloop: + while (v_0352) ; /* while no messages pending */ + + SBCLR(5); /* do not distrub */ + v_0352--; /* important that this be atomic */ + SBSET(5); + + t=v_0351; + size=mem[t++]; + if (!(size&0x8000)) { /* size > 0x7fff invalid */ + if (size==0) { /* die on message of length 0? */ + /* jump to 0x06f5 */ + /* jump to 0x05f0 */ + + /* TODO: analysis of HALT */ + HALT(); + } + for (i=size,j=0;i>0;i--) { + a_0356[j++]=mem[t++]; + a_0356[j++]=mem[t++]; + } + v_0351=t; + + /* jump to 0x002f */ + /* actual command handling */ + v_0345=a_0356[1]; + v_0344=a_0356[0]&0x00ff; + v_0343=(a_0346[0]>>7)&0x7e; + + /* jump table at 0x75 used here */ + switch (v_0343>>1) { + + // 0x43 + case 0: + case 10: + case 11: + case 12: + case 14: + case 15: + /* invalid command? */ + config=0x00ff; + fcn_066a(0x04); /* send off a message */ + fcn_0674(a_0356[0]); /* send first word of command as a message */ + goto mainloop; + break; + case 1: + /* jmp 0x0095 */ + break; + + case 2: + /* jmp 0x0243 */ + sub_0243(); + break; + + case 3: + /* jmp 0x0073 */ + break; + + case 4: + /* jmp 0x580 */ + break; + + case 5: + /* jmp 0x592 */ + break; + + case 6: + /* jmp 0x469 */ + break; + + case 7: + /* jmp 0x41d */ + break; + + case 8: /* mix */ + /* jmp 0x0485 */ + fcn_0067(fcn_0067(0x0346)); /* read message twice? */ + /* take in the two buffers to mix */ + fcn_0525(mem[0x344],mem[0x346],mem[0x347],0x400); /* size, addrH, addrL, dsp addr */ + fcn_0525(mem[0x344],mem[0x348],mem[0x349],0x800); + S16(); /* saturate all adds, multiplies to 16 bits? */ + + i=mem[0x0344]; + src1=0x400; + src2=0x800; + scale=mem[0x345]; + + prod=scale*mem[src2++]; + val2=mem[src2++]; + do { + val1=mem[src1]; + val1+=prod; + prod=scale*val2; + mem[src1]=val1; + val2=mem[src2]; + src1++; + src2++; + } while (--i); + + S40(); + + /* dma out mixed buf */ + fcn_0523(mem[0x344],mem[0x346],mem[0x347],0x400); + + break; + + case 9: + /* jmp 0x44d */ + break; + + case 13: + /* jmp 0x00b2 */ + break; + } + } + + v_0351=t; + + goto mainloop; +} + +/* message in MBOX exception vector? 0x000e */ +void exception() { + /* JMP 0x05b8 */ + + SBCLR(5); + S40(); + /* save ax0.h,ac0.h,ac0.m, and ac0.l */ + + if ((tH=register_fffe)&0x8000) { /* CPU mailbox H */ + if (!(tsize=register_ffff)) { /* CPU mailbox L */ + /* empty message? */ + while (!((tH=register_fffe)&0x8000)) ; + tH&=0xf; + v_034e=(tH+1)<<4; + a_04fc[tH]=register_ffff; + } else { /* nonempty message? */ + /* jump to 0x0692 */ + /* save ar0, r08 */ + t=v_0350; + mem[t++]=tsize; + + do { + while (!((tH=register_fffe)&0x8000)) ; + mem[t++]=tH; + mem[t++]=register_ffff; + } while (--tsize); + + v_0350=t; + v_0352++; + /* restore ar0, r08 */ + + /* jump to 0x05e6 */ + } + } else { /* interrupt without message? */ + /* jump to 0x06b9 */ + /* save ar0, r08 */ + mem[v_0350]=0; /* empty message */ + /* jump to 0x06ab */ + v_0350++; + v_0352++; + /* restore ar0, r08 */ + + /* jump to 0x05e6 */ + } + + /* 0x05e6 */ + + /* restore ax0.h,ac0.h,ac0.m, and ac0.l */ + SBSET(5); + /* RTI */ +} + +/* set up some registers */ +void fcn_0057() { + SBCLR(2); + SBCLR(3); + SBCLR(4); + SBCLR(6); + S40(); /* 40-bit mode */ + CLR15(); + M0(); /* don't multiply result by 2 */ + r08=-1; + r09=-1; + r0a=-1; + r0b=-1; + config=0xff; +} + +void fcn_0688() { + v_0350=0x0280; + v_0351=0x0280; + v_0352=0; +} + +void fcn_04c0() { + config=0xff; + for(i=0xff,ar0=0xb00;i>0;i--) mem[ar0++]=0; + mem[ar0++]=0; /* get the last one */ + fcn_0573(0x0b00,0x0100,0); +} + +/* a=an address in ac1.m, l=a length in ar0, v=a value? in ac0.m */ +void fcn_0573(short a, short l, short v) { + fcn_0561(a,l,0x0001); +} + +/* a=an address in ac1.m, l=a length in ar0, v=a value? in ac0.m, f is a flag? in ac0.h */ +/* return is in ax0.h */ +short fcn_0561(short a, short l, short v, short f) { + register_ffd1=0x0a; /* unknown reg, accel? */ + register_ffd6=-1; /* accel end addr H */ + register_ffd7=-1; /* accel end addr L */ + register_ffd8=v>>1; /* + register_ffd9=?; /* has a value from way back? */ + + return f; +} + +/* initializes some tables that look useful... */ +void fcn_0e14() { + a_04e8[0]=0x8240; + a_04e8[1]=0x7fff; + a_04e8[2]=0x7dbf; + a_04e8[3]=0x843f; + a_04f0[0]=0xb23b; + a_04f0[1]=0x7fff; + a_04f0[2]=0x4dc4; + a_04f0[3]=0xd808; + a_04ec[0]=a_04ec[1]=a_04ec[2]=a_04ec[3]=0; + a_04f4[0]=a_04f4[1]=a_04f4[2]=a_04f4[3]=0; +} + +/* send a message via DSP MBOX */ +void fcn_066a(short m) { + fcn_0682(); /* wait for empty mbox */ + register_fffc=0xdcd1; + register_fffd=m; + register_fffb=1; /* IRQ */ + fcn_0682(); +} + +/* wait for dsp mbox empty */ +void fcn_0682() { + while (register_fffc&0x8000); +} + +void fcn_0674(short m) { + fcn_0682(); + register_fffc=0xf355; + register_fffd=m; + fcn_0682(); +} + +/* a=address in ar0 */ +/* fetch a message body (up to zero)? */ +short fcn_0067(short a) { + i=0x0357; + j=a; + do { + mem[j++]=mem[i++]; + mem[j++]=mem[i]; + } while (mem[i++]); + return a; +} + +/* dma in, I assume */ +/* size=words to transfer in ar0, addrL=low word of RAM address in ac0.l, addrH=high word of RAM address in ac0.m, dspaddr=dsp address in ac1.m */ +void fcn_0525(short size, short addrH, short addrL, short dspaddr) { + register_ffcd=dspaddr; /* dsp address */ + register_ffc9=0; /* direction: ram->dsp */ + register_ffce=addrH; /* memory address H */ + register_ffcf=addrL; /* memory address L */ + register_ffcb=size<<1; /* bytes to transfer (size must be in words) */ + fcn_0536(); /* dma wait */ +} + +/* dma wait? */ +void fcn_0536() { + while (!(register_ffc9&4)); +} + +/* dma out, I assume */ +/* size=words to transfer in ar0, addrL=low word of RAM address is ac0.l, addrH=high word of RAM address in ac0.m, dspaddr=dsp address in ac1.m */ +/* shares code with fcn_0525 */ +void fcn_0523(short size, short addrH, short addrL, shot dspaddr) { + register_ffcd=dspaddr; + /* jump back into 0525 */ + register_ffc9=1; /* direction dsp->ram */ + register_ffce=addrH; + register_ffcf=addrL; + register_ffcb=size<<1; + fcn_0536(); +} + +/* huge subroutine, op #2 */ +void sub_0243() { + fcn_0067(0x0388); /* called in an indirect manner... */ + v_0341=v_0344; /* low byte first word of message */ + v_038e=v_0345; + v_0355=0; + fcn_022a(); /* get stuffs */ + fcn_05a4(); /* write to accel */ + + for (i=v_0341;i>0i--) { + fcn_0102(); + + } +} + +void fcn_022a() { + /* something else must set 386, 387 */ + fcn_0525(0x0040,v_0386,v_0387,0x03a8); +} + +void fcn_05a4() { + register_ffd4=-1; + register_ffd5=-1; + register_ffd6=-1; + register_ffd7=-1; +} + +void fcn_0102() { + for (i=0;i<0x50;i++) a_0d00[i]=0; + for (i=0;i<0x50;i++) a_0d60[i]=0; + fcn_0e3f(); + for (i=0;i<0x50;i++) a_0ca0[i]=0; + for (i=0;i<0x50;i++) a_0f40[i]=0; + for (i=0;i<0x50;i++) a_0fa0[i]=0; + for (i=0;i<0x50;i++) a_0a00[i]=0; + for (i=0;i<0x50;i++) a_09a0[i]=0; +} + +void fcn_0e3f() { + fcn_00fa(0x0f40,0x0b00,0x50,0x6784); + fcn_0ba4(0x04e8,0x0b00,0x04ec); +} + +/* addr1=address in ar0, addr2=address in ar3, size=size of table at addr1 in ac1.m, val=in ax0.l */ +void fcn_00fa(short addr1, short addr2, short size, short val) { + M2(); /* all multiplications 2x */ + + tmp=mem[addr1++]; + prod=val*tmp*2; + tmp=mem[addr1++]; + ac0.m=prod; + prod=val*tmp*2; + tmp=mem[addr1++]; + + do { + ac0.m=prod; + prod=val*tmp*2; + mem[addr2]=ac0.m; + tmp=mem[addr1]; + addr1++; + addr2++; + } while (--size); + + M0(); +} + +/* addr1=address in ar0 (source 4 element table?), addr2=address in ar1 (accelerator?), addr3=address in ar2 (destination 4 element table?) */ +void fcn_00ba4(short addr1, short addr2, short addr3) { + +}
\ No newline at end of file diff --git a/Docs/DSP/zeldaNotes.txt b/Docs/DSP/zeldaNotes.txt new file mode 100644 index 0000000000..984e1961fa --- /dev/null +++ b/Docs/DSP/zeldaNotes.txt @@ -0,0 +1,34 @@ +DSP startup sequence:
+
+DspBoot called with (JASystem::TAudioThread::syncDSP()) as a parameter.
+DSP lib initialized
+A Dsp task is created:
+ init callback = DspHandShake()
+ req callback = JASystem::TAudioThread::syncDSP()
+Task is pushed as first task and executed
+
+DSP send DSP_INIT command (0xDCD10003)
+__DSPHandler receive the command
+
+task's init callback (DspHandShake) is called
+1 mail is read from dsp (and discarded)
+DSP flag is set as running
+
+AIRegisterDMACallback(JASystem::TAudioThread::syncAudio((void))
+AIStartDMA() to initialize dma in AI module
+
+-----------------------------------
+
+DSP run sequence:
+
+__DSPHandler receive command DSP_RESUME
+callback JASystem::TAudioThread::syncDSP called and pull 1 mail
+A message is send by OSSendMessage(1)
+
+JASystem::TAudioThread::audioproc receive OSMessage:
+ 0=update dac
+ 1=update dsp
+ 2=nop ?
+ 3=exit thread
+
+dsp is updated
\ No newline at end of file |
