This commit is contained in:
Wolfgang Thaller 2012-03-29 10:29:41 +02:00
parent 272a5da348
commit c0964680a4
5 changed files with 264 additions and 0 deletions

19
libretro/Makefile Normal file
View File

@ -0,0 +1,19 @@
PREFIX=/media/LinuxHD/wolfgang/Projects/Retro68-build/toolchain
CC=${PREFIX}/bin/m68k-unknown-elf-gcc
LD=${PREFIX}/bin/m68k-unknown-elf-ld
AR=${PREFIX}/bin/m68k-unknown-elf-ar
CFLAGS=-O
OBJS=glue.o malloc.o syscalls.o start.o
all: retrocrt.o libretro.a
libretro.a: ${OBJS}
${AR} cqs $@ ${OBJS}
retrocrt.o: ${OBJS}
${LD} -r -o $@ ${OBJS}
.PHONY: install
install: retrocrt.o
cp $< ${PREFIX}/m68k-unknown-elf/lib/

15
libretro/glue.c Normal file
View File

@ -0,0 +1,15 @@
#include <MacMemory.h>
Size GetPtrSize(Ptr ptr)
{
long tmp;
__asm__ __volatile__(
"move.l %1, %%a0\n\t"
"dc.w 0xA021\n\t"
"move.l %%d0, %1"
: "=g"(tmp) : "g"(ptr) : "%%a0", "%%d0");
if(tmp > 0)
return (Size) tmp;
else
return 0;
}

75
libretro/malloc.c Normal file
View File

@ -0,0 +1,75 @@
#include <stdlib.h>
#include <errno.h>
#include <reent.h>
#include <string.h>
#include <MacMemory.h>
void referenceMyMalloc() {}
void *_malloc_r(struct _reent *reent_ptr, size_t sz)
{
return NewPtr(sz); // TODO: set errno
}
void *_calloc_r(struct _reent *reent_ptr, size_t sz, size_t sz2)
{
return NewPtrClear(sz*sz2); // TODO: set errno
}
void _free_r(struct _reent *reent_ptr, void *ptr)
{
if(ptr != NULL)
DisposePtr(ptr);
}
void *_realloc_r(struct _reent *reent_ptr, void *ptr, size_t sz)
{
if(ptr == NULL)
{
return NewPtr(sz);
}
else
{
MemError();
SetPtrSize(ptr, sz);
if(MemError())
{
size_t oldSz = GetPtrSize(ptr);
if(sz > oldSz)
{
void *newPtr = NewPtr(sz);
if(!newPtr)
{
errno = ENOMEM;
return NULL;
}
memcpy(newPtr, ptr, oldSz);
return newPtr;
}
else
{
errno = ENOMEM;
return NULL;
}
}
}
}
void *malloc(size_t sz)
{
return _malloc_r(_REENT, sz);
}
void free(void *p)
{
_free_r(_REENT, p);
}
void *realloc(void *ptr, size_t sz)
{
return _realloc_r(_REENT, ptr, sz);
}
void *calloc(size_t sz1, size_t sz2)
{
return _calloc_r(_REENT, sz1, sz2);
}

86
libretro/start.c Normal file
View File

@ -0,0 +1,86 @@
#include <Processes.h>
#include <Sound.h>
#include <Memory.h>
int main(int argc, char* argv[]);
struct flat_hdr {
char magic[4];
unsigned long rev; /* version */
unsigned long entry; /* Offset of first executable instruction
with text segment from beginning of file */
unsigned long data_start; /* Offset of data segment from beginning of
file */
unsigned long data_end; /* Offset of end of data segment
from beginning of file */
unsigned long bss_end; /* Offset of end of bss segment from beginning
of file */
/* (It is assumed that data_end through bss_end forms the bss segment.) */
unsigned long stack_size; /* Size of stack, in bytes */
unsigned long reloc_start; /* Offset of relocation records from
beginning of file */
unsigned long reloc_count; /* Number of relocation records */
unsigned long flags;
unsigned long filler[6]; /* Reserved, set to zero */
};
typedef void (*voidFunction)(void);
//extern voidFunction __init_array_start[];
//extern voidFunction __init_array_end[];
extern void __init_section(void);
extern void __init_section_end(void);
extern void __fini_section(void);
extern void __fini_section_end(void);
void _start()
{
char *argv[2] = { "./a.out", NULL };
long virtualstart, realstart;
__asm__( "move.l #_start, %0" : "=r"(virtualstart) );
__asm__( "lea (_start:w,%%pc), %0" : "=a"(realstart) );
long displacement = realstart - virtualstart;
struct flat_hdr *header = (struct flat_hdr*) (displacement - 0x40);
Ptr bss = NewPtrClear(header->bss_end - header->data_end);
long n = header->reloc_count;
long *relocs = (long*)( (char*)header + header->reloc_start );
long i;
long data_end = header->data_end - 0x40;
long bss_displacement = (long)bss - data_end;
for(i = 0; i < n; i++)
{
long *addr = (long*)(relocs[i] + displacement);
*addr += (*addr >= data_end ? bss_displacement : displacement);
}
/* {
voidFunction *p;
for(p = __init_array_start; p < __init_array_end; ++p)
(**p)();
}*/
//__init_section();
{
char *p = (char*)&__init_section;
char *e = (char*)&__init_section_end;
p += 2;
while( p < e )
{
(*(voidFunction)(*(long*)p))();
p += 6;
}
}
main(displacement, argv);
ExitToShell();
}

69
libretro/syscalls.c Normal file
View File

@ -0,0 +1,69 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <MacMemory.h>
#include <Processes.h>
int isatty(int fd) { return fd >= 0 && fd <= 2; }
void *sbrk(long increment)
{
Debugger();
return NewPtrClear(increment);
}
void _exit(int status)
{
if(status != 0)
Debugger();
ExitToShell();
for(;;)
;
}
ssize_t (*__write_hook)(int fd, const void*buf, size_t count) = NULL;
ssize_t write(int fd, const void *buf, size_t count)
{
if(__write_hook)
return (*__write_hook)(fd,buf,count);
return -1;
}
ssize_t read(int fd, void *buf, size_t count)
{
return -1;
}
int open(const char* name, int flags, mode_t mode)
{
__asm__ __volatile__ ("dc.w 0xa9ff");
return -1;
}
int close(int fd)
{
return -1;
}
int fstat(int fd, struct stat *buf)
{
return -1;
}
off_t lseek(int fd, off_t offset, int whence)
{
return (off_t) -1;
}
int kill(pid_t pid, int sig)
{
if(pid == 42)
_exit(42);
else
return -1;
}
pid_t getpid(void)
{
return 42;
}