Files
zSoft/apps/common/sysutils.c

309 lines
6.3 KiB
C

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Name: sysutils.c
// Created: January 2019
// Author(s): Philip Smart
// Description: Utilities for C compilation when stdlib is not included in the linker list.
// Basically a set of functions which are in libc cut down to basics. EVentually this
// module should be replaced by a micro libc compatible with the ZPU and K64F.
//
// Credits:
// Copyright: modifications (c) 2019-2020 Philip Smart <philip.smart@net2net.org>
//
// History: January 2020 - Utilities assembled from various sources.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// This source file is free software: you can redistribute it and#or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__K64F__)
#define uint32_t __uint32_t
#define uint16_t __uint16_t
#define uint8_t __uint8_t
#define int32_t __int32_t
#define int16_t __int16_t
#define int8_t __int8_t
#elif defined(__ZPU__)
#include <stdio.h>
#include <stdlib.h>
#else
#error "Target CPU not defined, use __ZPU__ or __K64F__"
#endif
#include <errno.h>
extern unsigned long _stext;
extern unsigned long _etext;
extern unsigned long _sdata;
extern unsigned long _edata;
extern unsigned long _sbss;
extern unsigned long _ebss;
extern unsigned long _estack;
#ifndef STACK_MARGIN
#define STACK_MARGIN 8192
#endif
#if defined(__ZPU__)
void outbyte(char c)
{
(void)xputc(c);
}
char inbyte(void)
{
return getserial();
}
#endif
int strlen(const char* s) {
int i;
for (i = 0; s[i]; i++) {
}
return i;
}
void* memcpy(void* dst, const void* src, int sz) {
char* d = (char*) dst;
char* s = (char*) src;
while (sz-- > 0) {
*(d++) = *(s++);
}
return dst;
}
int memcmp(const void* dst, const void* src, int sz) {
unsigned char* d = (unsigned char*) dst;
unsigned char* s = (unsigned char*) src;
int i, v;
for (i = 0; i < sz; i++) {
v = *(d++) - *(s++);
if (v != 0) {
return v;
}
}
return 0;
}
void *memset (void *dest, int val, size_t len)
{
unsigned char *ptr = dest;
while (len-- > 0)
*ptr++ = val;
return dest;
}
void* memmove(void* dst, const void* src, int sz) {
unsigned char* d = (unsigned char*) dst;
unsigned char* s = (unsigned char*) src;
int i;
if (d < s) {
for (i = 0; i < sz; i++) {
*(d++) = *(s++);
}
} else {
d += sz;
s += sz;
for (i = 0; i < sz; i++) {
*(--d) = *(--s);
}
}
return dst;
}
int strcmp (const char *p1, const char *p2)
{
const unsigned char *s1 = (const unsigned char *) p1;
const unsigned char *s2 = (const unsigned char *) p2;
unsigned char c1, c2;
do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2);
return c1 - c2;
}
char *strchr (register const char *s, int c)
{
do {
if (*s == c)
{
return (char*)s;
}
} while (*s++);
return (0);
}
char *strcpy (char *dest, const char *src)
{
return memcpy (dest, src, strlen (src) + 1);
}
int strncmp(const char *s1, const char *s2, register size_t n)
{
register unsigned char u1, u2;
while (n-- > 0)
{
u1 = (unsigned char) *s1++;
u2 = (unsigned char) *s2++;
if (u1 != u2)
return u1 - u2;
if (u1 == '\0')
return 0;
}
return 0;
}
char *strstr (const char *s1, const char *s2)
{
const char *p = s1;
const size_t len = strlen (s2);
for (; (p = strchr (p, *s2)) != 0; p++)
{
if (strncmp (p, s2, len) == 0)
return (char *)p;
}
return (0);
}
//char *__brkval = (char *)&_ebss;
//
//void * _sbrk(int incr)
//{
// char *prev, *stack;
//
// prev = __brkval;
// if (incr != 0) {
// #if defined __K64F__
// __asm__ volatile("mov %0, sp" : "=r" (stack) ::);
// #endif
// if (prev + incr >= stack - STACK_MARGIN) {
//// errno = ENOMEM;
// return (void *)-1;
// }
// __brkval = prev + incr;
// }
// return prev;
//}
//extern char __end__; /**< Defined by the linker */
//extern char __HeapLimit; /**< Defined by the linker */
//void * _sbrk(int incr)
//{
// static char *heap_end;
// char *prev_heap_end;
//
// if (heap_end == 0)
// {
// heap_end = &__end__;
//xprintf("Memory start:%d, %08lx\n",incr, heap_end);
// }
//
// prev_heap_end = heap_end;
// if ((heap_end + incr) > (char*) &__HeapLimit)
// {
//xprintf("Memory exhausted:%d, %08lx\n",incr, prev_heap_end);
// //errno = ENOMEM;
// return ((void*)-1); // error - no more memory
// }
// heap_end += incr;
//xprintf("Allocate:%d,end:%08lx\n",incr, prev_heap_end);
// return prev_heap_end;
//}
__attribute__((weak))
int _read(int file, char *ptr, int len)
{
strcpy(ptr, "HEREHERE\n");
return 9;
}
__attribute__((weak))
int _write(int file, char *ptr, int len)
{
return 0;
}
__attribute__((weak))
int _close(int fd)
{
return -1;
}
#include <sys/stat.h>
__attribute__((weak))
int _fstat(int fd, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
__attribute__((weak))
int _isatty(int fd)
{
return 1;
}
__attribute__((weak))
int _lseek(int fd, long long offset, int whence)
{
return -1;
}
__attribute__((weak))
void _exit(int status)
{
while (1);
}
__attribute__((weak))
void __cxa_pure_virtual()
{
while (1);
}
__attribute__((weak))
int __cxa_guard_acquire (char *g)
{
return !(*g);
}
__attribute__((weak))
void __cxa_guard_release(char *g)
{
*g = 1;
}
__attribute__((weak))
void abort(void)
{
while (1) ;
}
#ifdef __cplusplus
}
#endif