Update_SR_Register64 sets SR_TOP2BITS based on m, not h (does someone have tests saying otherwise?)
clean up dsp_base.inc a little, use some irom funcs where possible git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5069 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
dc76856736
commit
e0e5a25bcd
|
@ -112,6 +112,7 @@
|
||||||
#define DSP_DSMAL 0xcf // DSP DMA Address Low (External)
|
#define DSP_DSMAL 0xcf // DSP DMA Address Low (External)
|
||||||
|
|
||||||
#define DSP_FORMAT 0xd1 // Sample format
|
#define DSP_FORMAT 0xd1 // Sample format
|
||||||
|
#define DSP_ACUNK 0xd2 // Set to 3 on my dumps
|
||||||
#define DSP_ACDATA1 0xd3 // used only by Zelda ucodes
|
#define DSP_ACDATA1 0xd3 // used only by Zelda ucodes
|
||||||
#define DSP_ACSAH 0xd4 // Start of loop
|
#define DSP_ACSAH 0xd4 // Start of loop
|
||||||
#define DSP_ACSAL 0xd5
|
#define DSP_ACSAL 0xd5
|
||||||
|
@ -124,8 +125,9 @@
|
||||||
#define DSP_YN2 0xdc
|
#define DSP_YN2 0xdc
|
||||||
#define DSP_ACCELERATOR 0xdd // ADPCM accelerator read. Used by AX.
|
#define DSP_ACCELERATOR 0xdd // ADPCM accelerator read. Used by AX.
|
||||||
#define DSP_GAIN 0xde
|
#define DSP_GAIN 0xde
|
||||||
|
#define DSP_ACUNK2 0xdf // Set to 0xc on my dumps
|
||||||
|
|
||||||
#define DSP_DREQ_MASK 0xef // ARAM DMA Request Mask
|
#define DSP_AMDM 0xef // ARAM DMA Request Mask 0: DMA with ARAM unmasked 1: masked
|
||||||
|
|
||||||
#define DSP_DIRQ 0xfb // DSP Irq Rest
|
#define DSP_DIRQ 0xfb // DSP Irq Rest
|
||||||
#define DSP_DMBH 0xfc // DSP Mailbox H
|
#define DSP_DMBH 0xfc // DSP Mailbox H
|
||||||
|
|
|
@ -51,8 +51,8 @@ void Update_SR_Register64(s64 _Value, bool carry, bool overflow)
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
|
g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if top bits are equal, what is it good for?
|
// Checks if top bits of m are equal, what is it good for?
|
||||||
if (((_Value >> 62) == 0) || (_Value >> 62 == 3))
|
if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000))
|
||||||
{
|
{
|
||||||
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,7 +551,7 @@ bool DSPAssembler::VerifyParams(const opc_t *opc, param_t *par, int count, bool
|
||||||
{
|
{
|
||||||
if (ext) fprintf(stderr, "(ext) ");
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
if (par[i].val >= 0x1e && par[i].val <= 0x1f) {
|
if (par[i].val >= 0x1e && par[i].val <= 0x1f) {
|
||||||
fprintf(stderr, "%i : %s", code_line, cur_line.c_str());
|
fprintf(stderr, "%i : %s ", code_line, cur_line.c_str());
|
||||||
fprintf(stderr, "WARNING: $ACM%d register used instead of $ACC%d register Line: %d Param: %d Ext: %d\n",
|
fprintf(stderr, "WARNING: $ACM%d register used instead of $ACC%d register Line: %d Param: %d Ext: %d\n",
|
||||||
(par[i].val & 1), (par[i].val & 1), code_line, current_param, ext);
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param, ext);
|
||||||
}
|
}
|
||||||
|
@ -584,12 +584,12 @@ bool DSPAssembler::VerifyParams(const opc_t *opc, param_t *par, int count, bool
|
||||||
if (ext) fprintf(stderr, "(ext) ");
|
if (ext) fprintf(stderr, "(ext) ");
|
||||||
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
if (par[i].val >= 0x1e && par[i].val <= 0x1f)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s", cur_line.c_str());
|
fprintf(stderr, "%s ", cur_line.c_str());
|
||||||
fprintf(stderr, "WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %d\n",
|
fprintf(stderr, "WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %d\n",
|
||||||
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
||||||
}
|
}
|
||||||
else if (par[i].val >= 0x20 && par[i].val <= 0x21) {
|
else if (par[i].val >= 0x20 && par[i].val <= 0x21) {
|
||||||
fprintf(stderr, "%s", cur_line.c_str());
|
fprintf(stderr, "%s ", cur_line.c_str());
|
||||||
fprintf(stderr, "WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %d\n",
|
fprintf(stderr, "WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %d\n",
|
||||||
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,8 @@ REGS_BASE: equ 0x0f80
|
||||||
MEM_HI: equ 0x0f7E
|
MEM_HI: equ 0x0f7E
|
||||||
MEM_LO: equ 0x0f7F
|
MEM_LO: equ 0x0f7F
|
||||||
|
|
||||||
;
|
|
||||||
; CODE STARTS HERE.
|
|
||||||
|
|
||||||
; Interrupt vectors 8 vectors, 2 opcodes each
|
; Interrupt vectors 8 vectors, 2 opcodes each
|
||||||
|
|
||||||
jmp irq0
|
jmp irq0
|
||||||
jmp irq1
|
jmp irq1
|
||||||
jmp irq2
|
jmp irq2
|
||||||
|
@ -17,7 +14,7 @@ MEM_LO: equ 0x0f7F
|
||||||
jmp irq6
|
jmp irq6
|
||||||
jmp irq7
|
jmp irq7
|
||||||
|
|
||||||
; Main code at 0x10
|
; Main code (and normal entrypoint) at 0x10
|
||||||
sbset #0x02
|
sbset #0x02
|
||||||
sbset #0x03
|
sbset #0x03
|
||||||
sbclr #0x04
|
sbclr #0x04
|
||||||
|
@ -27,24 +24,21 @@ MEM_LO: equ 0x0f7F
|
||||||
s16
|
s16
|
||||||
lri $CR, #0x00ff
|
lri $CR, #0x00ff
|
||||||
|
|
||||||
; Why do we have a main label here?
|
|
||||||
main:
|
|
||||||
clr $acc1
|
clr $acc1
|
||||||
clr $acc0
|
clr $acc0
|
||||||
|
|
||||||
; get address of memory dump and copy it to DRAM
|
; get address of memory dump and copy it to DRAM
|
||||||
|
call 0x807e
|
||||||
call wait_for_dsp_mbox
|
|
||||||
si @DMBH, #0x8888
|
si @DMBH, #0x8888
|
||||||
si @DMBL, #0xdead
|
si @DMBL, #0xdead
|
||||||
si @DIRQ, #0x0001
|
si @DIRQ, #0x0001
|
||||||
|
|
||||||
call wait_for_cpu_mbox
|
call 0x8078
|
||||||
lrs $ac0.m, @CMBL
|
andi $ac0.m, #0x7fff
|
||||||
andi $ac1.m, #0x7fff
|
lrs $ac1.m, @CMBL
|
||||||
|
|
||||||
sr @MEM_HI, $ac1.m
|
sr @MEM_HI, $ac0.m
|
||||||
sr @MEM_LO, $ac0.m
|
sr @MEM_LO, $ac1.m
|
||||||
|
|
||||||
lri $ax0.l, #0
|
lri $ax0.l, #0
|
||||||
lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU)
|
lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU)
|
||||||
|
@ -55,18 +49,17 @@ main:
|
||||||
|
|
||||||
|
|
||||||
; get address of registers and DMA them to ram
|
; get address of registers and DMA them to ram
|
||||||
|
call 0x807e
|
||||||
call wait_for_dsp_mbox
|
|
||||||
si @DMBH, #0x8888
|
si @DMBH, #0x8888
|
||||||
si @DMBL, #0xbeef
|
si @DMBL, #0xbeef
|
||||||
si @DIRQ, #0x0001
|
si @DIRQ, #0x0001
|
||||||
|
|
||||||
call wait_for_cpu_mbox
|
call 0x8078
|
||||||
lrs $ac0.m, @CMBL
|
andi $ac0.m, #0x7fff
|
||||||
andi $ac1.m, #0x7fff
|
lrs $ac1.m, @CMBL
|
||||||
|
|
||||||
sr @MEM_HI, $ac1.m
|
sr @MEM_HI, $ac0.m
|
||||||
sr @MEM_LO, $ac0.m
|
sr @MEM_LO, $ac1.m
|
||||||
|
|
||||||
lri $ax0.l, #REGS_BASE
|
lri $ax0.l, #REGS_BASE
|
||||||
lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU)
|
lri $ax1.l, #0 ;(DSP_CR_IMEM | DSP_CR_TO_CPU)
|
||||||
|
@ -76,7 +69,6 @@ main:
|
||||||
call do_dma
|
call do_dma
|
||||||
|
|
||||||
; Read in all the registers from RAM
|
; Read in all the registers from RAM
|
||||||
|
|
||||||
lri $ar0, #REGS_BASE+1
|
lri $ar0, #REGS_BASE+1
|
||||||
lrri $ar1, @$ar0
|
lrri $ar1, @$ar0
|
||||||
lrri $ar2, @$ar0
|
lrri $ar2, @$ar0
|
||||||
|
@ -114,51 +106,21 @@ main:
|
||||||
jmp start_of_test
|
jmp start_of_test
|
||||||
|
|
||||||
; This is where we jump when we're done testing, see above.
|
; This is where we jump when we're done testing, see above.
|
||||||
end_of_test:
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
; We just fall into a loop, playing dead until someone resets the DSP.
|
; We just fall into a loop, playing dead until someone resets the DSP.
|
||||||
dead_loop:
|
end_of_test:
|
||||||
jmp dead_loop
|
jmp end_of_test
|
||||||
|
|
||||||
; Utility function to do DMA.
|
; Utility function to do DMA.
|
||||||
; ac0.l:ac0.m - external address.
|
|
||||||
; ax0.l - address in DSP
|
|
||||||
do_dma:
|
do_dma:
|
||||||
sr @DSMAH, $ac0.l
|
sr @DSMAH, $ac0.l
|
||||||
sr @DSMAL, $ac0.m
|
sr @DSMAL, $ac0.m
|
||||||
sr @DSPA, $ax0.l
|
sr @DSPA, $ax0.l
|
||||||
sr @DSCR, $ax1.l
|
sr @DSCR, $ax1.l
|
||||||
sr @DSBL, $ax0.h ; This kicks off the DMA.
|
sr @DSBL, $ax0.h ; This kicks off the DMA.
|
||||||
|
call 0x863d ; Wait for DMA to complete by watching a bit in DSCR.
|
||||||
; Waits for said DMA to complete by watching a bit in DSCR.
|
|
||||||
wait_dma:
|
|
||||||
lrs $ac1.m, @DSCR
|
|
||||||
andcf $ac1.m, #0x0004
|
|
||||||
jlz wait_dma
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; This waits for a mail to arrive in the DSP in-mailbox.
|
; IRQ handlers. Just send back exception# and die
|
||||||
wait_for_dsp_mbox:
|
|
||||||
lrs $ac1.m, @DMBH
|
|
||||||
andcf $ac1.m, #0x8000
|
|
||||||
jlz wait_for_dsp_mbox
|
|
||||||
ret
|
|
||||||
|
|
||||||
; This waits for the CPU to grab a mail that we just sent from the DSP.
|
|
||||||
wait_for_cpu_mbox:
|
|
||||||
lrs $ac1.m, @CMBH
|
|
||||||
andcf $ac1.m, #0x8000
|
|
||||||
jlnz wait_for_cpu_mbox
|
|
||||||
ret
|
|
||||||
|
|
||||||
; IRQ handlers. Not entirely sure what good they do currently.
|
|
||||||
irq0:
|
irq0:
|
||||||
lri $ac0.m, #0x0000
|
lri $ac0.m, #0x0000
|
||||||
jmp irq
|
jmp irq
|
||||||
|
@ -175,21 +137,6 @@ irq4:
|
||||||
lri $ac0.m, #0x0004
|
lri $ac0.m, #0x0004
|
||||||
jmp irq
|
jmp irq
|
||||||
irq5:
|
irq5:
|
||||||
; No idea what this code is doing.
|
|
||||||
s16
|
|
||||||
mrr $st1, $ac0.l
|
|
||||||
mrr $st1, $ac0.m
|
|
||||||
clr $acc0
|
|
||||||
mrr $ac0.m, $st1
|
|
||||||
mrr $ac0.l, $st1
|
|
||||||
nop ; Or why there's a nop sled here.
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
rti
|
|
||||||
|
|
||||||
lri $ac0.m, #0x0005
|
lri $ac0.m, #0x0005
|
||||||
jmp irq
|
jmp irq
|
||||||
irq6:
|
irq6:
|
||||||
|
@ -197,7 +144,6 @@ irq6:
|
||||||
jmp irq
|
jmp irq
|
||||||
irq7:
|
irq7:
|
||||||
lri $ac0.m, #0x0007
|
lri $ac0.m, #0x0007
|
||||||
jmp irq
|
|
||||||
|
|
||||||
irq:
|
irq:
|
||||||
lrs $ac1.m, @DMBH
|
lrs $ac1.m, @DMBH
|
||||||
|
@ -259,30 +205,26 @@ send_back:
|
||||||
lr $ac0.l, @MEM_HI
|
lr $ac0.l, @MEM_HI
|
||||||
lr $ac0.m, @MEM_LO
|
lr $ac0.m, @MEM_LO
|
||||||
|
|
||||||
lri $ar1, #8+8
|
|
||||||
|
|
||||||
; Now, why are we looping here?
|
; Now, why are we looping here?
|
||||||
|
lri $ar1, #8+8
|
||||||
bloop $ar1, dma_copy
|
bloop $ar1, dma_copy
|
||||||
call do_dma
|
call do_dma
|
||||||
addi $ac0.m, #0x200
|
addi $ac0.m, #0x200
|
||||||
mrr $ac1.m, $ax0.l
|
mrr $ac1.m, $ax0.l
|
||||||
addi $ac1.m, #0x100
|
addi $ac1.m, #0x100
|
||||||
|
dma_copy:
|
||||||
mrr $ax0.l, $ac1.m
|
mrr $ax0.l, $ac1.m
|
||||||
nop
|
|
||||||
|
|
||||||
dma_copy:
|
|
||||||
nop
|
|
||||||
|
|
||||||
; Wait for the CPU to send us a mail.
|
; Wait for the CPU to send us a mail.
|
||||||
call wait_for_dsp_mbox
|
call 0x807e
|
||||||
si @DMBH, #0x8888
|
si @DMBH, #0x8888
|
||||||
si @DMBL, #0xfeeb
|
si @DMBL, #0xfeeb
|
||||||
si @DIRQ, #0x0001
|
si @DIRQ, #0x0001
|
||||||
|
|
||||||
; wait for the CPU to recieve our response before we execute the next op
|
; wait for the CPU to recieve our response before we execute the next op
|
||||||
call wait_for_cpu_mbox
|
call 0x8078
|
||||||
lrs $ac0.m, @CMBL
|
andi $ac0.m, #0x7fff
|
||||||
andi $ac1.m, #0x7fff
|
lrs $ac1.m, @CMBL
|
||||||
|
|
||||||
; Restore all regs again so we're ready to execute another op.
|
; Restore all regs again so we're ready to execute another op.
|
||||||
lri $ar0, #REGS_BASE+1
|
lri $ar0, #REGS_BASE+1
|
||||||
|
@ -329,30 +271,5 @@ send_back_40:
|
||||||
set40
|
set40
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; This one's odd. Doesn't look like it should work since it uses ac0.m but
|
|
||||||
; increments acm0... (acc0)
|
|
||||||
; -- It's ok as addis adds short immediate to mid accumulator $acD.hm
|
|
||||||
dump_memory:
|
|
||||||
lri $ar2, #0x0000
|
|
||||||
lri $ac0.m, #0x1000
|
|
||||||
|
|
||||||
lri $ar1, #0x1000
|
|
||||||
bloop $ar1, _fill_loop2
|
|
||||||
|
|
||||||
mrr $ar3, $ac0.m
|
|
||||||
nx'ld : $ax0.h, $ax1.h, @$ar0
|
|
||||||
|
|
||||||
mrr $ac1.m, $ar0
|
|
||||||
mrr $ar0, $ar2
|
|
||||||
srri @$ar0, $ax1.h
|
|
||||||
mrr $ar2, $ar0
|
|
||||||
mrr $ar0, $ac1.m
|
|
||||||
|
|
||||||
addis $ac0.m, #0x1
|
|
||||||
|
|
||||||
_fill_loop2:
|
|
||||||
nop
|
|
||||||
ret ; from dump_memory
|
|
||||||
|
|
||||||
; Obviously this must be included directly before your test code
|
; Obviously this must be included directly before your test code
|
||||||
start_of_test:
|
start_of_test:
|
||||||
|
|
|
@ -59,9 +59,6 @@ bool DSPHost_Running()
|
||||||
|
|
||||||
void DSPHost_InterruptRequest()
|
void DSPHost_InterruptRequest()
|
||||||
{
|
{
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
|
||||||
NOTICE_LOG(DSPLLE, "Firing an interrupt on the PPC ASAP");
|
|
||||||
#endif
|
|
||||||
// Fire an interrupt on the PPC ASAP.
|
// Fire an interrupt on the PPC ASAP.
|
||||||
g_dspInitialize.pGenerateDSPInterrupt();
|
g_dspInitialize.pGenerateDSPInterrupt();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue