The example compiles fine and runs the code without errors. It just won't color cycle the FrameBuffer or give any indication that the code is actually running on the ME.
My PSP is capable of using the ME because the ME sample provided with the PSPSDK works fine. I don't want to build off of that though because most of this stuff is over my head and I'd rather code in C than assembly.
Here's the example project I'm working with. I got the code and built the prx from the SNES emu source (I've tried with daedulusX64 too). main.c is from J.F.s post on the ps2dev froums:
main.c
[spoiler]
Code: Select all
#include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspiofilemgr.h>
#include <pspdebug.h>
#include <psppower.h>
#include <pspdisplay.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "me.h"
#define printf pspDebugScreenPrintf
#define VERS 1
#define REVS 1
PSP_MODULE_INFO("DisplayTest", 0, VERS, REVS);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
PSP_HEAP_SIZE_KB(-256);
__attribute__((aligned(64))) unsigned int frame[512*272];
unsigned int *frameBuf;
volatile struct me_struct *mei;
__attribute__((aligned(64))) struct me_struct meinst;
/*
* ME functions
*
*/
int ColorCycle(volatile struct me_struct *mei)
{
int x, y;
int c = 0;
unsigned int *buffer;
buffer = (unsigned int *)((int)frameBuf | 0x40000000);
while (!(mei->signals & 0x00000001))
{
if (mei->signals & 0x00000002)
for(y=0;y<272;y++)
for(x=0;x<480;x++)
buffer[y*512+x]=(x&255)+((y&255)<<8)+((c&255)<<16);
c++;
}
return 0;
}
/*
* SC functions
*
*/
void *malloc_64(int size)
{
int mod_64 = size & 0x3f;
if (mod_64 != 0) size += 64 - mod_64;
return((void *)memalign(64, size));
}
int main(void)
{
//unsigned int b;
int mode, width, height, bufferwidth, pixelformat, x, y;
void *topaddr;
int hasME = 1;
int err;
pspDebugScreenInit();
pspDebugScreenSetBackColor(0x00000000);
pspDebugScreenSetTextColor(0x00ffffff);
pspDebugScreenClear();
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL);
SceUID mod = pspSdkLoadStartModule("mediaengine.prx", PSP_MEMORY_PARTITION_KERNEL);
if (mod < 0)
{
printf(" Error 0x%08X loading/starting mediaengine.prx.\n", mod);
hasME = 0;
}
printf("\n Display Test\n\n");
// mei = malloc_64(sizeof(struct me_struct));
// mei = (volatile struct me_struct *)(((int) mei) | 0x40000000);
mei = (volatile struct me_struct *)((u32)&meinst | 0x40000000);
sceKernelDcacheWritebackInvalidateAll();
if(hasME)
if (InitME(mei, sceKernelDevkitVersion()) != 0)
{
printf(" Couldn't initialize MediaEngine Instance\n");
hasME = 0;
}
printf(" Media Engine Instance initialized\n");
sceKernelDelayThread(2*1000*1000);
// FILE *fh = fopen("dump.bin", "w");
// fwrite(0x49000000, 1, 0x10000, fh);
// fclose(fh);
KillME(mei, sceKernelDevkitVersion());
printf(" Media Engine Instance destroyed\n");
sceKernelDelayThread(2*1000*1000);
InitME(mei, sceKernelDevkitVersion());
printf(" Media Engine Instance initialized\n");
sceKernelDelayThread(2*1000*1000);
sceDisplayGetMode(&mode, &width, &height);
sceDisplayGetFrameBuf(&topaddr, &bufferwidth, &pixelformat, 0);
printf(" mode = %d, width = %d, height = %d\n", mode, width, height);
printf(" fbuf = 0x%08X, bufferwidth = %d, pixelformat = %d\n", (int)topaddr, bufferwidth, pixelformat);
sceKernelDelayThread(5*1000*1000);
// frameBuf = (unsigned int *)0x09000000; // phat
// frameBuf = (unsigned int *)0x0b000000; // slim
frameBuf = (unsigned int *)((u32)&frame | 0x40000000);
for(y=0;y<272;y++)
{
for(x=0;x<480;x++)
{
frameBuf[y*512+x]=(x&255)+((y&255)*256);
}
}
sceKernelDcacheWritebackAll();
sceDisplaySetMode(0,480,272);
sceDisplaySetFrameBuf(frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_NEXTFRAME);
sceKernelDelayThread(2*1000*1000);
pspDebugScreenSetBase((u32 *)(0x40000000 | (int)frameBuf));
pspDebugScreenSetXY(0, 0);
printf(" Display Test");
sceKernelDelayThread(2*1000*1000);
if (hasME)
{
err = BeginME(mei, (int)ColorCycle, (int)mei, 0, 0, 0, 0);
if (err < 0)
printf(" failed! Error calling BeginME.\n");
}
if (hasME)
SignalME(mei, 0x00000002, 0x00000002); // start 480x272 ColorCycle
sceKernelDelayThread(3*1000*1000);
if (hasME)
SignalME(mei, 0x00000002, 0x00000000); // stop ColorCycle
sceKernelDelayThread(3*1000*1000);
if (hasME)
SignalME(mei, 0x00000002, 0x00000002); // start 480x272 ColorCycle
sceKernelDelayThread(3*1000*1000);
if (hasME)
SignalME(mei, 0x00000002, 0x00000000); // stop ColorCycle
if (hasME)
{
SignalME(mei, 0x00000001, 0x00000001); // exit ColorCycle
err = WaitME(mei);
}
sceKernelDelayThread(3*1000*1000);
sceKernelExitGame();
return 0; /* never reaches here - just to suppress warning */
} me.c
[spoiler]
Code: Select all
#include "me.h"
int CallME(volatile struct me_struct *mei, int func, int param, int prelen, void *preadr, int postlen, void *postadr)
{
if (!mei->done)
return -1;
mei->done = 0;
mei->func = func;
mei->param = param;
mei->result = 0;
mei->precache_len = prelen;
mei->precache_addr = preadr;
mei->postcache_len = postlen;
mei->postcache_addr = postadr;
mei->signals = 0;
mei->start = 1;
while (!mei->done);
return mei->result;
}
int WaitME(volatile struct me_struct *mei)
{
while (!mei->done);
return mei->result;
}
int BeginME(volatile struct me_struct *mei, int func, int param, int prelen, void *preadr, int postlen, void *postadr)
{
if (!mei->done)
return -1;
mei->done = 0;
mei->func = func;
mei->param = param;
mei->result = 0;
mei->precache_len = prelen;
mei->precache_addr = preadr;
mei->postcache_len = postlen;
mei->postcache_addr = postadr;
mei->signals = 0;
mei->start = 1;
return 0;
}
int CheckME(volatile struct me_struct *mei)
{
return mei->done;
}
unsigned int SignalME(volatile struct me_struct *mei, unsigned int sigmask, unsigned int sigset)
{
unsigned int signals;
signals = mei->signals;
mei->signals = (mei->signals & ~sigmask) | (sigset & sigmask);
return signals;
}
me.h
[spoiler]
Code: Select all
#ifndef me_h
#define me_h
#include <pspsdk.h>
#include <pspkernel.h>
#ifdef __cplusplus
extern "C" {
#endif
struct me_struct
{
int start;
int done;
int (*func)(int); // function ptr - func takes an int argument and returns int
int param; // function argument
int result; // function return value
int precache_len; // amount of space to invalidate before running func, -1 = all
void *precache_addr; // address of space to invalidate before running func
int postcache_len; // amount of space to flush after running func, -1 = all
void *postcache_addr; // address of space to flush after running func
unsigned int signals;
int init;
};
int InitME(volatile struct me_struct *mei, int devkitVersion);
void KillME(volatile struct me_struct *mei, int devkitVersion);
int CallME(volatile struct me_struct *mei, int func, int param, int prelen, void *preadr, int postlen, void *postadr);
int WaitME(volatile struct me_struct *mei);
int BeginME(volatile struct me_struct *mei, int func, int param, int prelen, void *preadr, int postlen, void *postadr);
int CheckME(volatile struct me_struct *mei);
unsigned int SignalME(volatile struct me_struct *mei, unsigned int sigmask, unsigned int sigset);
#ifdef __cplusplus
}
#endif
#endif
Makefile
[spoiler]
Code: Select all
TARGET = metest
OBJS = main.o me.o MediaEngine.o
INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS =
BUILD_PRX = 1
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = ME Test
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
mediaengine.prx and MediaEngine.S are included in the attachment.
=====
I feel silly (but also excited). It turns out the Makefile I posted here wasn't actually what I was using.
I thought it would be ok to use one from another project, but for some reason that wasn't working despite using the same code. EDIT: Compiling without "-G0" breaks it.
Anyway, it's good to have this project uploaded here since I don't think you can find this stuff all in one place.
Advertising