Sephnroth
Member
Hey, thanks to Dzz's great tutorials and his indulgance with my questions I learned what I needed to get started with coding for the 940. At first I did a quick test peice of code which simply set a shared variable to 0 during initialisation and then set it to 6 when the 940 was in its main loop - I read the result on the 920 and it was working grand (used printf to read the var from console)
so then I started work on a basic sound engine the idea being get bare bones mixer, get wavs working on it then see about other formats. At first I wrote a load of stupid code because I was under the ridiculous impression that I could use asm SWI calls from the 940 so was trying to open() wavs and ioctl from there. When I found out it was frustrating but no problem, I can iocotl on the 920 and buffer file data through the shared variable struct. I wrote code to do that buffering and went to test it on the 940 (the first test since my basic "set a variable" test) and noticed that the status variable was always reading 0 suddenly, it should still be 6.
after much messing around I realised that if I excluded my mixer.c file from my 940 project (which gets compiled into a .bin and loaded that way at runtime) then suddenly the status switched to 6 as it should do! This is odd because I dont use any of the code in that file yet! I commented out all the stuff I was going to move to the 920 anyway so I was left with just the bare bones mixer and it STILL breaks the whole thing if that c file is compiled and linked into the project :/ Anyone got any clues why? heres the relevent files
940 code:
main file with the loop and status setting (and also the code to read buffered wav data, note those malloc functions are empty at present):
you might also note that at the start of the function now it sets the variable to 5 instead of 0, that was a test and the showed what i most feared, the output of that var was still 0 so this function is never getting called.
this is heavenlymixer.c which breaks the whole thing, excluding it fixes it just fine -_-
and just incase its of any relevence, the entry point for the 940 code, but this is just the standard setup from dzz's demo tutorials:
thats it for 940 code.
920:
940.cpp in full, pretty much dzz's demo stuff but 940 memory shifted to 48mb offset to be sdl freindly:
im completly stumped. i commented pretty much everything out of the mixer except the main mixer because I cant afford to remove that, the whole point of this exercise is to get the heavy audio work going on the 940! if i take the mixer off I may as well do the lot on the 920. but simply if heavenlymixer.c is compiled into the bin, usStatus == 0. if excluded, == 6 as it should be
im so lost as to what to do >< sorry for long post, but if anyone can help, thanks!
EDIT:
bah this was supposed to be the I Need Help dev forum --; sorry :/
so then I started work on a basic sound engine the idea being get bare bones mixer, get wavs working on it then see about other formats. At first I wrote a load of stupid code because I was under the ridiculous impression that I could use asm SWI calls from the 940 so was trying to open() wavs and ioctl from there. When I found out it was frustrating but no problem, I can iocotl on the 920 and buffer file data through the shared variable struct. I wrote code to do that buffering and went to test it on the 940 (the first test since my basic "set a variable" test) and noticed that the status variable was always reading 0 suddenly, it should still be 6.
after much messing around I realised that if I excluded my mixer.c file from my 940 project (which gets compiled into a .bin and loaded that way at runtime) then suddenly the status switched to 6 as it should do! This is odd because I dont use any of the code in that file yet! I commented out all the stuff I was going to move to the 920 anyway so I was left with just the bare bones mixer and it STILL breaks the whole thing if that c file is compiled and linked into the project :/ Anyone got any clues why? heres the relevent files
940 code:
main file with the loop and status setting (and also the code to read buffered wav data, note those malloc functions are empty at present):
Code:
#include "lib940.h"
#include "shared940.h"
#include "heavenlymixer.h"
volatile tSharedVariables *gGlobStruct;
//USER ENTRY POINT, start your coding for the 940t here
/*
//920 writes these, 940 reads them
unsigned int nLoadWavStatus;
unsigned char cWavBuffer[512];
unsigned int nTotalSize;
unsigned int nThisSampleSize;
unsigned int nThisSampleStart;
//940 writes these, 920 reads
BOOL940 bFinishedRead;
unsigned int nLastSampleStart;
*/
unsigned int nLastStart = -1;
unsigned char *tmpWavBuffer = 0;
#define _user_malloc(s) malloc940(s)
#define _user_free(p) free940(p)
void main940() {
int p;
gGlobStruct = (tSharedVariables *) 0xF00000;
gGlobStruct->usStatus = 5;
gGlobStruct->bQuitProgram = 0;
while (!gGlobStruct->bQuitProgram) {
gGlobStruct->usStatus = 6;
//the 920 has a wav to load, its going to buffer the data to us so lets read it and tell it when we're ready for more
if (gGlobStruct->nLoadWavStatus == WAV_LOAD) {
if (gGlobStruct->nThisSampleStart == 0) { //bit of an unnessiary check this one, but you never know..
if (tmpWavBuffer != 0) {
_user_free(tmpWavBuffer); //free any old temporary wav data if it exists
}
tmpWavBuffer = _user_malloc(gGlobStruct->nTotalSize); //allocate a temp buffer for the new data
while (gGlobStruct->nLoadWavStatus == WAV_LOAD) { //while in load status loop
if (nLastStart != gGlobStruct->nThisSampleStart) { //if the last starting point we read from doesnt equal the new one then fresh data exists to load
gGlobStruct->bFinishedRead = 0; //let the 920 know we are definatly not finished
for (p = 0; p < gGlobStruct->nThisSampleLength; p++) {
// tmpWavBuffer[p + gGlobStruct->nThisSampleStart] = gGlobStruct->cWavBuffer[p]; //copy the data in offset by the last copy we did
}
nLastStart = gGlobStruct->nThisSampleStart; //set the last start to the current one
} else {
gGlobStruct->bFinishedRead = 1; //here we let the 920 know we are ready for fresh data
//it will change the sample start when it updates with new data so this process will repeat
}
}
//if we get to here we should have the complete wav data in our buffer
//pass it to the audio system and free our temp buffer
//LoadWav(tmpWavBuffer, 0, 0);
_user_free(tmpWavBuffer);
tmpWavBuffer = 0;
}
}
}
}
you might also note that at the start of the function now it sets the variable to 5 instead of 0, that was a test and the showed what i most feared, the output of that var was still 0 so this function is never getting called.
this is heavenlymixer.c which breaks the whole thing, excluding it fixes it just fine -_-
Code:
#include "heavenlymixer.h"
#include "lib940.h"
t_sndChannel sChannels[MAX_CHANNELS];
short sSoundBuffer[STANDARD_BUFFER_SIZE];
int devDSP;
int bSoundInit = 0;
void UpdateMixer(short *sOutput, unsigned int unBufferSize) {
int i, nChan, nSample1, nSample2;
for (i = 0; i < (unBufferSize >> 1); i++) { //for the length of the buffer..
nSample1 = 0; //reset the sample to 0
//////////////////////////////
// calculate audio sample //
//////////////////////////////
for (nChan = 0; nChan < MAX_CHANNELS; nChan++) { //loop through all the possiable channels
t_sndChannel *thisChanPtr = &sChannels[nChan]; //create a temporary pointer (optimisation, means you dont need to calculate the addres of nChannels[nChan] every time)
if (thisChanPtr->bPlay == 1) { //if playing..
nSample1 += thisChanPtr->sndData[thisChanPtr->sndPos] * thisChanPtr->sndVol; //add the sample data multiplied by the volume
thisChanPtr->sndPos++; //up the current position in this peice of audio
if (thisChanPtr->sndPos >= thisChanPtr->sndLength) { //if beyond the real length of the audio..
if (thisChanPtr->loopLength == 0) { //and it doesnt loop..
thisChanPtr->bPlay = 0; //stop the playback.
} else { //otherwise if it does loop..
while (thisChanPtr->sndPos >= thisChanPtr->sndLength) {
thisChanPtr->sndPos -= thisChanPtr->loopLength; //rewind the song back to its loop point
}
}
}
}
}
//////////////////////////////
// write sample to buffer //
//////////////////////////////
nSample1 >>= 2; //it.. um.. does something important, I forgot :/
//mix sample with buffer (simply compatbility, maybe something has already added to it?) then check for clipping (dont want to blow peoples ears now :P)
nSample2 = ((int)*sOutput) + nSample1;
if (nSample2 > CLIP_MAX) { nSample2 = CLIP_MAX; }
if (nSample2 < CLIP_MIN) { nSample2 = CLIP_MIN; }
//write this audio sample into the output buffer
*sOutput++ = (short)nSample2;
//have to do it again because gp2x = stereo sound and this = mono mixer
nSample2 = ((int)*sOutput) + nSample1;
if (nSample2 > CLIP_MAX) { nSample2 = CLIP_MAX; }
if (nSample2 < CLIP_MIN) { nSample2 = CLIP_MIN; }
*sOutput++ = (short)nSample2;
}
}
void ResetSound() {
int nChan;
for (nChan = 0; nChan < MAX_CHANNELS; nChan++) {
sChannels[nChan].bPlay = 0;
sChannels[nChan].loopLength = 0;
sChannels[nChan].sndData = 0;
sChannels[nChan].sndLength = 0;
sChannels[nChan].sndPos = 0;
sChannels[nChan].sndVol = 0;
}
ClearBuffer(STANDARD_BUFFER_SIZE);
}
void ClearBuffer(int nSize) {
int i;
for (i = 0; i < nSize; i++) {
sSoundBuffer[i] = 0;
}
}
void LoadWav(unsigned char *wav_data, int nChan, int nLoop) {
if (nChan < 0 || nChan >= MAX_CHANNELS) {
return;
}
}
and just incase its of any relevence, the entry point for the 940 code, but this is just the standard setup from dzz's demo tutorials:
Code:
extern void main940();
void entry940(void) __attribute__((naked));
void entry940(void) {
asm volatile (
"b .CodeEntryPoint @ reset all entry points to same place (0x0)\n"
"b .CodeEntryPoint\n"
"b .CodeEntryPoint\n"
"b .CodeEntryPoint\n"
"b .CodeEntryPoint\n"
"b .CodeEntryPoint\n"
"b .CodeEntryPoint\n"
"b .CodeEntryPoint\n"
".CodeEntryPoint:\n"
"mov sp, #0x100000 @ set the top of the stack at 1M\n"
"sub sp, sp, #4 @ minus 4\n"
/*
Setting up memory region 0 as uncached
bit 0 = enable
bit 1-5 = 5-bit region size
bit 12,31 = base address. both regions have base address of zero
*/
"mov r0, #0x3F @ region data\n"
"mcr p15, 0, r0, c6, c0, 0 @ data region 0\n"
"mcr p15, 0, r0, c6, c0, 1 @ code region 0\n"
/*
set up region 1 (first 16M)
*/
"mov r0, #0x2F @ region data\n"
"mcr p15, 0, r0, c6, c1, 0 @ data region 1\n"
"mcr p15, 0, r0, c6, c1, 1 @ code region 1\n"
/* set region 1 to be cachable */
"mov r0, #2 @ 2 means region 1. 1 == 0, 4 == 2, etc\n"
"mcr p15, 0, r0, c2, c0, 0 @ turn on data cache\n"
"mcr p15, 0, r0, c2, c0, 1 @ turn on instruction cache\n"
/* enable data buffering in region 1 */
"mcr p15, 0, r0, c3, c0, 0 @ turn on write buffer\n"
/* enable protection for all memory regions */
"mov r0, #15\n"
"mcr p15, 0, r0, c5, c0, 0 @ set full data permission\n"
"mcr p15, 0, r0, c5, c0, 1 @ set full code permission\n"
"mcr p15, 0, r0, c1, c0, 0 @ fetch current control register\n"
"orr r0, r0, #1 @ enable protection unit\n"
"orr r0, r0, #9 @ enable D cache\n"
"orr r0, r0, #0x1000 @ enable I cache\n"
"orr r0, r0, #0xC0000000 @ async + fastbus\n"
"mcr p15, 0, r0, c1, c0, 0 @ set control register\n"
);
//call the "users" entry point:
main940();
}
thats it for 940 code.
920:
940.cpp in full, pretty much dzz's demo stuff but 940 memory shifted to 48mb offset to be sdl freindly:
Code:
#include "stdio.h"
#include "stdlib.h"
#include "fcntl.h"
#include "unistd.h"
#include "string.h"
#include "sys/mman.h"
#include "shared940.h"
// Hexidecimal reprisentations of the number of bytes in a set amount of megs for memory mapping
// for example, when I map 16megs of memory starting at the 48mb offset in the ram i would map HEX16 at HEX48
#define HEX48 0x3000000
#define HEX16 0x1000000
#define HEX15 0xF00000
#define HEX2 0x200000
#define HEX1 0x100000
volatile tSharedVariables *gGlobStruct;
volatile unsigned long *gMmsp2Regs32;
volatile unsigned short *gMmsp2Regs16;
unsigned char *gMemoryPointer;
int nDevMem;
int Init940() {
nDevMem = open("/dev/mem", O_RDWR);
gMmsp2Regs32 = (unsigned long *) mmap(0, 0x10000, 3, 1, nDevMem, 0xC0000000); //the processor registers, 32 bit
gMmsp2Regs16 = (unsigned short *) gMmsp2Regs32; //16bit version
gMemoryPointer = (unsigned char *)mmap(0, HEX16, 3, 1, nDevMem, HEX48); //16mb of memory offset by 48mb
gGlobStruct = (tSharedVariables *) (gMemoryPointer + HEX15); //last meg used for shared variable stack
gGlobStruct->bQuitProgram = false;
gGlobStruct->usStatus = 0;
gMmsp2Regs16[0x3B48 >> 1] = (1 << 7) | 3; //reset the 940t and inform it that its been shifted to the 48mb offset
gMmsp2Regs16[0x0904 >> 1] &= (~(1 << 0)); //pause the 940t
//need to copy the pre-compiled code that the 940 has to run into its memory space.
//for triple triad I have stored that code in 940audio.bin (ogg engine)
int f = open("940audio.bin", O_RDONLY); //open the precompiled code
if (f < 0) {
return -1; //error :(
}
int nOffset = 0;
int nRead = 0;
unsigned char buff[1024];
while((nRead = read(f, buff, 1024)) > 0) { //while there is code left to read, read it..
memcpy(gMemoryPointer + nOffset, buff, nRead); //copy it in to the mapped memory for the 940t..
nOffset += nRead; //up the locations for the next copy
}
close(f); //close the file
//there are two interrupts that connect the two processors, but I dont use them so I need to disable them
gMmsp2Regs16[0x3B40 >> 1] = 0; //interrupt 1
gMmsp2Regs16[0x3B42 >> 1] = 0; //interrupt 2
//now take the 940 out of reset state and get that thing executing
gMmsp2Regs16[0x3B48 >> 1] = 3; //take out of reset, preserve the memory shift setting from earlier (3)
gMmsp2Regs16[0x0904 >> 1] |= (1 << 0); //begin execution!
return 0;
}
unsigned short Get940Status() {
return gGlobStruct->usStatus;
}
void Shutdown940() {
gMmsp2Regs16[0x3B48 >> 1] = (1 << 7) | 3; //reset the 940 cpu
gMmsp2Regs16[0x0904 >> 1] &= (~(1 << 0)); //pause it
munmap(gMemoryPointer, 0xF00000);
munmap((void *)gMmsp2Regs32, 0x10000);
close(nDevMem);
}
//still untested loadwav to buffer wav data to the 940 (512byte buffer)
void LoadWav(const char *szFilename, int nChannel, int nLoop) {
FILE *nFile = fopen(szFilename, "r+");
fseek(nFile, 0, SEEK_END);
gGlobStruct->nTotalSize = ftell(nFile);
fseek(nFile, 0, SEEK_SET);
if (gGlobStruct->nTotalSize >= 512) {
int nCopied = 0;
int nThisCopy = 0;
unsigned char tmpBuffer[512];
while (nCopied != gGlobStruct->nTotalSize) {
if (gGlobStruct->nTotalSize - nCopied < 512) {
nThisCopy = gGlobStruct->nTotalSize - nCopied;
} else {
nThisCopy = 512;
}
fread(tmpBuffer, 1, nThisCopy, nFile);
for (int p = 0; p < nThisCopy; p++) {
gGlobStruct->cWavBuffer[p] = tmpBuffer[p];
}
gGlobStruct->nThisSampleStart = nCopied;
gGlobStruct->nThisSampleLength = nThisCopy;
gGlobStruct->bFinishedRead = false;
gGlobStruct->nLoadWavStatus == WAV_LOAD;
nCopied += nThisCopy;
while(!gGlobStruct->bFinishedRead) {
};
}
} else {
int nThisCopy = gGlobStruct->nTotalSize;
unsigned char tmpBuffer[512];
fread(tmpBuffer, 1, nThisCopy, nFile);
for (int p = 0; p < nThisCopy; p++) {
gGlobStruct->cWavBuffer[p] = tmpBuffer[p];
}
gGlobStruct->nThisSampleStart = 0;
gGlobStruct->nThisSampleLength = nThisCopy;
gGlobStruct->bFinishedRead = false;
gGlobStruct->nLoadWavStatus == WAV_LOAD;
while (!gGlobStruct->bFinishedRead) {
}
}
gGlobStruct->nLoadWavStatus == 0;
fclose(nFile);
}
im completly stumped. i commented pretty much everything out of the mixer except the main mixer because I cant afford to remove that, the whole point of this exercise is to get the heavy audio work going on the 940! if i take the mixer off I may as well do the lot on the 920. but simply if heavenlymixer.c is compiled into the bin, usStatus == 0. if excluded, == 6 as it should be
im so lost as to what to do >< sorry for long post, but if anyone can help, thanks!
EDIT:
bah this was supposed to be the I Need Help dev forum --; sorry :/