m68k: add new "interrupt" example
I don't completely understand how the scsp timers work; "8192" is a magic number I came up with by experimentation.
This commit is contained in:
parent
ab91778312
commit
f21e1d5c78
4
Makefile
4
Makefile
@ -84,7 +84,9 @@ m68k:
|
|||||||
m68k/%.bin: m68k
|
m68k/%.bin: m68k
|
||||||
$(MAKE) -C m68k $(notdir $@)
|
$(MAKE) -C m68k $(notdir $@)
|
||||||
|
|
||||||
scsp/sound_cpu.elf: scsp/sound_cpu.o m68k/slot.bin.o
|
scsp/sound_cpu__slot.elf: scsp/sound_cpu__slot.o m68k/slot.bin.o
|
||||||
|
|
||||||
|
scsp/sound_cpu__interrupt.elf: scsp/sound_cpu__interrupt.o m68k/interrupt.bin.o
|
||||||
|
|
||||||
# clean
|
# clean
|
||||||
clean: clean-sh
|
clean: clean-sh
|
||||||
|
@ -9,4 +9,6 @@ include $(LIB)/m68k/common.mk
|
|||||||
%.pcm.o: %.pcm
|
%.pcm.o: %.pcm
|
||||||
$(BUILD_BINARY_O)
|
$(BUILD_BINARY_O)
|
||||||
|
|
||||||
slot.elf: $(LIB)/m68k/vectors.o slot.o sine-44100-s16be-1ch.pcm.o
|
slot.elf: $(LIB)/m68k/vectors.o $(LIB)/m68k/handlers.o slot.o sine-44100-s16be-1ch.pcm.o
|
||||||
|
|
||||||
|
interrupt.elf: $(LIB)/m68k/vectors.o $(LIB)/m68k/handlers.o interrupt.o jojo-11025-s16be-1ch.pcm.o
|
||||||
|
88
m68k/interrupt.cpp
Normal file
88
m68k/interrupt.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "scsp.h"
|
||||||
|
|
||||||
|
extern void * _jojo_start __asm("_binary_jojo_11025_s16be_1ch_pcm_start");
|
||||||
|
|
||||||
|
static volatile int32_t frame = 0;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void auto_vector_1(void) __attribute__ ((interrupt_handler));
|
||||||
|
void auto_vector_1(void)
|
||||||
|
{
|
||||||
|
// reset TIMER_A interrupt
|
||||||
|
scsp.reg.ctrl.SCIRE = INT__TIMER_A;
|
||||||
|
|
||||||
|
frame++;
|
||||||
|
//if (frame > 3962) frame = 0;
|
||||||
|
|
||||||
|
const uint16_t * jojo_start = reinterpret_cast<uint16_t *>(&_jojo_start);
|
||||||
|
const uint32_t frame_addr = reinterpret_cast<uint32_t>(&jojo_start[frame * 8192]);
|
||||||
|
|
||||||
|
scsp_slot& slot = scsp.reg.slot[frame % 32];
|
||||||
|
slot.LOOP = 0;
|
||||||
|
slot.LOOP |= LOOP__KYONEX;
|
||||||
|
|
||||||
|
slot.LOOP = LOOP__KYONB | LOOP__SA(frame_addr); // kx kb sbctl[1:0] ssctl[1:0] lpctl[1:0] 8b sa[19:16]
|
||||||
|
slot.SA = SA__SA(frame_addr); // start address (bytes)
|
||||||
|
slot.LSA = 0; // loop start address (samples)
|
||||||
|
slot.LEA = 8192; // loop end address (samples)
|
||||||
|
slot.EG = EG__AR(0x1f) | EG__EGHOLD; // d2r d1r ho ar krs dl rr
|
||||||
|
slot.VOLUME = 0; // stwinh sdir tl
|
||||||
|
slot.FM = 0; // mdl mdxsl mdysl
|
||||||
|
slot.PITCH = PITCH__OCT(-2) | PITCH__FNS(0); // oct fns
|
||||||
|
slot.LFO = 0; // lfof plfows
|
||||||
|
slot.MIXER = MIXER__DISDL(0b101); // disdl dipan efsdl efpan
|
||||||
|
|
||||||
|
slot.LOOP |= LOOP__KYONEX;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
for (long i = 0; i < 807; i++) { asm volatile ("nop"); } // wait for (way) more than 30µs
|
||||||
|
|
||||||
|
scsp.reg.ctrl.MIXER = MIXER__MEM4MB | MIXER__MVOL(0xf);
|
||||||
|
|
||||||
|
scsp.reg.ctrl.TIMA = TIMA__TACTL(7);
|
||||||
|
|
||||||
|
// timer A is vector 1 (0b001)
|
||||||
|
scsp.reg.ctrl.SCILV2 = 0;
|
||||||
|
scsp.reg.ctrl.SCILV1 = 0;
|
||||||
|
scsp.reg.ctrl.SCILV0 = SCILV__TIMER_A;
|
||||||
|
|
||||||
|
// enable TIMER_A
|
||||||
|
scsp.reg.ctrl.SCIRE = INT__TIMER_A;
|
||||||
|
scsp.reg.ctrl.SCIEB = INT__TIMER_A;
|
||||||
|
|
||||||
|
asm volatile ("move.w #8192,%sr");
|
||||||
|
|
||||||
|
const uint16_t * jojo_start = reinterpret_cast<uint16_t *>(&_jojo_start);
|
||||||
|
const uint32_t frame_addr = reinterpret_cast<uint32_t>(&jojo_start[frame * 128]);
|
||||||
|
|
||||||
|
scsp_slot& slot = scsp.reg.slot[0];
|
||||||
|
slot.LOOP = 0;
|
||||||
|
slot.LOOP |= LOOP__KYONEX;
|
||||||
|
|
||||||
|
slot.LOOP = LOOP__KYONB | LOOP__SA(frame_addr); // kx kb sbctl[1:0] ssctl[1:0] lpctl[1:0] 8b sa[19:16]
|
||||||
|
slot.SA = SA__SA(frame_addr); // start address (bytes)
|
||||||
|
slot.LSA = 0; // loop start address (samples)
|
||||||
|
slot.LEA = 128; // loop end address (samples)
|
||||||
|
slot.EG = EG__AR(0x1f) | EG__EGHOLD; // d2r d1r ho ar krs dl rr
|
||||||
|
slot.VOLUME = 0; // stwinh sdir tl
|
||||||
|
slot.FM = 0; // mdl mdxsl mdysl
|
||||||
|
slot.PITCH = PITCH__OCT(-2) | PITCH__FNS(0); // oct fns
|
||||||
|
slot.LFO = 0; // lfof plfows
|
||||||
|
slot.MIXER = MIXER__DISDL(0b101); // disdl dipan efsdl efpan
|
||||||
|
|
||||||
|
slot.LOOP |= LOOP__KYONEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void start(void)
|
||||||
|
{
|
||||||
|
main();
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
BIN
m68k/jojo-11025-s16be-1ch.pcm
Normal file
BIN
m68k/jojo-11025-s16be-1ch.pcm
Normal file
Binary file not shown.
@ -1,8 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "smpc.h"
|
|
||||||
#include "scsp.h"
|
|
||||||
|
|
||||||
#include "../common/copy.hpp"
|
#include "scsp.h"
|
||||||
|
|
||||||
extern void * _sine_start __asm("_binary_sine_44100_s16be_1ch_pcm_start");
|
extern void * _sine_start __asm("_binary_sine_44100_s16be_1ch_pcm_start");
|
||||||
|
|
||||||
@ -15,6 +13,9 @@ void main()
|
|||||||
const uint32_t sine_start = reinterpret_cast<uint32_t>(&_sine_start);
|
const uint32_t sine_start = reinterpret_cast<uint32_t>(&_sine_start);
|
||||||
|
|
||||||
scsp_slot& slot = scsp.reg.slot[0];
|
scsp_slot& slot = scsp.reg.slot[0];
|
||||||
|
slot.LOOP = 0;
|
||||||
|
slot.LOOP |= LOOP__KYONEX;
|
||||||
|
|
||||||
slot.LOOP = LOOP__KYONB | LOOP__LPCTL__NORMAL | LOOP__SA(sine_start); // kx kb sbctl[1:0] ssctl[1:0] lpctl[1:0] 8b sa[19:16]
|
slot.LOOP = LOOP__KYONB | LOOP__LPCTL__NORMAL | LOOP__SA(sine_start); // kx kb sbctl[1:0] ssctl[1:0] lpctl[1:0] 8b sa[19:16]
|
||||||
slot.SA = SA__SA(sine_start); // start address (bytes)
|
slot.SA = SA__SA(sine_start); // start address (bytes)
|
||||||
slot.LSA = 0; // loop start address (samples)
|
slot.LSA = 0; // loop start address (samples)
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#include "../common/copy.hpp"
|
#include "../common/copy.hpp"
|
||||||
|
|
||||||
extern void * _binary_m68k_slot_bin_start __asm("_binary_m68k_slot_bin_start");
|
extern void * _m68k_start __asm("_binary_m68k_interrupt_bin_start");
|
||||||
extern void * _binary_m68k_slot_bin_size __asm("_binary_m68k_slot_bin_size");
|
extern void * _m68k_size __asm("_binary_m68k_interrupt_bin_size");
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@ -23,8 +23,8 @@ void main()
|
|||||||
|
|
||||||
scsp.reg.ctrl.MIXER = MIXER__MEM4MB;
|
scsp.reg.ctrl.MIXER = MIXER__MEM4MB;
|
||||||
|
|
||||||
uint32_t * m68k_main_start = (uint32_t *)&_binary_m68k_slot_bin_start;
|
uint32_t * m68k_main_start = reinterpret_cast<uint32_t*>(&_m68k_start);
|
||||||
uint32_t m68k_main_size = (uint32_t)&_binary_m68k_slot_bin_size;
|
uint32_t m68k_main_size = reinterpret_cast<uint32_t>(&_m68k_size);
|
||||||
copy<uint32_t>(&scsp.ram.u32[0], m68k_main_start, m68k_main_size);
|
copy<uint32_t>(&scsp.ram.u32[0], m68k_main_start, m68k_main_size);
|
||||||
|
|
||||||
while ((smpc.reg.SF & 1) != 0);
|
while ((smpc.reg.SF & 1) != 0);
|
43
scsp/sound_cpu__slot.cpp
Normal file
43
scsp/sound_cpu__slot.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "smpc.h"
|
||||||
|
#include "scsp.h"
|
||||||
|
|
||||||
|
#include "../common/copy.hpp"
|
||||||
|
|
||||||
|
extern void * _m68k_start __asm("_binary_m68k_slot_bin_start");
|
||||||
|
extern void * _m68k_size __asm("_binary_m68k_slot_bin_size");
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
/* SEGA SATURN TECHNICAL BULLETIN # 51
|
||||||
|
|
||||||
|
The document suggests that Sound RAM is (somewhat) preserved
|
||||||
|
during SNDOFF.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while ((smpc.reg.SF & 1) != 0);
|
||||||
|
smpc.reg.SF = 1;
|
||||||
|
smpc.reg.COMREG = COMREG__SNDOFF;
|
||||||
|
while (smpc.reg.oreg[31] != OREG31__SNDOFF);
|
||||||
|
|
||||||
|
scsp.reg.ctrl.MIXER = MIXER__MEM4MB;
|
||||||
|
|
||||||
|
uint32_t * m68k_main_start = reinterpret_cast<uint32_t*>(&_m68k_start);
|
||||||
|
uint32_t m68k_main_size = reinterpret_cast<uint32_t>(&_m68k_size);
|
||||||
|
copy<uint32_t>(&scsp.ram.u32[0], m68k_main_start, m68k_main_size);
|
||||||
|
|
||||||
|
while ((smpc.reg.SF & 1) != 0);
|
||||||
|
smpc.reg.SF = 1;
|
||||||
|
smpc.reg.COMREG = COMREG__SNDON;
|
||||||
|
while (smpc.reg.oreg[31] != OREG31__SNDON);
|
||||||
|
|
||||||
|
// do nothing while the sound CPU manipulates the SCSP
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void start(void)
|
||||||
|
{
|
||||||
|
main();
|
||||||
|
while (1);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user