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
This commit is contained in:
parent
5f0ea50453
commit
e94820ea7d
|
@ -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()
|
||||
{
|
||||
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue