2009-04-18 11:31:37 +00:00
|
|
|
/* DSP_MIXER -> PCM VOICE SOFTWARE PROCESSOR (8-16 Bits Mono/Stereo Voices)
|
|
|
|
|
|
|
|
// Thanks to Duddie for you hard work and documentation
|
|
|
|
|
|
|
|
Copyright (c) 2008 Hermes <www.entuwii.net>
|
|
|
|
All rights reserved.
|
|
|
|
|
2021-07-05 02:15:36 +00:00
|
|
|
SPDX-License-Identifier: BSD-3-Clause
|
2009-04-18 11:31:37 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2022-06-14 00:03:19 +00:00
|
|
|
#include "HermesText.h"
|
2009-04-18 11:31:37 +00:00
|
|
|
|
2022-06-14 00:03:19 +00:00
|
|
|
const char s_hermes_text[21370] = R"(
|
2009-04-18 11:31:37 +00:00
|
|
|
/********************************/
|
|
|
|
/** REGISTER NAMES **/
|
|
|
|
/********************************/
|
|
|
|
|
|
|
|
AR0: equ 0x00 ; address registers
|
|
|
|
AR1: equ 0x01
|
|
|
|
AR2: equ 0x02
|
|
|
|
AR3: equ 0x03 // used as jump function selector
|
|
|
|
|
|
|
|
IX0: equ 0x04 // LEFT_VOLUME accel
|
|
|
|
IX1: equ 0x05 // RIGHT_VOLUME accel
|
|
|
|
IX2: equ 0x06 // ADDRH_SMP accel
|
|
|
|
IX3: equ 0x07 // ADDRL_SMP accel
|
|
|
|
|
|
|
|
R08: equ 0x08 // fixed to 48000 value
|
|
|
|
R09: equ 0x09 // problems using this
|
|
|
|
R0A: equ 0x0a // ADDREH_SMP accel
|
|
|
|
R0B: equ 0x0b // ADDREL_SMP accel
|
|
|
|
|
|
|
|
ST0: equ 0x0c
|
|
|
|
ST1: equ 0x0d
|
|
|
|
ST2: equ 0x0e
|
|
|
|
ST3: equ 0x0f
|
|
|
|
|
|
|
|
CONFIG: equ 0x12
|
|
|
|
SR: equ 0x13
|
|
|
|
|
|
|
|
PRODL: equ 0x14
|
|
|
|
PRODM: equ 0x15
|
|
|
|
PRODH: equ 0x16
|
|
|
|
PRODM2: equ 0x17
|
|
|
|
|
|
|
|
AXL0: equ 0x18
|
|
|
|
AXL1: equ 0x19
|
|
|
|
AXH0: equ 0x1A // SMP_R accel
|
|
|
|
AXH1: equ 0x1b // SMP_L accel
|
|
|
|
|
|
|
|
ACC0: equ 0x1c // accumulator (global)
|
|
|
|
ACC1: equ 0x1d
|
|
|
|
|
|
|
|
ACL0: equ 0x1c // Low accumulator
|
|
|
|
ACL1: equ 0x1d
|
|
|
|
ACM0: equ 0x1e // Mid accumulator
|
|
|
|
ACM1: equ 0x1f
|
|
|
|
ACH0: equ 0x10 // Sign extended 8 bit register 0
|
|
|
|
ACH1: equ 0x11 // Sign extended 8 bit register 1
|
|
|
|
|
|
|
|
/********************************/
|
|
|
|
/** HARDWARE REGISTER ADDRESS **/
|
|
|
|
/********************************/
|
|
|
|
|
|
|
|
DSCR: equ 0xffc9 ; DSP DMA Control Reg
|
|
|
|
DSBL: equ 0xffcb ; DSP DMA Block Length
|
|
|
|
DSPA: equ 0xffcd ; DSP DMA DMEM Address
|
|
|
|
DSMAH: equ 0xffce ; DSP DMA Mem Address H
|
|
|
|
DSMAL: equ 0xffcf ; DSP DMA Mem Address L
|
|
|
|
|
|
|
|
DIRQ: equ 0xfffb ; DSP Irq Request
|
|
|
|
DMBH: equ 0xfffc ; DSP Mailbox H
|
|
|
|
DMBL: equ 0xfffd ; DSP Mailbox L
|
|
|
|
CMBH: equ 0xfffe ; CPU Mailbox H
|
|
|
|
CMBL: equ 0xffff ; CPU Mailbox L
|
|
|
|
|
|
|
|
DMA_TO_DSP: equ 0
|
|
|
|
DMA_TO_CPU: equ 1
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* NUM_SAMPLES SLICE */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
NUM_SAMPLES: equ 1024 ; 1024 stereo samples 16 bits
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* SOUND CHANNEL REGS */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
MEM_REG2: equ 0x0
|
|
|
|
MEM_VECTH: equ MEM_REG2
|
|
|
|
MEM_VECTL: equ MEM_REG2+1
|
|
|
|
RETURN: equ MEM_REG2+2
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* CHANNEL DATAS */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
MEM_REG: equ MEM_REG2+0x10
|
|
|
|
|
|
|
|
ADDRH_SND: equ MEM_REG // Output buffer
|
|
|
|
ADDRL_SND: equ MEM_REG+1
|
|
|
|
|
|
|
|
DELAYH_SND: equ MEM_REG+2 // Delay samples High word
|
|
|
|
DELAYL_SND: equ MEM_REG+3 // Delay samples Low word
|
|
|
|
|
|
|
|
CHAN_REGS: equ MEM_REG+4 // specific regs for the channel
|
|
|
|
|
|
|
|
FLAGSH_SMP: equ CHAN_REGS+0 // countain number of bytes for step (1-> Mono 8 bits, 2-> Stereo 8 bits and Mono 16 bits, 4-> Stereo 16 bits)
|
|
|
|
FLAGSL_SMP: equ CHAN_REGS+1 // 0->Mono 8 bits, 1->Stereo 8 bits, 2->Mono 16 bits 3 -> Stereo 16 bits
|
|
|
|
|
|
|
|
ADDRH_SMP: equ CHAN_REGS+2 // start address
|
|
|
|
ADDRL_SMP: equ CHAN_REGS+3
|
|
|
|
|
|
|
|
ADDREH_SMP: equ CHAN_REGS+4 // end address
|
|
|
|
ADDREL_SMP: equ CHAN_REGS+5
|
|
|
|
|
|
|
|
FREQH_SMP: equ CHAN_REGS+6 // Freq in Hz to play
|
|
|
|
FREQL_SMP: equ CHAN_REGS+7
|
|
|
|
|
|
|
|
SMP_L: equ CHAN_REGS+8 // last sample for left (used to joint various buffers)
|
|
|
|
SMP_R: equ CHAN_REGS+9 // last sample for right (used to joint various buffers)
|
|
|
|
|
|
|
|
COUNTERH_SMP: equ CHAN_REGS+10 // pitch counter
|
|
|
|
COUNTERL_SMP: equ CHAN_REGS+11
|
|
|
|
|
|
|
|
LEFT_VOLUME: equ CHAN_REGS+12 // volume (0 to 255)
|
|
|
|
RIGHT_VOLUME: equ CHAN_REGS+13
|
|
|
|
|
|
|
|
ADDR2H_SMP: equ CHAN_REGS+14 // start address of buffer two (to joint)
|
|
|
|
ADDR2L_SMP: equ CHAN_REGS+15
|
|
|
|
|
|
|
|
ADDR2EH_SMP: equ CHAN_REGS+16 // end address of buffer two (to joint)
|
|
|
|
ADDR2EL_SMP: equ CHAN_REGS+17
|
|
|
|
|
|
|
|
LEFT_VOLUME2: equ CHAN_REGS+18 // volume (0 to 255) for buffer two
|
|
|
|
RIGHT_VOLUME2: equ CHAN_REGS+19
|
|
|
|
|
|
|
|
BACKUPH_SMP: equ CHAN_REGS+20 // start address backup
|
|
|
|
BACKUPL_SMP: equ CHAN_REGS+21
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* VOICE SAMPLE BUFFER DATAS */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
MEM_SAMP: equ CHAN_REGS+0x20
|
|
|
|
|
|
|
|
|
|
|
|
data_end: equ MEM_SAMP+0x20
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* SND OUTPUT DATAS */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
MEM_SND: equ data_end ; it need 2048 words (4096 bytes)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*** START CODE ***/
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* EXCEPTION TABLE */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
jmp exception0
|
|
|
|
jmp exception1
|
|
|
|
jmp exception2
|
|
|
|
jmp exception3
|
|
|
|
jmp exception4
|
|
|
|
jmp exception5
|
|
|
|
jmp exception6
|
|
|
|
jmp exception7
|
|
|
|
|
|
|
|
lri $CONFIG, #0xff
|
|
|
|
lri $SR,#0
|
UnitTests: Update DSP test text for old renames
This change makes assembling DSPTestText match DSPTestBinary, though HermesText doesn't yet match HermesBinary.
The test data was originally added on April 18, 2009 in e7e4ef4481d1c5dcce6463414d815843ae15b8e2. Then, set16 and set40 were swapped on April 22, 2009 89178f411cf1e8ef61b005197545618e53a0d4e8, which updated the DSPSpy version of dsp_code, but not the version in DSPTool used for testing. So, when the test was made, the assembled data matched the text, but a few days after it no longer did.
Similarly, on Jul 7, 2009 in 1654c582ab9a6323a31802c4b241c0cffc9d3bca the conditional instructions were adjusted, and 0x1706 was changed from JRL to JRNC and 0x0297 was changed from JGE to JC.
For what it's worth, devkitPro made the same changes on May 31, 2010 in https://github.com/devkitPro/gamecube-tools/commit/8a65c85c9b4748ed3dab3c0c85aeb0df95d58cfb and updated their version of the asnd ucode (which is this ucode) on June 11, 2011 in https://github.com/devkitpro/libogc/commit/b1b8ecab3af3745c8df0b401abd512bdf5fcc011 (though this update also includes other feature changes). Note that at the time, they didn't reassemble the ucode unless they made changes to it; the assembled was stored in the repo until https://github.com/devkitPro/libogc/compare/bfb705fe1607a3031d18b65d603975b68a1cffd4~...d20f9bdcfb43260c6c759f4fb98d724931443f93.
This fixes the following failures with Hermes:
!! 0015 : 8e00 vs 8f00 - set16 vs set40
!! 016f : 8e00 vs 8f00 - set16 vs set40
and with Hermes:
!! 0014 : 8e00 vs 8f00 - set16 vs set40
!! 0063 : 8e00 vs 8f00 - set16 vs set40
!! 019b : 1706 vs 1701 - jrnc $AR0 vs jrl $AR0
!! 01bf : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
!! 01d2 : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
Hermes has the remaining failures:
!! 027b : 03c0 vs 03a0 - andcf $AC1.M, #0x8000 vs andf $AC1.M, #0x8000
!! 027d : 029d vs 0294 - jlz 0x027a vs jnz 0x027a
2022-06-14 04:46:03 +00:00
|
|
|
s16
|
2009-04-18 11:31:37 +00:00
|
|
|
clr15
|
|
|
|
m0
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* main */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
main:
|
|
|
|
|
|
|
|
// send init token to CPU
|
|
|
|
|
|
|
|
si @DMBH, #0xdcd1
|
|
|
|
si @DMBL, #0x0000
|
|
|
|
si @DIRQ, #1
|
|
|
|
|
|
|
|
recv_cmd:
|
|
|
|
// check if previous mail is received from the CPU
|
|
|
|
|
|
|
|
call wait_for_dsp_mail
|
|
|
|
|
|
|
|
// wait a mail from CPU
|
|
|
|
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
|
|
|
|
si @DMBH, #0xdcd1
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
lri $ACM0,#0xcdd1
|
|
|
|
cmp
|
|
|
|
jz sys_command
|
|
|
|
|
|
|
|
clr $ACC1
|
|
|
|
lrs $ACM1, @CMBL
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x111 // fill the internal sample buffer and process the voice internally
|
|
|
|
jz input_samples
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x112 // get samples from the external buffer to the internal buffer and process the voice mixing the samples internally
|
|
|
|
jz input_samples2
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x123 // get the address of the voice datas buffer (CHANNEL DATAS)
|
|
|
|
jz get_data_addr
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x222 // process the voice mixing the samples internally
|
|
|
|
jz input_next_samples
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x666 // send the samples for the internal buffer to the external buffer
|
|
|
|
jz send_samples
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x777 // special: to dump the IROM Datas (remember disable others functions from the interrupt vector to use)
|
|
|
|
jz rom_dump_word // (CMBH+0x8000) countain the address of IROM
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x888 // Used for test
|
|
|
|
jz polla_loca
|
|
|
|
|
|
|
|
cmpi $ACM1, #0x999
|
|
|
|
jz task_terminate
|
|
|
|
|
|
|
|
si @DMBL, #0x0004 // return 0 as ignore command
|
|
|
|
si @DIRQ, #0x1 // set the interrupt
|
|
|
|
jmp recv_cmd
|
|
|
|
|
|
|
|
task_terminate:
|
|
|
|
si @DMBL, #0x0003
|
|
|
|
si @DIRQ, #0x1
|
|
|
|
jmp recv_cmd
|
|
|
|
|
|
|
|
sys_command:
|
|
|
|
clr $ACC1
|
|
|
|
lrs $ACM1, @CMBL
|
|
|
|
|
|
|
|
cmpi $ACM1,#0x0001
|
|
|
|
jz run_nexttask
|
|
|
|
|
|
|
|
cmpi $ACM1,#0x0002
|
|
|
|
jz 0x8000
|
|
|
|
|
|
|
|
jmp recv_cmd
|
|
|
|
|
|
|
|
run_nexttask:
|
UnitTests: Update DSP test text for old renames
This change makes assembling DSPTestText match DSPTestBinary, though HermesText doesn't yet match HermesBinary.
The test data was originally added on April 18, 2009 in e7e4ef4481d1c5dcce6463414d815843ae15b8e2. Then, set16 and set40 were swapped on April 22, 2009 89178f411cf1e8ef61b005197545618e53a0d4e8, which updated the DSPSpy version of dsp_code, but not the version in DSPTool used for testing. So, when the test was made, the assembled data matched the text, but a few days after it no longer did.
Similarly, on Jul 7, 2009 in 1654c582ab9a6323a31802c4b241c0cffc9d3bca the conditional instructions were adjusted, and 0x1706 was changed from JRL to JRNC and 0x0297 was changed from JGE to JC.
For what it's worth, devkitPro made the same changes on May 31, 2010 in https://github.com/devkitPro/gamecube-tools/commit/8a65c85c9b4748ed3dab3c0c85aeb0df95d58cfb and updated their version of the asnd ucode (which is this ucode) on June 11, 2011 in https://github.com/devkitpro/libogc/commit/b1b8ecab3af3745c8df0b401abd512bdf5fcc011 (though this update also includes other feature changes). Note that at the time, they didn't reassemble the ucode unless they made changes to it; the assembled was stored in the repo until https://github.com/devkitPro/libogc/compare/bfb705fe1607a3031d18b65d603975b68a1cffd4~...d20f9bdcfb43260c6c759f4fb98d724931443f93.
This fixes the following failures with Hermes:
!! 0015 : 8e00 vs 8f00 - set16 vs set40
!! 016f : 8e00 vs 8f00 - set16 vs set40
and with Hermes:
!! 0014 : 8e00 vs 8f00 - set16 vs set40
!! 0063 : 8e00 vs 8f00 - set16 vs set40
!! 019b : 1706 vs 1701 - jrnc $AR0 vs jrl $AR0
!! 01bf : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
!! 01d2 : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
Hermes has the remaining failures:
!! 027b : 03c0 vs 03a0 - andcf $AC1.M, #0x8000 vs andf $AC1.M, #0x8000
!! 027d : 029d vs 0294 - jlz 0x027a vs jnz 0x027a
2022-06-14 04:46:03 +00:00
|
|
|
s16
|
2009-04-18 11:31:37 +00:00
|
|
|
call wait_for_cpu_mail
|
|
|
|
lrs $29,@CMBL
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lrs $29,@CMBL
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lrs $29,@CMBL
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lr $5,@CMBL
|
|
|
|
andi $31,#0x0fff
|
|
|
|
mrr $4,$31
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lr $7,@CMBL
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lr $6,@CMBL
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lr $0,@CMBL
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lrs $24,@CMBL
|
|
|
|
andi $31,#0x0fff
|
|
|
|
mrr $26,$31
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lrs $25,@CMBL
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
lrs $27,@CMBL
|
|
|
|
sbclr #0x05
|
|
|
|
sbclr #0x06
|
|
|
|
jmp 0x80b5
|
|
|
|
halt
|
|
|
|
|
|
|
|
/**************************************************************************************************************************************/
|
|
|
|
// send the samples for the internal buffer to the external buffer
|
|
|
|
|
|
|
|
send_samples:
|
|
|
|
|
|
|
|
lri $AR0, #MEM_SND
|
|
|
|
lris $AXL1, #DMA_TO_CPU;
|
|
|
|
lri $AXL0, #NUM_SAMPLES*4 ; len
|
|
|
|
lr $ACM0, @ADDRH_SND
|
|
|
|
lr $ACL0, @ADDRL_SND
|
|
|
|
|
|
|
|
call do_dma
|
|
|
|
si @DMBL, #0x0004
|
|
|
|
si @DIRQ, #0x1 // set the interrupt
|
|
|
|
jmp recv_cmd
|
|
|
|
|
|
|
|
/**************************************************************************************************************************************/
|
|
|
|
// get the address of the voice datas buffer (CHANNEL DATAS)
|
|
|
|
|
|
|
|
get_data_addr:
|
|
|
|
call wait_for_cpu_mail
|
|
|
|
|
|
|
|
lrs $ACM0, @CMBH
|
|
|
|
lr $ACL0, @CMBL
|
|
|
|
|
|
|
|
sr @MEM_VECTH, $ACM0
|
|
|
|
sr @MEM_VECTL, $ACL0
|
|
|
|
|
|
|
|
si @DIRQ, #0x0 // clear the interrupt
|
|
|
|
jmp recv_cmd
|
|
|
|
|
|
|
|
/**************************************************************************************************************************************/
|
|
|
|
// fill the internal sample buffer and process the voice internally
|
|
|
|
|
|
|
|
input_samples:
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
lr $ACM0, @MEM_VECTH
|
|
|
|
lr $ACL0, @MEM_VECTL
|
|
|
|
|
|
|
|
lris $AXL0, #0x0004
|
|
|
|
sr @RETURN, $AXL0
|
|
|
|
si @DIRQ, #0x0000
|
|
|
|
|
|
|
|
// program DMA to get datas
|
|
|
|
|
|
|
|
lri $AR0, #MEM_REG
|
|
|
|
lris $AXL1, #DMA_TO_DSP
|
|
|
|
lris $AXL0, #64 ; len
|
|
|
|
|
|
|
|
call do_dma
|
|
|
|
|
|
|
|
lri $AR1, #MEM_SND
|
|
|
|
lri $ACL1, #0;
|
|
|
|
|
|
|
|
lri $AXL0, #NUM_SAMPLES
|
|
|
|
bloop $AXL0, loop_get1
|
|
|
|
|
|
|
|
srri @$AR1, $ACL1
|
|
|
|
srri @$AR1, $ACL1
|
|
|
|
|
|
|
|
loop_get1:
|
|
|
|
nop
|
|
|
|
|
|
|
|
lr $ACM0, @ADDRH_SND
|
|
|
|
lr $ACL0, @ADDRL_SND
|
|
|
|
jmp start_main
|
|
|
|
|
|
|
|
/**************************************************************************************************************************************/
|
|
|
|
// get samples from the external buffer to the internal buffer and process the voice mixing the samples internally
|
|
|
|
|
|
|
|
input_samples2:
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
lr $ACM0, @MEM_VECTH
|
|
|
|
lr $ACL0, @MEM_VECTL
|
|
|
|
|
|
|
|
lris $AXL0, #0x0004
|
|
|
|
sr @RETURN, $AXL0
|
|
|
|
si @DIRQ, #0x0000
|
|
|
|
|
|
|
|
// program DMA to get datas
|
|
|
|
|
|
|
|
lri $AR0, #MEM_REG
|
|
|
|
lri $AXL1, #DMA_TO_DSP
|
|
|
|
lris $AXL0, #64 ; len
|
|
|
|
|
|
|
|
call do_dma
|
|
|
|
|
|
|
|
lr $ACM0, @ADDRH_SND
|
|
|
|
lr $ACL0, @ADDRL_SND
|
|
|
|
|
|
|
|
lri $AR0, #MEM_SND
|
|
|
|
lris $AXL1, #DMA_TO_DSP;
|
|
|
|
lri $AXL0, #NUM_SAMPLES*4; len
|
|
|
|
|
|
|
|
call do_dma
|
|
|
|
|
|
|
|
jmp start_main
|
|
|
|
|
|
|
|
/**************************************************************************************************************************************/
|
|
|
|
// process the voice mixing the samples internally
|
|
|
|
|
|
|
|
input_next_samples:
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
lr $ACM0, @MEM_VECTH
|
|
|
|
lr $ACL0, @MEM_VECTL
|
|
|
|
|
|
|
|
lris $AXL0, #0x0004
|
|
|
|
sr @RETURN, $AXL0
|
|
|
|
si @DIRQ, #0x0000
|
|
|
|
|
|
|
|
// program DMA to get datas
|
|
|
|
|
|
|
|
lri $AR0, #MEM_REG
|
|
|
|
lris $AXL1, #DMA_TO_DSP
|
|
|
|
lris $AXL0, #64 ; len
|
|
|
|
|
|
|
|
call do_dma
|
|
|
|
|
|
|
|
/**************************************************************************************************************************************/
|
|
|
|
// mixing and control pitch to create 1024 Stereo Samples at 16 bits from here
|
|
|
|
|
|
|
|
start_main:
|
|
|
|
|
|
|
|
lri $R08, #48000
|
|
|
|
|
|
|
|
// load the previous samples used
|
|
|
|
|
|
|
|
lr $AXH0, @SMP_R
|
|
|
|
lr $AXH1, @SMP_L
|
|
|
|
|
|
|
|
// optimize the jump function to get MONO/STEREO 8/16 bits samples
|
|
|
|
|
|
|
|
lr $ACM1, @FLAGSL_SMP
|
|
|
|
andi $ACM1, #0x3
|
|
|
|
addi $ACM1, #sample_selector
|
|
|
|
mrr $AR3, $ACM1
|
|
|
|
ilrr $ACM1, @$AR3
|
|
|
|
mrr $AR3, $ACM1 // AR3 countain the jump loaded from sample selector
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
|
|
|
|
// test for channel paused
|
|
|
|
|
|
|
|
lr $ACM0, @FLAGSL_SMP
|
|
|
|
andcf $ACM0, #0x20
|
|
|
|
jlz end_main
|
|
|
|
|
|
|
|
// load the sample address
|
|
|
|
|
|
|
|
lr $ACM0, @ADDRH_SMP
|
|
|
|
lr $ACL0, @ADDRL_SMP
|
|
|
|
|
|
|
|
// test if ADDR_SMP & ADDR2H_SMP are zero
|
|
|
|
|
|
|
|
tst $ACC0
|
|
|
|
jnz do_not_change1
|
|
|
|
|
|
|
|
// set return as "change of buffer"
|
|
|
|
|
|
|
|
lris $AXL0, #0x0004
|
|
|
|
sr @RETURN, $AXL0
|
|
|
|
|
|
|
|
// change to buffer 2 if it is possible
|
|
|
|
|
|
|
|
call change_buffer
|
|
|
|
|
|
|
|
// stops if again 0 address
|
|
|
|
|
|
|
|
tst $ACC0
|
|
|
|
jz save_datas_end
|
|
|
|
|
|
|
|
do_not_change1:
|
|
|
|
|
|
|
|
|
|
|
|
// backup the external sample address
|
|
|
|
|
|
|
|
mrr $IX2, $ACM0
|
|
|
|
mrr $IX3, $ACL0
|
|
|
|
|
|
|
|
|
|
|
|
// load the counter pitch
|
|
|
|
|
|
|
|
//lr $r08, @COUNTERH_SMP
|
|
|
|
//lr $r09, @COUNTERL_SMP
|
|
|
|
|
|
|
|
// load the end address of the samples
|
|
|
|
|
|
|
|
lr $r0a, @ADDREH_SMP
|
|
|
|
lr $r0b, @ADDREL_SMP
|
|
|
|
|
|
|
|
// load AR1 with internal buffer address
|
|
|
|
|
|
|
|
lri $AR1, #MEM_SND
|
|
|
|
|
|
|
|
/////////////////////////////////////
|
|
|
|
// delay time section
|
|
|
|
/////////////////////////////////////
|
|
|
|
|
|
|
|
// load AXL0 with the samples to be processed
|
|
|
|
|
|
|
|
lri $AXL0, #NUM_SAMPLES
|
|
|
|
|
|
|
|
// test if DELAY == 0 and skip or not
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
clr $ACC1
|
|
|
|
lr $ACH0, @DELAYH_SND
|
|
|
|
lr $ACM0, @DELAYL_SND
|
|
|
|
tst $ACC0
|
|
|
|
jz no_delay
|
|
|
|
|
|
|
|
// samples left and right to 0
|
|
|
|
|
|
|
|
lris $AXH0, #0
|
|
|
|
lris $AXH1, #0
|
|
|
|
|
|
|
|
// load the samples to be processed in ACM1
|
|
|
|
|
|
|
|
mrr $ACM1, $AXL0
|
|
|
|
l_delay:
|
|
|
|
iar $AR1 // skip two samples
|
|
|
|
iar $AR1
|
|
|
|
decm $ACM1
|
|
|
|
jz exit_delay1 // exit1 if samples to be processed == 0
|
|
|
|
|
|
|
|
decm $ACM0
|
|
|
|
jz exit_delay2 // exit2 if delay time == 0
|
|
|
|
jmp l_delay
|
|
|
|
|
|
|
|
// store the remanent delay and ends
|
|
|
|
|
|
|
|
exit_delay1:
|
|
|
|
decm $ACM0
|
|
|
|
|
|
|
|
sr @DELAYH_SND, $ACH0
|
|
|
|
sr @DELAYL_SND, $ACM0
|
|
|
|
|
|
|
|
lris $AXL0,#0 ; exit from loop
|
|
|
|
|
|
|
|
jmp no_delay
|
|
|
|
|
|
|
|
|
|
|
|
exit_delay2:
|
|
|
|
|
|
|
|
// store delay=0 and continue
|
|
|
|
|
|
|
|
sr @DELAYH_SND, $ACH0
|
|
|
|
sr @DELAYL_SND, $ACM0
|
|
|
|
mrr $AXL0, $ACL1 // load remanent samples to be processed in AXL0
|
|
|
|
|
|
|
|
no_delay:
|
|
|
|
|
|
|
|
/////////////////////////////////////
|
|
|
|
// end of delay time section
|
|
|
|
/////////////////////////////////////
|
2022-06-14 00:03:19 +00:00
|
|
|
)" // Work around C2026 on MSVC, which allows at most 16380 single-byte characters in a single
|
|
|
|
// non-concatenated string literal (but you can concatenate multiple shorter string literals to
|
|
|
|
// produce a longer string just fine). (This comment is not part of the actual test program,
|
|
|
|
// and instead there is a single blank line at this location.)
|
|
|
|
R"(
|
2009-04-18 11:31:37 +00:00
|
|
|
/* bucle de generacion de samples */
|
|
|
|
|
|
|
|
|
|
|
|
// load the sample buffer with address aligned to 32 bytes blocks (first time)
|
|
|
|
|
|
|
|
si @DSCR, #DMA_TO_DSP // very important!: load_smp_addr_align and jump_load_smp_addr need fix this DMA Register (I gain some cycles so)
|
|
|
|
|
|
|
|
// load_smp_addr_align input: $IX2:$IX3
|
|
|
|
|
|
|
|
call load_smp_addr_align
|
|
|
|
|
|
|
|
// load the volume registers
|
|
|
|
|
|
|
|
lr $IX0, @LEFT_VOLUME
|
|
|
|
lr $IX1, @RIGHT_VOLUME
|
|
|
|
|
|
|
|
// test the freq value
|
|
|
|
|
|
|
|
clr $ACL0
|
|
|
|
lr $ACH0, @FREQH_SMP
|
|
|
|
lr $ACM0, @FREQL_SMP
|
|
|
|
|
|
|
|
clr $ACC1
|
|
|
|
;lri $ACM1,#48000
|
|
|
|
mrr $ACM1, $R08
|
|
|
|
cmp
|
|
|
|
|
|
|
|
// select the output of the routine to process stereo-mono 8/16bits samples
|
|
|
|
|
|
|
|
lri $AR0, #get_sample // fast method <=48000
|
|
|
|
|
|
|
|
// if number is greater freq>48000 fix different routine
|
|
|
|
|
|
|
|
ifg
|
|
|
|
lri $AR0, #get_sample2 // slow method >48000
|
|
|
|
|
|
|
|
// loops for samples to be processed
|
|
|
|
|
|
|
|
bloop $AXL0, loop_end
|
|
|
|
|
|
|
|
//srri @$AR1, $AXH0 // put sample R
|
|
|
|
//srri @$AR1, $AXH1 // put sample L
|
|
|
|
|
|
|
|
// Mix right sample section
|
|
|
|
|
|
|
|
lrr $ACL0, @$AR1 // load in ACL0 the right sample from the internal buffer
|
|
|
|
movax $ACC1, $AXL1 // big trick :) load the current sample <<16 and sign extended
|
|
|
|
|
|
|
|
asl $ACC0,#24 // convert sample from buffer to 24 bit number with sign extended (ACH0:ACM0)
|
|
|
|
asr $ACC0,#-8
|
|
|
|
|
|
|
|
add $ACC0,$ACC1 // current_sample+buffer sample
|
|
|
|
|
|
|
|
cmpi $ACM0,#32767 // limit to 32767
|
|
|
|
jle right_skip
|
|
|
|
|
|
|
|
lri $ACM0, #32767
|
|
|
|
jmp right_skip2
|
|
|
|
|
|
|
|
right_skip:
|
|
|
|
|
|
|
|
cmpi $ACM0,#-32768 // limit to -32768
|
|
|
|
ifle
|
|
|
|
lri $ACM0, #-32768
|
|
|
|
|
|
|
|
right_skip2:
|
|
|
|
|
|
|
|
srri @$AR1, $ACM0 // store the right sample mixed to the internal buffer and increment AR1
|
|
|
|
|
|
|
|
// Mix left sample section
|
|
|
|
|
|
|
|
lrr $ACL0, @$AR1 // load in ACL0 the left sample from the internal buffer
|
|
|
|
|
|
|
|
movax $ACC1, $AXL0 // big trick :) load the current sample <<16 and sign extended
|
|
|
|
|
|
|
|
asl $ACC0, #24 // convert sample from buffer to 24 bit number with sign extended (ACH0:ACM0)
|
|
|
|
asr $ACC0, #-8
|
|
|
|
|
|
|
|
add $ACC0, $ACC1 // current_sample+buffer sample
|
|
|
|
|
|
|
|
cmpi $ACM0,#32767 // limit to 32767
|
|
|
|
jle left_skip
|
|
|
|
|
|
|
|
lri $ACM0, #32767
|
|
|
|
jmp left_skip2
|
|
|
|
|
|
|
|
left_skip:
|
|
|
|
|
|
|
|
cmpi $ACM0,#-32768 // limit to -32768
|
|
|
|
ifle
|
|
|
|
lri $ACM0, #-32768
|
|
|
|
|
|
|
|
left_skip2:
|
|
|
|
|
|
|
|
srri @$AR1, $ACM0 // store the left sample mixed to the internal buffer and increment AR1
|
|
|
|
|
|
|
|
// adds the counter with the voice frequency and test if it >=48000 to get the next sample
|
|
|
|
|
|
|
|
clr $ACL1
|
|
|
|
lr $ACH1, @COUNTERH_SMP
|
|
|
|
lr $ACM1, @COUNTERL_SMP
|
|
|
|
clr $ACL0
|
|
|
|
lr $ACH0, @FREQH_SMP
|
|
|
|
lr $ACM0, @FREQL_SMP
|
|
|
|
|
|
|
|
add $ACC1,$ACC0
|
|
|
|
clr $ACC0
|
|
|
|
//lri $ACM0,#48000
|
|
|
|
mrr $ACM0, $R08
|
|
|
|
|
|
|
|
cmp
|
|
|
|
|
UnitTests: Update DSP test text for old renames
This change makes assembling DSPTestText match DSPTestBinary, though HermesText doesn't yet match HermesBinary.
The test data was originally added on April 18, 2009 in e7e4ef4481d1c5dcce6463414d815843ae15b8e2. Then, set16 and set40 were swapped on April 22, 2009 89178f411cf1e8ef61b005197545618e53a0d4e8, which updated the DSPSpy version of dsp_code, but not the version in DSPTool used for testing. So, when the test was made, the assembled data matched the text, but a few days after it no longer did.
Similarly, on Jul 7, 2009 in 1654c582ab9a6323a31802c4b241c0cffc9d3bca the conditional instructions were adjusted, and 0x1706 was changed from JRL to JRNC and 0x0297 was changed from JGE to JC.
For what it's worth, devkitPro made the same changes on May 31, 2010 in https://github.com/devkitPro/gamecube-tools/commit/8a65c85c9b4748ed3dab3c0c85aeb0df95d58cfb and updated their version of the asnd ucode (which is this ucode) on June 11, 2011 in https://github.com/devkitpro/libogc/commit/b1b8ecab3af3745c8df0b401abd512bdf5fcc011 (though this update also includes other feature changes). Note that at the time, they didn't reassemble the ucode unless they made changes to it; the assembled was stored in the repo until https://github.com/devkitPro/libogc/compare/bfb705fe1607a3031d18b65d603975b68a1cffd4~...d20f9bdcfb43260c6c759f4fb98d724931443f93.
This fixes the following failures with Hermes:
!! 0015 : 8e00 vs 8f00 - set16 vs set40
!! 016f : 8e00 vs 8f00 - set16 vs set40
and with Hermes:
!! 0014 : 8e00 vs 8f00 - set16 vs set40
!! 0063 : 8e00 vs 8f00 - set16 vs set40
!! 019b : 1706 vs 1701 - jrnc $AR0 vs jrl $AR0
!! 01bf : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
!! 01d2 : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
Hermes has the remaining failures:
!! 027b : 03c0 vs 03a0 - andcf $AC1.M, #0x8000 vs andf $AC1.M, #0x8000
!! 027d : 029d vs 0294 - jlz 0x027a vs jnz 0x027a
2022-06-14 04:46:03 +00:00
|
|
|
jrnc $AR0 //get_sample or get_sample2 method
|
2009-04-18 11:31:37 +00:00
|
|
|
|
|
|
|
sr @COUNTERH_SMP, $ACH1
|
|
|
|
sr @COUNTERL_SMP, $ACM1
|
|
|
|
|
|
|
|
jmp loop_end
|
|
|
|
|
|
|
|
// get a new sample for freq > 48000 Hz
|
|
|
|
|
|
|
|
get_sample2: // slow method
|
|
|
|
|
|
|
|
sub $ACC1,$ACC0 // restore the counter
|
|
|
|
|
|
|
|
// restore the external sample buffer address
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
mrr $ACM0, $IX2 // load ADDRH_SMP
|
|
|
|
mrr $ACL0, $IX3 // load ADDRL_SMP
|
|
|
|
|
|
|
|
lr $AXL1, @FLAGSH_SMP // add the step to get the next samples
|
|
|
|
addaxl $ACC0, $AXL1
|
|
|
|
|
|
|
|
mrr $IX2, $ACM0 // store ADDRH_SMP
|
|
|
|
mrr $IX3, $ACL0 // store ADDRL_SMP
|
|
|
|
|
|
|
|
mrr $ACM0, $ACL0
|
|
|
|
andf $ACM0, #0x1f
|
|
|
|
|
|
|
|
// load_smp_addr_align input: $IX2:$IX3 call if (ACM0 & 0x1f)==0
|
|
|
|
|
|
|
|
calllz load_smp_addr_align
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
//lri $ACM0,#48000
|
|
|
|
mrr $ACM0, $R08
|
|
|
|
|
|
|
|
cmp
|
|
|
|
|
|
|
|
jle get_sample2
|
|
|
|
|
|
|
|
sr @COUNTERH_SMP, $ACH1
|
|
|
|
sr @COUNTERL_SMP, $ACM1
|
|
|
|
|
|
|
|
mrr $ACM0, $IX2 // load ADDRH_SMP
|
|
|
|
mrr $ACL0, $IX3 // load ADDRL_SMP
|
|
|
|
|
|
|
|
clr $ACC1
|
|
|
|
mrr $ACM1, $r0a // load ADDREH_SMP
|
|
|
|
mrr $ACL1, $r0b // load ADDREL_SMP
|
|
|
|
|
|
|
|
// compares if the current address is >= end address to change the buffer or stops
|
|
|
|
|
|
|
|
cmp
|
|
|
|
|
|
|
|
// if addr>addr end get a new buffer (if you uses double buffer)
|
|
|
|
|
UnitTests: Update DSP test text for old renames
This change makes assembling DSPTestText match DSPTestBinary, though HermesText doesn't yet match HermesBinary.
The test data was originally added on April 18, 2009 in e7e4ef4481d1c5dcce6463414d815843ae15b8e2. Then, set16 and set40 were swapped on April 22, 2009 89178f411cf1e8ef61b005197545618e53a0d4e8, which updated the DSPSpy version of dsp_code, but not the version in DSPTool used for testing. So, when the test was made, the assembled data matched the text, but a few days after it no longer did.
Similarly, on Jul 7, 2009 in 1654c582ab9a6323a31802c4b241c0cffc9d3bca the conditional instructions were adjusted, and 0x1706 was changed from JRL to JRNC and 0x0297 was changed from JGE to JC.
For what it's worth, devkitPro made the same changes on May 31, 2010 in https://github.com/devkitPro/gamecube-tools/commit/8a65c85c9b4748ed3dab3c0c85aeb0df95d58cfb and updated their version of the asnd ucode (which is this ucode) on June 11, 2011 in https://github.com/devkitpro/libogc/commit/b1b8ecab3af3745c8df0b401abd512bdf5fcc011 (though this update also includes other feature changes). Note that at the time, they didn't reassemble the ucode unless they made changes to it; the assembled was stored in the repo until https://github.com/devkitPro/libogc/compare/bfb705fe1607a3031d18b65d603975b68a1cffd4~...d20f9bdcfb43260c6c759f4fb98d724931443f93.
This fixes the following failures with Hermes:
!! 0015 : 8e00 vs 8f00 - set16 vs set40
!! 016f : 8e00 vs 8f00 - set16 vs set40
and with Hermes:
!! 0014 : 8e00 vs 8f00 - set16 vs set40
!! 0063 : 8e00 vs 8f00 - set16 vs set40
!! 019b : 1706 vs 1701 - jrnc $AR0 vs jrl $AR0
!! 01bf : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
!! 01d2 : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
Hermes has the remaining failures:
!! 027b : 03c0 vs 03a0 - andcf $AC1.M, #0x8000 vs andf $AC1.M, #0x8000
!! 027d : 029d vs 0294 - jlz 0x027a vs jnz 0x027a
2022-06-14 04:46:03 +00:00
|
|
|
jc get_new_buffer
|
2009-04-18 11:31:37 +00:00
|
|
|
|
|
|
|
// load samples from dma, return $ar2 with the addr to get the samples and return using $ar0 to the routine to process 8-16bits Mono/Stereo
|
|
|
|
|
|
|
|
jmp jump_load_smp_addr
|
|
|
|
|
|
|
|
// get a new sample for freq <= 48000 Hz
|
|
|
|
|
|
|
|
get_sample: // fast method
|
|
|
|
|
|
|
|
sub $ACC1,$ACC0 // restore the counter
|
|
|
|
sr @COUNTERH_SMP, $ACH1
|
|
|
|
sr @COUNTERL_SMP, $ACM1
|
|
|
|
|
|
|
|
// restore the external sample buffer address
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
mrr $ACM0, $IX2 // load ADDRH_SMP
|
|
|
|
mrr $ACL0, $IX3 // load ADDRL_SMP
|
|
|
|
|
|
|
|
lr $AXL1, @FLAGSH_SMP // add the step to get the next samples
|
|
|
|
addaxl $ACC0, $AXL1
|
|
|
|
|
|
|
|
clr $ACC1
|
|
|
|
mrr $ACM1, $r0a // load ADDREH_SMP
|
|
|
|
mrr $ACL1, $r0b // load ADDREL_SMP
|
|
|
|
|
|
|
|
// compares if the current address is >= end address to change the buffer or stops
|
|
|
|
|
|
|
|
cmp
|
UnitTests: Update DSP test text for old renames
This change makes assembling DSPTestText match DSPTestBinary, though HermesText doesn't yet match HermesBinary.
The test data was originally added on April 18, 2009 in e7e4ef4481d1c5dcce6463414d815843ae15b8e2. Then, set16 and set40 were swapped on April 22, 2009 89178f411cf1e8ef61b005197545618e53a0d4e8, which updated the DSPSpy version of dsp_code, but not the version in DSPTool used for testing. So, when the test was made, the assembled data matched the text, but a few days after it no longer did.
Similarly, on Jul 7, 2009 in 1654c582ab9a6323a31802c4b241c0cffc9d3bca the conditional instructions were adjusted, and 0x1706 was changed from JRL to JRNC and 0x0297 was changed from JGE to JC.
For what it's worth, devkitPro made the same changes on May 31, 2010 in https://github.com/devkitPro/gamecube-tools/commit/8a65c85c9b4748ed3dab3c0c85aeb0df95d58cfb and updated their version of the asnd ucode (which is this ucode) on June 11, 2011 in https://github.com/devkitpro/libogc/commit/b1b8ecab3af3745c8df0b401abd512bdf5fcc011 (though this update also includes other feature changes). Note that at the time, they didn't reassemble the ucode unless they made changes to it; the assembled was stored in the repo until https://github.com/devkitPro/libogc/compare/bfb705fe1607a3031d18b65d603975b68a1cffd4~...d20f9bdcfb43260c6c759f4fb98d724931443f93.
This fixes the following failures with Hermes:
!! 0015 : 8e00 vs 8f00 - set16 vs set40
!! 016f : 8e00 vs 8f00 - set16 vs set40
and with Hermes:
!! 0014 : 8e00 vs 8f00 - set16 vs set40
!! 0063 : 8e00 vs 8f00 - set16 vs set40
!! 019b : 1706 vs 1701 - jrnc $AR0 vs jrl $AR0
!! 01bf : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
!! 01d2 : 0297 vs 0290 - jc 0x01dc vs jge 0x01dc
Hermes has the remaining failures:
!! 027b : 03c0 vs 03a0 - andcf $AC1.M, #0x8000 vs andf $AC1.M, #0x8000
!! 027d : 029d vs 0294 - jlz 0x027a vs jnz 0x027a
2022-06-14 04:46:03 +00:00
|
|
|
jc get_new_buffer
|
2009-04-18 11:31:37 +00:00
|
|
|
|
|
|
|
// load the new sample from the buffer
|
|
|
|
|
|
|
|
mrr $IX2, $ACM0 // store ADDRH_SMP
|
|
|
|
mrr $IX3, $ACL0 // store ADDRL_SMP
|
|
|
|
|
|
|
|
// load samples from dma, return $ar2 with the addr and return using $ar0 to the routine to process 8-16bits Mono/Stereo or addr_get_sample_again
|
|
|
|
|
|
|
|
jmp jump_load_smp_addr
|
|
|
|
|
|
|
|
sample_selector:
|
|
|
|
cw mono_8bits
|
|
|
|
cw mono_16bits
|
|
|
|
cw stereo_8bits
|
|
|
|
cw stereo_16bits
|
|
|
|
|
|
|
|
get_new_buffer:
|
|
|
|
|
|
|
|
// set return as "change of buffer": it need to change the sample address
|
|
|
|
|
|
|
|
lris $AXL0, #0x0004
|
|
|
|
sr @RETURN, $AXL0
|
|
|
|
|
|
|
|
call change_buffer // load add from addr2
|
|
|
|
|
|
|
|
// addr is 0 ? go to zero_samples and exit
|
|
|
|
|
|
|
|
tst $acc0
|
|
|
|
jz zero_samples
|
|
|
|
|
|
|
|
// load_smp_addr_align input: $IX2:$IX3
|
|
|
|
|
|
|
|
call load_smp_addr_align // force the load the samples cached (address aligned)
|
|
|
|
|
|
|
|
// jump_load_smp_addr: $IX2:$IX3
|
|
|
|
// load samples from dma, return $ar2 with the addr to get the samples and return using $ar0 to the routine to process 8-16bits Mono/Stereo
|
|
|
|
|
|
|
|
jmp jump_load_smp_addr
|
|
|
|
|
|
|
|
// set to 0 the current samples
|
|
|
|
|
|
|
|
zero_samples:
|
|
|
|
|
|
|
|
lris $AXH0, #0
|
|
|
|
lris $AXH1, #0
|
|
|
|
jmp out_samp
|
|
|
|
|
|
|
|
mono_8bits:
|
|
|
|
|
|
|
|
// 8 bits mono
|
|
|
|
mrr $ACM1, $IX3
|
|
|
|
lrri $ACL0, @$AR2
|
|
|
|
andf $ACM1, #0x1
|
|
|
|
|
|
|
|
iflz // obtain sample0-sample1 from 8bits packet
|
|
|
|
asr $ACL0, #-8
|
|
|
|
asl $ACL0, #8
|
|
|
|
|
|
|
|
mrr $AXH1,$ACL0
|
|
|
|
mrr $AXH0,$ACL0
|
|
|
|
jmp out_samp
|
|
|
|
|
|
|
|
stereo_8bits:
|
|
|
|
|
|
|
|
// 8 bits stereo
|
|
|
|
|
|
|
|
lrri $ACL0, @$AR2
|
|
|
|
mrr $ACM0, $ACL0
|
|
|
|
andi $ACM0, #0xff00
|
|
|
|
mrr $AXH1, $ACM0
|
|
|
|
lsl $ACL0, #8
|
|
|
|
mrr $AXH0, $ACL0
|
|
|
|
|
|
|
|
jmp out_samp
|
|
|
|
|
|
|
|
mono_16bits:
|
|
|
|
|
|
|
|
// 16 bits mono
|
|
|
|
|
|
|
|
lrri $AXH1, @$AR2
|
|
|
|
mrr $AXH0,$AXH1
|
|
|
|
jmp out_samp
|
|
|
|
|
|
|
|
stereo_16bits:
|
|
|
|
|
|
|
|
// 16 bits stereo
|
|
|
|
|
|
|
|
lrri $AXH1, @$AR2
|
|
|
|
lrri $AXH0, @$AR2
|
|
|
|
|
|
|
|
out_samp:
|
|
|
|
|
|
|
|
// multiply sample x volume
|
|
|
|
|
|
|
|
// LEFT_VOLUME
|
|
|
|
mrr $AXL0,$IX0
|
|
|
|
mul $AXL0,$AXH0
|
|
|
|
movp $ACL0
|
|
|
|
asr $ACL0,#-8
|
|
|
|
mrr $AXH0, $ACL0
|
|
|
|
|
|
|
|
// RIGHT VOLUME
|
|
|
|
mrr $AXL1,$IX1
|
|
|
|
mul $AXL1,$AXH1
|
|
|
|
movp $ACL0
|
|
|
|
asr $ACL0,#-8
|
|
|
|
mrr $AXH1, $ACL0
|
|
|
|
|
|
|
|
loop_end:
|
|
|
|
nop
|
|
|
|
|
|
|
|
end_process:
|
|
|
|
|
|
|
|
// load the sample address
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
mrr $ACM0, $IX2
|
|
|
|
mrr $ACL0, $IX3
|
|
|
|
|
|
|
|
tst $ACC0
|
|
|
|
jnz save_datas_end
|
|
|
|
|
|
|
|
// set return as "change of buffer"
|
|
|
|
|
|
|
|
lris $AXL0, #0x0004
|
|
|
|
sr @RETURN, $AXL0
|
|
|
|
|
|
|
|
// change to buffer 2 if it is possible
|
|
|
|
|
|
|
|
call change_buffer
|
|
|
|
|
|
|
|
save_datas_end:
|
|
|
|
|
|
|
|
sr @ADDRH_SMP, $IX2
|
|
|
|
sr @ADDRL_SMP, $IX3
|
|
|
|
sr @SMP_R, $AXH0
|
|
|
|
sr @SMP_L, $AXH1
|
|
|
|
|
|
|
|
end_main:
|
|
|
|
|
|
|
|
// program DMA to send the CHANNEL DATAS changed
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
lr $ACM0, @MEM_VECTH
|
|
|
|
lr $ACL0, @MEM_VECTL
|
|
|
|
|
|
|
|
lri $AR0, #MEM_REG
|
|
|
|
lris $AXL1, #DMA_TO_CPU
|
|
|
|
lris $AXL0, #64 ; len
|
|
|
|
|
|
|
|
call do_dma
|
|
|
|
|
|
|
|
si @DMBH, #0xdcd1
|
|
|
|
lr $ACL0, @RETURN
|
|
|
|
|
|
|
|
sr @DMBL, $ACL0
|
|
|
|
si @DIRQ, #0x1 // set the interrupt
|
|
|
|
|
|
|
|
jmp recv_cmd
|
|
|
|
|
|
|
|
change_buffer:
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
lr $ACM0, @LEFT_VOLUME2
|
|
|
|
lr $ACL0, @RIGHT_VOLUME2
|
|
|
|
sr @LEFT_VOLUME, $ACM0
|
|
|
|
sr @RIGHT_VOLUME, $ACL0
|
|
|
|
mrr $IX0, $ACM0
|
|
|
|
mrr $IX1, $ACL0
|
|
|
|
|
|
|
|
lr $ACM0, @ADDR2EH_SMP
|
|
|
|
lr $ACL0, @ADDR2EL_SMP
|
|
|
|
sr @ADDREH_SMP, $ACM0
|
|
|
|
sr @ADDREL_SMP, $ACL0
|
|
|
|
mrr $r0a, $ACM0
|
|
|
|
mrr $r0b, $ACL0
|
|
|
|
|
|
|
|
lr $ACM0, @ADDR2H_SMP
|
|
|
|
lr $ACL0, @ADDR2L_SMP
|
|
|
|
sr @ADDRH_SMP, $ACM0
|
|
|
|
sr @ADDRL_SMP, $ACL0
|
|
|
|
sr @BACKUPH_SMP, $ACM0
|
|
|
|
sr @BACKUPL_SMP, $ACL0
|
|
|
|
mrr $IX2, $ACM0
|
|
|
|
mrr $IX3, $ACL0
|
|
|
|
|
|
|
|
lr $ACM1, @FLAGSL_SMP
|
|
|
|
andcf $ACM1, #0x4
|
|
|
|
retlz
|
|
|
|
|
|
|
|
sr @ADDR2H_SMP, $ACH0
|
|
|
|
sr @ADDR2L_SMP, $ACH0
|
|
|
|
sr @ADDR2EH_SMP, $ACH0
|
|
|
|
sr @ADDR2EL_SMP, $ACH0
|
|
|
|
ret
|
|
|
|
|
|
|
|
/**************************************************************/
|
|
|
|
/* DMA ROUTINE */
|
|
|
|
/**************************************************************/
|
|
|
|
|
|
|
|
do_dma:
|
|
|
|
|
|
|
|
sr @DSMAH, $ACM0
|
|
|
|
sr @DSMAL, $ACL0
|
|
|
|
sr @DSPA, $AR0
|
|
|
|
sr @DSCR, $AXL1
|
|
|
|
sr @DSBL, $AXL0
|
|
|
|
|
|
|
|
wait_dma:
|
|
|
|
|
|
|
|
lrs $ACM1, @DSCR
|
|
|
|
andcf $ACM1, #0x4
|
|
|
|
jlz wait_dma
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
wait_for_dsp_mail:
|
|
|
|
|
|
|
|
lrs $ACM1, @DMBH
|
|
|
|
andf $ACM1, #0x8000
|
|
|
|
jnz wait_for_dsp_mail
|
|
|
|
ret
|
|
|
|
|
|
|
|
wait_for_cpu_mail:
|
|
|
|
|
|
|
|
lrs $ACM1, @cmbh
|
|
|
|
andcf $ACM1, #0x8000
|
|
|
|
jlnz wait_for_cpu_mail
|
|
|
|
ret
|
|
|
|
|
|
|
|
load_smp_addr_align:
|
|
|
|
|
|
|
|
mrr $ACL0, $IX3 // load ADDRL_SMP
|
|
|
|
|
|
|
|
lsr $ACC0, #-5
|
|
|
|
lsl $ACC0, #5
|
|
|
|
sr @DSMAH, $IX2
|
|
|
|
sr @DSMAL, $ACL0
|
|
|
|
si @DSPA, #MEM_SAMP
|
|
|
|
;si @DSCR, #DMA_TO_DSP
|
|
|
|
si @DSBL, #0x20
|
|
|
|
|
|
|
|
wait_dma1:
|
|
|
|
lrs $ACM0, @DSCR
|
|
|
|
andcf $ACM0, #0x4
|
|
|
|
jlz wait_dma1
|
|
|
|
|
|
|
|
lri $AR2, #MEM_SAMP
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////
|
|
|
|
|
|
|
|
jump_load_smp_addr:
|
|
|
|
|
|
|
|
mrr $ACM0, $IX3 // load ADDRL_SMP
|
|
|
|
asr $ACC0, #-1
|
|
|
|
andi $ACM0, #0xf
|
|
|
|
jz jump_load_smp_dma
|
|
|
|
|
|
|
|
addi $ACM0, #MEM_SAMP
|
|
|
|
mrr $AR2, $ACM0
|
|
|
|
jmpr $AR3
|
|
|
|
|
|
|
|
jump_load_smp_dma:
|
|
|
|
|
|
|
|
sr @DSMAH, $IX2
|
|
|
|
sr @DSMAL, $IX3
|
|
|
|
si @DSPA, #MEM_SAMP
|
|
|
|
;si @DSCR, #DMA_TO_DSP // to gain some cycles
|
|
|
|
si @DSBL, #0x20
|
|
|
|
|
|
|
|
wait_dma2:
|
|
|
|
lrs $ACM0, @DSCR
|
|
|
|
andcf $ACM0, #0x4
|
|
|
|
jlz wait_dma2
|
|
|
|
|
|
|
|
lri $AR2, #MEM_SAMP
|
|
|
|
jmpr $AR3
|
|
|
|
|
|
|
|
// exception table
|
|
|
|
|
|
|
|
exception0: // RESET
|
|
|
|
rti
|
|
|
|
|
|
|
|
exception1: // STACK OVERFLOW
|
|
|
|
rti
|
|
|
|
|
|
|
|
exception2:
|
|
|
|
rti
|
|
|
|
|
|
|
|
exception3:
|
|
|
|
rti
|
|
|
|
|
|
|
|
exception4:
|
|
|
|
rti
|
|
|
|
|
|
|
|
exception5: // ACCELERATOR ADDRESS OVERFLOW
|
|
|
|
rti
|
|
|
|
|
|
|
|
exception6:
|
|
|
|
rti
|
|
|
|
|
|
|
|
exception7:
|
|
|
|
rti
|
|
|
|
|
|
|
|
// routine to read a word of the IROM space
|
|
|
|
|
|
|
|
rom_dump_word:
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
|
|
|
|
lr $ACM0, @CMBH
|
|
|
|
ori $ACM0, #0x8000
|
|
|
|
mrr $AR0, $ACM0
|
|
|
|
clr $ACC0
|
|
|
|
ilrr $ACM0, @$AR0
|
|
|
|
sr @DMBH, $ACL0
|
|
|
|
sr @DMBL, $ACM0
|
|
|
|
;si @DIRQ, #0x1 // set the interrupt
|
|
|
|
clr $ACC0
|
|
|
|
jmp recv_cmd
|
|
|
|
|
|
|
|
polla_loca:
|
|
|
|
|
|
|
|
clr $ACC0
|
|
|
|
lri $acm0, #0x0
|
|
|
|
andf $acm0,#0x1
|
|
|
|
|
|
|
|
sr @DMBH, $sr
|
|
|
|
sr @DMBL, $acm0
|
|
|
|
;si @DIRQ, #0x1 // set the interrupt
|
|
|
|
clr $ACC0
|
|
|
|
jmp recv_cmd
|
|
|
|
|
2022-06-14 00:03:19 +00:00
|
|
|
)";
|