initial commit
This commit is contained in:
@@ -0,0 +1,870 @@
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "math.h"
|
||||
#include "crt.h"
|
||||
|
||||
void itoa(int n, char * s, unsigned radix)
|
||||
{
|
||||
bool neg = n < 0;
|
||||
unsigned un = neg ? -n : n;
|
||||
|
||||
char i = 0;
|
||||
do {
|
||||
char d = un % radix;
|
||||
d += d < 10 ? '0' : 'A' - 10;;
|
||||
s[i++] = d;
|
||||
} while ((un /= radix) > 0);
|
||||
|
||||
if (neg)
|
||||
{
|
||||
s[i++] = '-';
|
||||
}
|
||||
s[i] = 0;
|
||||
char j = 0;
|
||||
while (j + 1 < i)
|
||||
{
|
||||
char c = s[j];
|
||||
s[j++] = s[--i];
|
||||
s[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void utoa(unsigned int n, char * s, unsigned radix)
|
||||
{
|
||||
char i = 0;
|
||||
do {
|
||||
char d = n % radix;
|
||||
d += d < 10 ? '0' : 'A' - 10;;
|
||||
s[i++] = d;
|
||||
} while ((n /= radix) > 0);
|
||||
|
||||
s[i] = 0;
|
||||
char j = 0;
|
||||
while ((char)(j + 1) < i)
|
||||
{
|
||||
char c = s[j];
|
||||
s[j++] = s[--i];
|
||||
s[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void ltoa(long n, char * s, unsigned radix)
|
||||
{
|
||||
bool neg = n < 0;
|
||||
if (neg)
|
||||
{
|
||||
n = - n;
|
||||
}
|
||||
|
||||
char i = 0;
|
||||
do {
|
||||
char d = n % radix;
|
||||
d += d < 10 ? '0' : 'A' - 10;;
|
||||
s[i++] = d;
|
||||
} while ((n /= radix) > 0);
|
||||
|
||||
if (neg)
|
||||
{
|
||||
s[i++] = '-';
|
||||
}
|
||||
s[i] = 0;
|
||||
char j = 0;
|
||||
while (j + 1 < i)
|
||||
{
|
||||
char c = s[j];
|
||||
s[j++] = s[--i];
|
||||
s[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void ultoa(unsigned long n, char * s, unsigned radix)
|
||||
{
|
||||
char i = 0;
|
||||
do {
|
||||
char d = n % radix;
|
||||
d += d < 10 ? '0' : 'A' - 10;;
|
||||
s[i++] = d;
|
||||
} while ((n /= radix) > 0);
|
||||
|
||||
s[i] = 0;
|
||||
char j = 0;
|
||||
while (j + 1 < i)
|
||||
{
|
||||
char c = s[j];
|
||||
s[j++] = s[--i];
|
||||
s[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ftoa(float f, char * s)
|
||||
{
|
||||
if (f < 0.0)
|
||||
{
|
||||
f = -f;
|
||||
*s++ = '-';
|
||||
}
|
||||
|
||||
int digits = 0;
|
||||
while (f >= 1000.0)
|
||||
{
|
||||
f /= 1000;
|
||||
digits += 3;
|
||||
}
|
||||
|
||||
if (f != 0.0)
|
||||
{
|
||||
while (f < 1.0)
|
||||
{
|
||||
f *= 1000;
|
||||
digits -= 3;
|
||||
}
|
||||
|
||||
while (f >= 10.0)
|
||||
{
|
||||
f /= 10;
|
||||
digits ++;
|
||||
}
|
||||
|
||||
f += 0.0000005;
|
||||
if (f >= 10.0)
|
||||
{
|
||||
f /= 10.0;
|
||||
digits ++;
|
||||
}
|
||||
}
|
||||
|
||||
int exp = 0;
|
||||
if (digits < 0)
|
||||
{
|
||||
exp = digits;
|
||||
digits = 0;
|
||||
}
|
||||
else if (digits > 6)
|
||||
{
|
||||
exp = digits;
|
||||
digits = 0;
|
||||
}
|
||||
|
||||
for(int i=0; i<7; i++)
|
||||
{
|
||||
int c = (int)f;
|
||||
f -= (float)c;
|
||||
f *= 10.0;
|
||||
*s++ = c + '0';
|
||||
if (i == digits)
|
||||
*s++ = '.';
|
||||
}
|
||||
if (exp)
|
||||
{
|
||||
*s++ = 'E';
|
||||
if (exp < 0)
|
||||
{
|
||||
*s++ = '-';
|
||||
exp = -exp;
|
||||
}
|
||||
else
|
||||
*s++ = '+';
|
||||
|
||||
if (exp >= 10)
|
||||
{
|
||||
*s++ = exp / 10 + '0';
|
||||
exp %= 10;
|
||||
}
|
||||
*s++ = exp + '0';
|
||||
}
|
||||
|
||||
*s++= 0;
|
||||
}
|
||||
|
||||
int atoi(const char * s)
|
||||
{
|
||||
char c;
|
||||
while ((c = *s++) <= ' ')
|
||||
if (!c) return 0;
|
||||
|
||||
bool neg = false;
|
||||
if (c == '-')
|
||||
{
|
||||
neg = true;
|
||||
c = *s++;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *s++;
|
||||
|
||||
int v = 0;
|
||||
while (c >= '0' && c <= '9')
|
||||
{
|
||||
v = v * 10 + (c - '0');
|
||||
c = *s++;
|
||||
}
|
||||
|
||||
if (neg)
|
||||
v = -v;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
long atol(const char * s)
|
||||
{
|
||||
char c;
|
||||
while ((c = *s++) <= ' ')
|
||||
if (!c) return 0;
|
||||
|
||||
bool neg = false;
|
||||
if (c == '-')
|
||||
{
|
||||
neg = true;
|
||||
c = *s++;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *s++;
|
||||
|
||||
long v = 0;
|
||||
while (c >= '0' && c <= '9')
|
||||
{
|
||||
v = v * 10 + (c - '0');
|
||||
c = *s++;
|
||||
}
|
||||
|
||||
if (neg)
|
||||
v = -v;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
const float tpow10[7] = {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0};
|
||||
|
||||
float atof(const char * s)
|
||||
{
|
||||
return strtof(s, nullptr);
|
||||
}
|
||||
|
||||
float strtof(const char *s, const char **endp)
|
||||
{
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
char c = *s;
|
||||
while (c <= ' ')
|
||||
{
|
||||
if (!c) return 0;
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
bool neg = false;
|
||||
if (c == '-')
|
||||
{
|
||||
neg = true;
|
||||
c = *++s;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *++s;
|
||||
|
||||
float v = 0;
|
||||
while (c >= '0' && c <= '9')
|
||||
{
|
||||
v = v * 10 + (c - '0');
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (c == '.')
|
||||
{
|
||||
float d = 1.0;
|
||||
c = *++s;
|
||||
while (c >= '0' && c <= '9')
|
||||
{
|
||||
v = v * 10 + (c - '0');
|
||||
d = d * 10;
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
v /= d;
|
||||
}
|
||||
|
||||
if (c == 'e' || c == 'E')
|
||||
{
|
||||
c = *++s;
|
||||
bool eneg = false;
|
||||
if (c == '-')
|
||||
{
|
||||
eneg = true;
|
||||
c = *++s;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *++s;
|
||||
|
||||
int e = 0;
|
||||
while (c >= '0' && c <= '9')
|
||||
{
|
||||
e = e * 10 + (c - '0');
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (eneg)
|
||||
{
|
||||
while (e > 6)
|
||||
{
|
||||
v /= 1000000.0;
|
||||
e -= 6;
|
||||
}
|
||||
v /= tpow10[e];
|
||||
}
|
||||
else
|
||||
{
|
||||
while (e > 6)
|
||||
{
|
||||
v *= 1000000.0;
|
||||
e -= 6;
|
||||
}
|
||||
v *= tpow10[e];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (neg)
|
||||
v = -v;
|
||||
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int strtoi(const char *s, const char **endp, char base)
|
||||
{
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
char c = *s;
|
||||
while (c <= ' ')
|
||||
{
|
||||
if (!c) return 0;
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
bool neg = false;
|
||||
if (c == '-')
|
||||
{
|
||||
neg = true;
|
||||
c = *++s;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *++s;
|
||||
|
||||
if (c == '0')
|
||||
{
|
||||
c = *++s;
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
base = 16;
|
||||
c = *++s;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = 8;
|
||||
} else if (base == 0)
|
||||
base = 10;
|
||||
|
||||
int v = 0;
|
||||
for(;;)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
v = v * base + (c - '0');
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
v = v * base + (c - 'a' + 10);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
v = v * base + (c - 'A' + 10);
|
||||
else
|
||||
break;
|
||||
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (neg)
|
||||
v = -v;
|
||||
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned strtou(const char *s, const char **endp, char base)
|
||||
{
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
char c = *s;
|
||||
while (c <= ' ')
|
||||
{
|
||||
if (!c) return 0;
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (c == '0')
|
||||
{
|
||||
c = *++s;
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
base = 16;
|
||||
c = *++s;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = 8;
|
||||
} else if (base == 0)
|
||||
base = 10;
|
||||
|
||||
unsigned v = 0;
|
||||
for(;;)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
v = v * base + (c - '0');
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
v = v * base + (c - 'a' + 10);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
v = v * base + (c - 'A' + 10);
|
||||
else
|
||||
break;
|
||||
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
long strtol(const char *s, const char **endp, char base)
|
||||
{
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
char c = *s;
|
||||
while (c <= ' ')
|
||||
{
|
||||
if (!c) return 0;
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
bool neg = false;
|
||||
if (c == '-')
|
||||
{
|
||||
neg = true;
|
||||
c = *++s;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *++s;
|
||||
|
||||
if (c == '0')
|
||||
{
|
||||
c = *++s;
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
base = 16;
|
||||
c = *++s;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = 8;
|
||||
} else if (base == 0)
|
||||
base = 10;
|
||||
|
||||
long v = 0;
|
||||
for(;;)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
v = v * base + (c - '0');
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
v = v * base + (c - 'a' + 10);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
v = v * base + (c - 'A' + 10);
|
||||
else
|
||||
break;
|
||||
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (neg)
|
||||
v = -v;
|
||||
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned long strtoul(const char *s, const char **endp, char base)
|
||||
{
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
char c = *s;
|
||||
while (c <= ' ')
|
||||
{
|
||||
if (!c) return 0;
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (c == '0')
|
||||
{
|
||||
c = *++s;
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
base = 16;
|
||||
c = *++s;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = 8;
|
||||
} else if (base == 0)
|
||||
base = 10;
|
||||
|
||||
unsigned long v = 0;
|
||||
for(;;)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
v = v * base + (c - '0');
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
v = v * base + (c - 'a' + 10);
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
v = v * base + (c - 'A' + 10);
|
||||
else
|
||||
break;
|
||||
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
if (endp)
|
||||
*endp = s;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int abs(int n)
|
||||
{
|
||||
return n < 0 ? - n : n;
|
||||
}
|
||||
|
||||
long labs(long n)
|
||||
{
|
||||
return n < 0 ? - n : n;
|
||||
}
|
||||
|
||||
div_t div(int numer, int denom)
|
||||
{
|
||||
div_t result;
|
||||
|
||||
if (denom == 0)
|
||||
{
|
||||
result.quot = 0;
|
||||
result.rem = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.quot = numer / denom;
|
||||
result.rem = numer % denom;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ldiv_t ldiv(long int numer, long int denom)
|
||||
{
|
||||
ldiv_t result;
|
||||
|
||||
if (denom == 0)
|
||||
{
|
||||
result.quot = 0;
|
||||
result.rem = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.quot = numer / denom;
|
||||
result.rem = numer % denom;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void exit(int status)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda status
|
||||
sta accu + 0
|
||||
lda status + 1
|
||||
sta accu + 1
|
||||
ldx spentry
|
||||
txs
|
||||
lda #$4c
|
||||
sta $54
|
||||
lda #0
|
||||
sta $13
|
||||
}
|
||||
}
|
||||
|
||||
void abort(void)
|
||||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
extern struct Heap {
|
||||
Heap * next, * end;
|
||||
} HeapNode;
|
||||
|
||||
unsigned heapfree(void)
|
||||
{
|
||||
unsigned avail = 0;
|
||||
Heap * h = HeapNode.next;
|
||||
while (h)
|
||||
{
|
||||
avail += (h->end - h) * sizeof(Heap);
|
||||
h = h->next;
|
||||
}
|
||||
return avail;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct Heap {q
|
||||
unsigned int size;
|
||||
Heap * next;
|
||||
} * freeHeap;
|
||||
|
||||
bool freeHeapInit = false;
|
||||
|
||||
void HeapStart, HeapEnd;
|
||||
|
||||
#pragma section(heap, 0x0000, HeapStart, HeapEnd)
|
||||
|
||||
|
||||
void * malloc(unsigned int size)
|
||||
{
|
||||
size = (size + 7) & ~3;
|
||||
if (!freeHeapInit)
|
||||
{
|
||||
freeHeap = (Heap *)&HeapStart;
|
||||
freeHeap->next = nullptr;
|
||||
freeHeap->size = (unsigned int)&HeapEnd - (unsigned int)&HeapStart;
|
||||
freeHeapInit = true;
|
||||
}
|
||||
|
||||
Heap * pheap = nullptr, * heap = freeHeap;
|
||||
while (heap)
|
||||
{
|
||||
if (size <= heap->size)
|
||||
{
|
||||
if (size == heap->size)
|
||||
{
|
||||
if (pheap)
|
||||
pheap->next = heap->next;
|
||||
else
|
||||
freeHeap = heap->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
Heap * nheap = (Heap *)((int)heap + size);
|
||||
nheap->size = heap->size - size;
|
||||
nheap->next = heap->next;
|
||||
if (pheap)
|
||||
pheap->next = nheap;
|
||||
else
|
||||
freeHeap = nheap;
|
||||
heap->size = size;
|
||||
}
|
||||
|
||||
return (void *)((int)heap + 2);
|
||||
}
|
||||
pheap = heap;
|
||||
heap = heap->next;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void free(void * ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
Heap * fheap = (Heap *)((int)ptr - 2);
|
||||
Heap * eheap = (Heap *)((int)ptr - 2 + fheap->size);
|
||||
|
||||
if (freeHeap)
|
||||
{
|
||||
if (eheap == freeHeap)
|
||||
{
|
||||
fheap->size += freeHeap->size;
|
||||
fheap->next = freeHeap->next;
|
||||
freeHeap = fheap;
|
||||
}
|
||||
else if (eheap < freeHeap)
|
||||
{
|
||||
fheap->next = freeHeap;
|
||||
freeHeap = fheap;
|
||||
}
|
||||
else
|
||||
{
|
||||
Heap * pheap = freeHeap;
|
||||
while (pheap->next && pheap->next < fheap)
|
||||
pheap = pheap->next;
|
||||
Heap * nheap = (Heap *)((int)pheap + pheap->size);
|
||||
|
||||
if (nheap == fheap)
|
||||
{
|
||||
pheap->size += fheap->size;
|
||||
if (pheap->next == eheap)
|
||||
{
|
||||
pheap->size += pheap->next->size;
|
||||
pheap->next = pheap->next->next;
|
||||
}
|
||||
}
|
||||
else if (pheap->next == eheap)
|
||||
{
|
||||
fheap->next = pheap->next->next;
|
||||
fheap->size += pheap->next->size;
|
||||
pheap->next = fheap;
|
||||
}
|
||||
else
|
||||
{
|
||||
fheap->next = pheap->next;
|
||||
pheap->next = fheap;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freeHeap = fheap;
|
||||
freeHeap->next = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void * calloc(int num, int size)
|
||||
{
|
||||
size *= num;
|
||||
void * p = malloc(size);
|
||||
if (p)
|
||||
memclr(p, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
void * realloc(void * ptr, unsigned size)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
#ifdef HEAPCHECK
|
||||
Heap * pheap = (Heap *)((char *)ptr - 6);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 6);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#else
|
||||
unsigned nsize = (size + 5) & ~3;
|
||||
|
||||
// Get heap info
|
||||
Heap * pheap = (Heap *)((char *)ptr - 2);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
Heap * h = HeapNode.next;
|
||||
Heap * hp = &HeapNode;
|
||||
while (h && h < pheap)
|
||||
{
|
||||
hp = h;
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (nsize <= psize)
|
||||
{
|
||||
// check if we should free some memory
|
||||
if (nsize + sizeof(HeapNode) < psize)
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
|
||||
if (h == eheap)
|
||||
{
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
nheap->end = eheap;
|
||||
nheap->next = h;
|
||||
}
|
||||
|
||||
hp->next = nheap;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
else if (h == eheap)
|
||||
{
|
||||
// Free space after this
|
||||
|
||||
// Check if enough space if extending
|
||||
unsigned xsize = (char *)h->end - (char *)pheap;
|
||||
if (xsize >= nsize)
|
||||
{
|
||||
if (xsize > nsize + sizeof(HeapNode))
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
hp->next = nheap;
|
||||
}
|
||||
else
|
||||
{
|
||||
pheap->next = h->end;
|
||||
hp->next = h->next;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 2);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static unsigned seed = 31232;
|
||||
static unsigned long seedl = 321432142412;
|
||||
|
||||
unsigned int rand(void)
|
||||
{
|
||||
seed ^= seed << 7;
|
||||
seed ^= seed >> 9;
|
||||
seed ^= seed << 8;
|
||||
return seed;
|
||||
}
|
||||
|
||||
void srand(unsigned int s)
|
||||
{
|
||||
seed = s;
|
||||
}
|
||||
|
||||
unsigned long lrand(void)
|
||||
{
|
||||
seedl ^= seedl << 13;
|
||||
seedl ^= seedl >> 17;
|
||||
seedl ^= seedl << 5;
|
||||
return seedl;
|
||||
}
|
||||
|
||||
void lsrand(unsigned long s)
|
||||
{
|
||||
seedl = s;
|
||||
}
|
||||
Reference in New Issue
Block a user