Compare commits
29 Commits
6989798d87
...
ecfc7a127b
|
@ -1,6 +1,10 @@
|
|||
# Prefix of the toolchain
|
||||
|
||||
ifeq "$(PSXSDK_PATH)" ""
|
||||
TOOLCHAIN_PREFIX = /usr/local/psxsdk
|
||||
else
|
||||
TOOLCHAIN_PREFIX = $(PSXSDK_PATH)
|
||||
endif
|
||||
|
||||
# Make command
|
||||
# Tip: Set to gmake on *BSD
|
||||
|
|
|
@ -42,6 +42,12 @@ static inline fix16_t fix16_from_int(int a) { return a * fix16_one; }
|
|||
static inline float fix16_to_float(fix16_t a) { return (float)a / fix16_one; }
|
||||
static inline double fix16_to_dbl(fix16_t a) { return (double)a / fix16_one; }
|
||||
|
||||
/* Static inline functions cannot be used to determine compile-time values,
|
||||
* so use this expression instead if needed. */
|
||||
#define FIX16_C_FROM_INT(a) ((a) * fix16_one)
|
||||
#define FIX16_C_FROM_FLOAT(a) (((float)(a) * fix16_one) >= 0 ? \
|
||||
(((float)(a) * fix16_one)) + 0.5f : ((float)(a) * fix16_one) - 0.5f)
|
||||
|
||||
static inline int fix16_to_int(fix16_t a)
|
||||
{
|
||||
#ifdef FIXMATH_NO_ROUNDING
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
* BSD license
|
||||
*/
|
||||
|
||||
#ifndef __IN_LIBPSX
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
|
|
|
@ -57,21 +57,23 @@ extern "C"
|
|||
* - PSXSDK 2018-01-10
|
||||
* + 0.6.2 (0x0602)
|
||||
* - PSXSDK 2019-04-10
|
||||
* + 0.7.0 (0x070000)
|
||||
* - PSXSDK 2021-10-24
|
||||
*/
|
||||
|
||||
#define PSXSDK_VERSION 0x0602
|
||||
#define PSXSDK_VERSION 0x070100
|
||||
|
||||
/**
|
||||
* PSXSDK version information in string format
|
||||
*/
|
||||
|
||||
#define PSXSDK_VERSION_STRING "0.6.2"
|
||||
#define PSXSDK_VERSION_STRING "0.7.1"
|
||||
|
||||
/**
|
||||
* PSXSDK version date (BCD YYYY-MM-DD)
|
||||
*/
|
||||
|
||||
#define PSXSDK_VERSION_DATE 0x20190410
|
||||
#define PSXSDK_VERSION_DATE 0x20211208
|
||||
|
||||
|
||||
/*
|
||||
|
@ -123,18 +125,14 @@ enum cop0_register_numbers
|
|||
/**
|
||||
* Root counter specifications
|
||||
*/
|
||||
|
||||
enum psx_rcnt_specs
|
||||
{
|
||||
/** Pixel clock*/
|
||||
RCntCNT0 = 0xf2000000,
|
||||
/** Horizontal sync*/
|
||||
RCntCNT1 = 0xf2000001,
|
||||
/** System clock / 8 */
|
||||
RCntCNT2 = 0xf2000002,
|
||||
/** VSync (VBlank) */
|
||||
RCntCNT3 = 0xf2000003,
|
||||
};
|
||||
/** Pixel clock*/
|
||||
#define RCntCNT0 0xf2000000
|
||||
/** Horizontal sync*/
|
||||
#define RCntCNT1 0xf2000001
|
||||
/** System clock / 8 */
|
||||
#define RCntCNT2 0xf2000002
|
||||
/** VSync (VBlank) */
|
||||
#define RCntCNT3 0xf2000003
|
||||
|
||||
/**
|
||||
* Root counter modes
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -31,11 +32,6 @@ extern "C"
|
|||
|
||||
#define EOF -1
|
||||
|
||||
/* NULL */
|
||||
#ifndef NULL
|
||||
#define NULL (void*)0
|
||||
#endif
|
||||
|
||||
enum stdio_directions
|
||||
{
|
||||
STDIO_DIRECTION_BIOS,
|
||||
|
@ -74,8 +70,16 @@ typedef struct
|
|||
unsigned int eof;
|
||||
/** Error marker */
|
||||
unsigned int error;
|
||||
/** Sector buffer. */
|
||||
unsigned char *const buf;
|
||||
/** Last used sector for reading. */
|
||||
size_t last_sect;
|
||||
/** Sector buffer can be used for reading. */
|
||||
unsigned int cache_available;
|
||||
}FILE;
|
||||
|
||||
extern FILE *const stdin, *const stdout, *const stderr;
|
||||
|
||||
/* Console functions */
|
||||
|
||||
int putchar(int c);
|
||||
|
@ -87,7 +91,7 @@ int puts(const char *str);
|
|||
*/
|
||||
|
||||
extern int printf(const char *format, ...);
|
||||
|
||||
int fprintf(FILE *fd, const char *format, ...);
|
||||
|
||||
#ifdef __IN_LIBPSX
|
||||
|
||||
|
@ -108,13 +112,13 @@ int vsnprintf(char *string, size_t size, const char *fmt, va_list ap);
|
|||
int vsprintf(char *string, const char *fmt, va_list ap);
|
||||
int sprintf(char *string, const char *fmt, ...);
|
||||
int snprintf(char *string, size_t size, const char *fmt, ...);
|
||||
int vprintf(char *fmt, va_list ap);
|
||||
int vprintf(const char *fmt, va_list ap);
|
||||
|
||||
FILE *fdopen(int fildes, const char *mode);
|
||||
FILE *fopen(const char *path, const char *mode);
|
||||
int fclose(FILE *stream);
|
||||
int fread(void *ptr, int size, int nmemb, FILE *f);
|
||||
int fwrite(void *ptr, int size, int nmemb, FILE *f);
|
||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
|
||||
int fgetc(FILE *f);
|
||||
int ftell(FILE *f);
|
||||
|
@ -125,6 +129,7 @@ void clearerr(FILE *stream);
|
|||
int feof(FILE *stream);
|
||||
int ferror(FILE *stream);
|
||||
int fileno(FILE *stream);
|
||||
void perror(const char *s);
|
||||
|
||||
#define getc(f) fgetc(f)
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ extern "C"
|
|||
#endif
|
||||
|
||||
typedef unsigned int size_t;
|
||||
typedef signed int ssize_t;
|
||||
|
||||
/* Conversion functions */
|
||||
|
||||
|
@ -52,6 +51,8 @@ void *realloc(void *buf , size_t n);
|
|||
|
||||
int abs(int x);
|
||||
long long strtoll(const char *nptr, char **endptr, int base);
|
||||
unsigned long long strtoull(const char *nptr, char **endptr, int base);
|
||||
unsigned long strtoul(const char *nptr, char **endptr, int base);
|
||||
long strtol(const char *nptr, char **endptr, int base);
|
||||
double strtod(const char *nptr, char **endptr);
|
||||
long double strtold(const char *nptr, char **endptr);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <psx.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
@ -18,14 +19,15 @@
|
|||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char onesec_buf[2048];
|
||||
int errno;
|
||||
int __stdio_direction = STDIO_DIRECTION_BIOS;
|
||||
static unsigned int __sio_cr_mapped = 0;
|
||||
|
||||
#define NUM_OF_FILE_STRUCTS 259
|
||||
#define NUM_OF_FILE_STRUCTS 6
|
||||
|
||||
FILE file_structs[NUM_OF_FILE_STRUCTS] =
|
||||
enum {SECTOR_SZ = 2048};
|
||||
|
||||
static FILE file_structs[NUM_OF_FILE_STRUCTS] =
|
||||
{
|
||||
[0] = // stdin
|
||||
{
|
||||
|
@ -60,11 +62,16 @@ FILE file_structs[NUM_OF_FILE_STRUCTS] =
|
|||
.eof = 0,
|
||||
.error = 0
|
||||
},
|
||||
|
||||
[3 ... NUM_OF_FILE_STRUCTS - 1] =
|
||||
{
|
||||
.buf = (unsigned char[SECTOR_SZ]){}
|
||||
}
|
||||
};
|
||||
|
||||
FILE *stdin = &file_structs[0];
|
||||
FILE *stdout = &file_structs[1];
|
||||
FILE *stderr = &file_structs[2];
|
||||
FILE *const stdin = &file_structs[0];
|
||||
FILE *const stdout = &file_structs[1];
|
||||
FILE *const stderr = &file_structs[2];
|
||||
|
||||
#define IS_CONS_IN(f) (f->fildes == 0)
|
||||
#define IS_CONS_OUT(f) (f->fildes == 1 || f->fildes == 2)
|
||||
|
@ -95,22 +102,18 @@ unsigned int fmode_to_desmode(const char *fmode)
|
|||
|
||||
if(strcmp(rmode, "r") == 0)
|
||||
{
|
||||
dprintf("Open for reading.\n");
|
||||
return O_RDONLY;
|
||||
}
|
||||
else if(strcmp(rmode, "r+") == 0)
|
||||
{
|
||||
dprintf("Open for reading and writing.\n");
|
||||
return O_RDWR;
|
||||
}
|
||||
else if(strcmp(rmode, "w") == 0)
|
||||
{
|
||||
dprintf("Open for writing.\n");
|
||||
return O_WRONLY | O_CREAT | O_TRUNC;
|
||||
}
|
||||
else if(strcmp(rmode, "w+") == 0)
|
||||
{
|
||||
dprintf("Open for writing. Truncate to zero or create file.\n");
|
||||
return O_RDWR | O_CREAT | O_TRUNC;
|
||||
}
|
||||
else if(strcmp(rmode, "a") == 0)
|
||||
|
@ -137,10 +140,20 @@ FILE *fdopen(int fildes, const char *mode)
|
|||
// Find a free file structure
|
||||
for(x = 0; x < NUM_OF_FILE_STRUCTS; x++)
|
||||
{
|
||||
if(file_structs[x].used == 0)
|
||||
FILE *const f = &file_structs[x];
|
||||
|
||||
if(f->used == 0)
|
||||
{
|
||||
bzero(&file_structs[x], sizeof(FILE));
|
||||
file_structs[x].used = 1;
|
||||
f->size = 0;
|
||||
f->eof = 0;
|
||||
f->error = 0;
|
||||
f->used = 1;
|
||||
f->last_sect = 0;
|
||||
f->cache_available = 0;
|
||||
|
||||
if (f->buf)
|
||||
memset(f->buf, 0, SECTOR_SZ);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -164,18 +177,23 @@ static FILE *fopen_internal(const char *path, const char *mode, FILE *f)
|
|||
|
||||
if(strncmp(path, "cdromL:", 7) == 0)
|
||||
{
|
||||
#ifdef PSXSDK_CDROML_ENABLED
|
||||
s = malloc(1024);
|
||||
|
||||
if(libc_get_transtbl_fname(path+7, s, 1024) == 0)
|
||||
return NULL;
|
||||
|
||||
fd = open(s, fmode_to_desmode(mode));
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
fd = open(path, fmode_to_desmode(mode));
|
||||
|
||||
if(fd == -1)
|
||||
{
|
||||
errno = ENOENT;
|
||||
if(s!=NULL)free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -228,6 +246,110 @@ int fclose(FILE *stream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static size_t cdromread(void *restrict ptr, size_t sz,
|
||||
FILE *restrict const f)
|
||||
{
|
||||
const size_t start_sect = f->pos >> __builtin_ctz(SECTOR_SZ);
|
||||
const size_t end_pos = f->pos + sz;
|
||||
const size_t end_sector = end_pos >> __builtin_ctz(SECTOR_SZ);
|
||||
size_t readb = 0;
|
||||
int read_complete_sector = 0;
|
||||
|
||||
if (feof(f) || ferror(f))
|
||||
return 0;
|
||||
else if (f->cache_available)
|
||||
{
|
||||
const size_t first_sector_sz = f->pos % SECTOR_SZ;
|
||||
|
||||
if (f->last_sect == start_sect && f->last_sect == end_sector)
|
||||
{
|
||||
/* Use buffered I/O. */
|
||||
size_t max;
|
||||
|
||||
if (end_pos >= f->size)
|
||||
{
|
||||
max = f->size - f->pos;
|
||||
f->eof = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = sz;
|
||||
}
|
||||
|
||||
memcpy(ptr, &f->buf[first_sector_sz], max);
|
||||
f->pos += max;
|
||||
readb = max;
|
||||
}
|
||||
else if (f->last_sect == start_sect)
|
||||
{
|
||||
/* Partial buffered I/O possible. */
|
||||
const size_t firstsz = SECTOR_SZ - first_sector_sz;
|
||||
|
||||
memcpy(ptr, &f->buf[first_sector_sz], firstsz);
|
||||
ptr = (char *)ptr + firstsz;
|
||||
f->pos += firstsz;
|
||||
f->cache_available = 0;
|
||||
readb += firstsz;
|
||||
read_complete_sector = 1;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t rem = sz - readb;
|
||||
|
||||
if (rem)
|
||||
{
|
||||
const size_t whole_sectors = rem / SECTOR_SZ;
|
||||
|
||||
if (whole_sectors)
|
||||
{
|
||||
if (!read_complete_sector)
|
||||
lseek(f->fildes, f->pos & ~(SECTOR_SZ - 1), SEEK_SET);
|
||||
|
||||
const size_t s = whole_sectors * SECTOR_SZ;
|
||||
const int n = read(f->fildes, &((unsigned char *)ptr)[readb], s);
|
||||
|
||||
if (n >= 0)
|
||||
{
|
||||
readb += s;
|
||||
f->pos += s;
|
||||
ptr = (unsigned char *)ptr + s;
|
||||
|
||||
if (f->pos >= f->size)
|
||||
f->eof = 1;
|
||||
|
||||
f->cache_available = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (f->pos < f->size)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (!read_complete_sector)
|
||||
lseek(f->fildes, f->pos & ~(SECTOR_SZ - 1), SEEK_SET);
|
||||
|
||||
n = read(f->fildes, f->buf, SECTOR_SZ);
|
||||
|
||||
if (n >= 0)
|
||||
{
|
||||
readb = n > rem ? rem : n;
|
||||
|
||||
memmove(ptr, f->buf, readb);
|
||||
ptr = (unsigned char *)ptr + readb;
|
||||
f->pos += readb;
|
||||
|
||||
if (f->pos >= f->size)
|
||||
f->eof = 1;
|
||||
|
||||
f->cache_available = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f->last_sect = end_sector;
|
||||
return f->pos;
|
||||
}
|
||||
|
||||
/*
|
||||
* fread doesn't require reads to be carried in block unit
|
||||
* Notice that however seeks on the CD drive will be very slow - so avoid using non block units
|
||||
|
@ -235,83 +357,29 @@ int fclose(FILE *stream)
|
|||
* This is done to make programming and porting easier
|
||||
*/
|
||||
|
||||
int fread(void *ptr, int size, int nmemb, FILE *f)
|
||||
size_t fread(void *restrict const ptr, const size_t size, const size_t nmemb,
|
||||
FILE *restrict const f)
|
||||
{
|
||||
int rsize = size * nmemb;
|
||||
int csize = rsize;
|
||||
int max;
|
||||
int nsect = (f->pos + rsize) >> 11;
|
||||
nsect -= f->pos >> 11;
|
||||
nsect++;
|
||||
|
||||
//printf("f->dev = %d, f->pos = %d, rsize = %d\n", f->dev, f->pos, rsize);
|
||||
|
||||
if(f->dev == FDEV_CDROM)
|
||||
if (size && nmemb)
|
||||
{
|
||||
// First sector
|
||||
lseek(f->fildes, f->pos & (~0x7ff), SEEK_SET);
|
||||
read(f->fildes, onesec_buf, 2048);
|
||||
size_t rsize = size * nmemb;
|
||||
|
||||
max = 2048 - (f->pos & 2047);
|
||||
|
||||
//printf("ptr(FIRST) = %d, %x\n", ptr, ptr);
|
||||
printf("rsize = %d\n", rsize);
|
||||
|
||||
memcpy(ptr, onesec_buf + (f->pos & 2047), (rsize > max) ? max : rsize);
|
||||
|
||||
// Middle sector
|
||||
ptr += max;
|
||||
|
||||
//printf("ptr(MIDDLEsex) = %d, %x\n", ptr, ptr);
|
||||
nsect--;
|
||||
csize -= max;
|
||||
|
||||
if(nsect > 1)
|
||||
switch (f->dev)
|
||||
{
|
||||
//lseek(f->fildes, (f->pos & (~0x7ff)) + 2048, SEEK_SET);
|
||||
case FDEV_CDROM:
|
||||
rsize = cdromread(ptr, rsize, f);
|
||||
break;
|
||||
|
||||
//#warning "Check correctness of this calculation."
|
||||
|
||||
/*if(rsize & 2047)
|
||||
sect_num = (rsize|2047)+1;
|
||||
else
|
||||
sect_num = rsize;
|
||||
|
||||
sect_num -= 4096;*/
|
||||
|
||||
//printf("read_middle=%d, sect_num = %d\n", read(f->fildes, ptr, sect_num), sect_num);
|
||||
|
||||
read(f->fildes, ptr, (nsect - 1) * 2048);
|
||||
|
||||
ptr += (nsect - 1) * 2048;
|
||||
csize -= (nsect - 1) * 2048;
|
||||
nsect = 1;
|
||||
case FDEV_CONSOLE:
|
||||
/* Fall through. */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
//printf("ptr(LAST) = %d, %x\n", ptr, ptr);
|
||||
|
||||
if(nsect == 1)
|
||||
{
|
||||
// Last sector
|
||||
read(f->fildes, onesec_buf, 2048);
|
||||
|
||||
memcpy(ptr, onesec_buf, csize);
|
||||
}
|
||||
}
|
||||
else if(f->dev == FDEV_CONSOLE)
|
||||
return 0;
|
||||
|
||||
|
||||
if(f->dev != FDEV_CONSOLE)
|
||||
{
|
||||
f->pos+= rsize;
|
||||
f->eof = (f->pos > f->size);
|
||||
|
||||
if(f->eof)
|
||||
f->pos = f->size;
|
||||
return rsize / size;
|
||||
}
|
||||
|
||||
return rsize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fgetc(FILE *f)
|
||||
|
@ -648,7 +716,8 @@ int puts(const char *str)
|
|||
return EOF;
|
||||
}
|
||||
|
||||
int fwrite(void *ptr, int size, int nmemb, FILE *f)
|
||||
size_t fwrite(void *restrict const ptr, const size_t size, const size_t nmemb,
|
||||
FILE *restrict const f)
|
||||
{
|
||||
if(IS_CONS_OUT(f)) // stdout or stderr
|
||||
{
|
||||
|
|
|
@ -114,3 +114,8 @@ int strerror_r(int errnum, char *strerrbuf, size_t buflen)
|
|||
snprintf(strerrbuf, buflen, "Unknown error %d", errnum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void perror(const char *s)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", s, strerror(errno));
|
||||
}
|
||||
|
|
|
@ -811,9 +811,9 @@ static int __vsnprintf_internal(char *string, size_t size, const char *fmt, va_l
|
|||
|
||||
static int vsnprintf_put_in_string(char *string, unsigned int sz, char c, int pos)
|
||||
{
|
||||
if(pos>=sz)
|
||||
if(pos >= sz && c)
|
||||
return 0;
|
||||
else
|
||||
else if (c || pos <= sz)
|
||||
string[pos] = c;
|
||||
|
||||
return 1;
|
||||
|
@ -843,7 +843,7 @@ static int out_put_in_string(char *string, unsigned int sz, char c, int pos)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int vprintf(char *fmt, va_list ap)
|
||||
int vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
return __vsnprintf_internal(NULL, -1, fmt, ap, out_put_in_string);
|
||||
}
|
||||
|
@ -853,6 +853,22 @@ int vsprintf(char *string, const char *fmt, va_list ap)
|
|||
return vsnprintf(string, 0xffffffff, fmt, ap);
|
||||
}
|
||||
|
||||
int fprintf(FILE *const fd, const char *fmt, ...)
|
||||
{
|
||||
if (fd == stdout || fd == stderr)
|
||||
{
|
||||
int r;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sprintf(char *string, const char *fmt, ...)
|
||||
{
|
||||
int r;
|
||||
|
|
|
@ -10,14 +10,40 @@
|
|||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
void *memcpy(void *const dst, const void *const src, size_t len)
|
||||
{
|
||||
void *dst2 = dst;
|
||||
|
||||
while(len--)
|
||||
*(((unsigned char*)dst++)) = *(((unsigned char*)src++));
|
||||
|
||||
return dst2;
|
||||
union
|
||||
{
|
||||
const void *v;
|
||||
const unsigned char *c;
|
||||
const unsigned int *w;
|
||||
} srcl;
|
||||
|
||||
union
|
||||
{
|
||||
void *v;
|
||||
unsigned char *c;
|
||||
unsigned int *w;
|
||||
} dstl;
|
||||
|
||||
srcl.v = src;
|
||||
dstl.v = dst;
|
||||
|
||||
/* Avoid unaligned access before doing word access. */
|
||||
while (len && (((ptrdiff_t)dstl.v & (sizeof (int) - 1))
|
||||
|| ((ptrdiff_t)srcl.v & (sizeof (int) - 1))))
|
||||
{
|
||||
*dstl.c++ = *srcl.c++;
|
||||
len--;
|
||||
}
|
||||
|
||||
for (; len >= sizeof (int); len -= sizeof (int))
|
||||
*dstl.w++ = *srcl.w++;
|
||||
|
||||
while (len--)
|
||||
*dstl.c++ = *srcl.c++;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memccpy(void *dst, const void *src, int c, size_t len)
|
||||
|
@ -37,11 +63,29 @@ void *memccpy(void *dst, const void *src, int c, size_t len)
|
|||
|
||||
void *memset(void *dst , int c , size_t len)
|
||||
{
|
||||
unsigned char *dstc = (unsigned char*)dst;
|
||||
int x;
|
||||
union
|
||||
{
|
||||
void *v;
|
||||
unsigned char *c;
|
||||
unsigned int *w;
|
||||
} dstl;
|
||||
|
||||
for(x = 0; x < len; x++)
|
||||
dstc[x] = c;
|
||||
const int cw = c | c << 8 | c << 16 | c << 24;
|
||||
|
||||
dstl.v = dst;
|
||||
|
||||
/* Avoid unaligned access before doing word access. */
|
||||
while (len && ((ptrdiff_t)dstl.v & (sizeof (int) - 1)))
|
||||
{
|
||||
*dstl.c++ = c;
|
||||
len--;
|
||||
}
|
||||
|
||||
for (; len >= sizeof (int); len -= sizeof (int))
|
||||
*dstl.w++ = cw;
|
||||
|
||||
while (len--)
|
||||
*dstl.c++ = c;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
@ -286,11 +330,72 @@ long long strtoll(const char *nptr, char **endptr, int base)
|
|||
return n?-r:r;
|
||||
}
|
||||
|
||||
unsigned long long strtoull(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
int r = 0;
|
||||
int t = 0;
|
||||
int n = 0;
|
||||
|
||||
while(*nptr && isspace(*nptr))
|
||||
nptr++;
|
||||
|
||||
if(base == 0)
|
||||
{
|
||||
if(*nptr == '0')
|
||||
base = 8;
|
||||
else
|
||||
base = 10;
|
||||
}
|
||||
|
||||
if(!(base >= 2 && base <= 36))
|
||||
return 0;
|
||||
|
||||
if(base == 16 && *nptr == '0')
|
||||
{
|
||||
if(*(nptr+1) == 'x' || *(nptr+1) == 'X')
|
||||
nptr+=2;
|
||||
}
|
||||
|
||||
while(*nptr)
|
||||
{
|
||||
switch(*nptr)
|
||||
{
|
||||
case '0'...'9':
|
||||
t = *nptr - '0';
|
||||
break;
|
||||
case 'a' ... 'z':
|
||||
t = (*nptr - 'a') + 10;
|
||||
break;
|
||||
case 'A' ... 'Z':
|
||||
t = (*nptr - 'A') + 10;
|
||||
break;
|
||||
default:
|
||||
t = 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
if(t>=base)
|
||||
break;
|
||||
|
||||
r*=base;
|
||||
r+=t;
|
||||
nptr++;
|
||||
}
|
||||
|
||||
if(endptr)*endptr = (char*)nptr;
|
||||
return n?-r:r;
|
||||
}
|
||||
|
||||
long strtol(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return (long)strtoll(nptr, endptr, base);
|
||||
}
|
||||
|
||||
unsigned long strtoul(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return strtoull(nptr, endptr, base);
|
||||
}
|
||||
|
||||
double strtod(const char *nptr, char **endptr)
|
||||
{
|
||||
char strbuf[64];
|
||||
|
|
|
@ -12,6 +12,7 @@ extern int __bss_start[];
|
|||
extern int __bss_end[];
|
||||
|
||||
static unsigned int first_free_page;
|
||||
static int init;
|
||||
|
||||
// 1K granularity and "pages", so more allocations which are small can be done
|
||||
|
||||
|
@ -22,7 +23,7 @@ static unsigned int alloc_size[2048];
|
|||
// 0x80000000 - 0x8000FFFF RAM used by the BIOS
|
||||
// 0x80010000 - 0x801FFFFF Program memory
|
||||
|
||||
void malloc_setup()
|
||||
static void malloc_setup()
|
||||
{
|
||||
int x;
|
||||
|
||||
|
@ -53,6 +54,14 @@ void malloc_setup()
|
|||
|
||||
void *malloc(size_t size)
|
||||
{
|
||||
if (!init)
|
||||
{
|
||||
// Setup memory allocation functions
|
||||
malloc_setup();
|
||||
dprintf("Finished setting up memory allocation functions.\n");
|
||||
init = 1;
|
||||
}
|
||||
|
||||
dprintf("malloc(%d)\n", size);
|
||||
|
||||
int x, y;
|
||||
|
@ -78,7 +87,7 @@ void *malloc(size_t size)
|
|||
// printf("Page found at %dKb\n", x);
|
||||
|
||||
for(y = 0; y < size; y++)
|
||||
if(busy_pages[x+y] == 1) goto malloc_keep_finding;
|
||||
if(busy_pages[x+y] == 1) continue;
|
||||
|
||||
// We found the memory we wanted, now make it busy
|
||||
|
||||
|
@ -94,8 +103,6 @@ void *malloc(size_t size)
|
|||
|
||||
return (void*)((unsigned int)0x80000000 + (x<<10));
|
||||
}
|
||||
malloc_keep_finding:
|
||||
; // Useless statement to make GCC not bail out...
|
||||
}
|
||||
|
||||
printf("failed malloc(%d)\n", size);
|
||||
|
@ -106,14 +113,9 @@ malloc_keep_finding:
|
|||
void *calloc(size_t number, size_t size)
|
||||
{
|
||||
void *ptr = malloc(number * size);
|
||||
unsigned char *cptr = (unsigned char*)ptr;
|
||||
int x;
|
||||
|
||||
if(ptr == NULL)
|
||||
ptr = NULL;
|
||||
|
||||
for(x = 0; x < (number * size); x++)
|
||||
cptr[x] = 0;
|
||||
if (ptr)
|
||||
memset(ptr, 0, number * size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef _PSXSDK_MEMORY_H
|
||||
#define _PSXSDK_MEMORY_H
|
||||
|
||||
void malloc_setup();
|
||||
|
||||
#endif
|
|
@ -62,7 +62,9 @@ void QueryPAD(int pad_n, const unsigned char *in, unsigned char *out, int len)
|
|||
/*Get the initial command (usually 0x01 or 0x81)*/
|
||||
TempData = *in;
|
||||
|
||||
#if 0
|
||||
for(y=0;y<400;y++); /*Slight delay before first transmission*/
|
||||
#endif
|
||||
|
||||
for(x = 0; x < len; x++)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <psx.h>
|
||||
#include <stdio.h>
|
||||
#include "memory.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int __bss_start[];
|
||||
extern int __bss_end[];
|
||||
|
@ -27,22 +28,16 @@ static void call_ctors(void)
|
|||
|
||||
void psxsdk_setup()
|
||||
{
|
||||
unsigned int x;
|
||||
|
||||
|
||||
printf("Initializing PSXSDK... \n");
|
||||
|
||||
dprintf("Clearing BSS space...\n");
|
||||
|
||||
// Clear BSS space
|
||||
for(x = (unsigned int)__bss_start; x < (unsigned int)__bss_end; x++)
|
||||
*((unsigned char*)x) = 0;
|
||||
|
||||
// Clear BSS space
|
||||
memset(__bss_start, 0, (ptrdiff_t)__bss_end - (ptrdiff_t)__bss_start);
|
||||
|
||||
dprintf("BSS space cleared.\n");
|
||||
|
||||
// Setup memory allocation functions
|
||||
malloc_setup();
|
||||
|
||||
dprintf("Finished setting up memory allocation functions.\n");
|
||||
|
||||
// Call static constructors
|
||||
call_ctors();
|
||||
|
|
|
@ -164,6 +164,8 @@ void SsUpload(const void *addr, int size, int spu_addr)
|
|||
|
||||
while(size > 0)
|
||||
{
|
||||
int n = size / sizeof *ptr > 32 ? 32 : size / sizeof *ptr;
|
||||
|
||||
SPU_STATUS = 4; // Sound RAM Data Transfer Control
|
||||
SPU_CONTROL = SPU_CONTROL & ~0x30; // SPUCNT.transfer_mode = 0 (STOP)
|
||||
|
||||
|
@ -173,7 +175,7 @@ void SsUpload(const void *addr, int size, int spu_addr)
|
|||
|
||||
SPU_ADDR = spu_addr >> 3;
|
||||
|
||||
for(i = 0; i < 32; i++)
|
||||
for(i = 0; i < n; i++)
|
||||
SPU_DATA = ptr[i];
|
||||
|
||||
SPU_CONTROL = (SPU_CONTROL & ~0x30) | 16; // SPUCNT.transfer_mode = 1 (MANUAL)
|
||||
|
@ -183,9 +185,9 @@ void SsUpload(const void *addr, int size, int spu_addr)
|
|||
|
||||
while(SPU_STATUS2 & 0x400); // wait for transfer busy bit to be cleared
|
||||
|
||||
spu_addr += 64;
|
||||
ptr += 32;
|
||||
size-=64;
|
||||
spu_addr += n * sizeof *ptr;
|
||||
ptr += n;
|
||||
size-=n * sizeof *ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue