From 35b97557e72e163566a52aec49a34a8dd4f0733a Mon Sep 17 00:00:00 2001 From: Marcin Gasperowicz Date: Sun, 23 Dec 2012 13:55:12 +0100 Subject: [PATCH] Added some parts of standard library WARNING, this stuff should compile fine but it's untested. There's no support for many functions atm. --- .gitignore | 1 + include/ctype.h | 176 ++++++++++++ include/errno.h | 81 ++++++ include/limits.h | 72 +++++ include/stdarg.h | 57 ++++ include/stdbool.h | 53 ++++ include/stddef.h | 70 +++++ include/stdint.h | 144 ++++++++++ include/stdio.h | 150 +++++++++++ include/stdlib.h | 136 ++++++++++ include/string.h | 95 +++++++ lib/asminc/ctype.inc | 29 ++ lib/common/Makefile | 259 +++++++++--------- lib/common/abs.s | 16 ++ lib/common/atoi.s | 138 ++++++++++ lib/common/isalnum.s | 21 ++ lib/common/isalpha.s | 21 ++ lib/common/isblank.s | 23 ++ lib/common/iscntrl.s | 21 ++ lib/common/isdigit.s | 21 ++ lib/common/isgraph.s | 22 ++ lib/common/islower.s | 21 ++ lib/common/isprint.s | 22 ++ lib/common/ispunct.s | 22 ++ lib/common/isspace.s | 21 ++ lib/common/isupper.s | 21 ++ lib/common/isxdigit.s | 21 ++ lib/common/itoa.s | 146 ++++++++++ lib/common/memchr.s | 57 ++++ lib/common/memcmp.s | 72 +++++ lib/common/memcpy.s | 80 ++++++ lib/common/memmove.s | 84 ++++++ lib/common/memset.s | 95 +++++++ lib/common/strcat.s | 55 ++++ lib/common/strchr.s | 48 ++++ lib/common/strcmp.s | 35 +++ lib/common/strcoll.s | 13 + lib/common/strcpy.s | 30 +++ lib/common/strcspn.s | 54 ++++ lib/common/strdup.s | 85 ++++++ lib/common/strerror.s | 35 +++ lib/common/strftime.c | 224 ++++++++++++++++ lib/common/stricmp.s | 60 +++++ lib/common/strlen.s | 26 ++ lib/common/strlower.s | 47 ++++ lib/common/strncat.s | 72 +++++ lib/common/strncmp.s | 81 ++++++ lib/common/strncpy.s | 69 +++++ lib/common/strnicmp.s | 103 +++++++ lib/common/stroserr.s | 61 +++++ lib/common/strpbrk.s | 60 +++++ lib/common/strrchr.s | 47 ++++ lib/common/strspn.s | 56 ++++ lib/common/strstr.s | 97 +++++++ lib/common/strtoimax.s | 9 + lib/common/strtok.c | 77 ++++++ lib/common/strtok.s | 228 ++++++++++++++++ lib/common/strtol.c | 128 +++++++++ lib/common/strtol.s | 592 +++++++++++++++++++++++++++++++++++++++++ lib/common/strtoul.c | 119 +++++++++ lib/common/strtoul.s | 541 +++++++++++++++++++++++++++++++++++++ lib/common/strtoumax.s | 9 + lib/common/strupper.s | 47 ++++ lib/common/strxfrm.c | 20 ++ lib/common/strxfrm.s | 82 ++++++ lib/common/tolower.s | 21 ++ lib/common/toupper.s | 21 ++ lib/rpc8e.lib | Bin 108327 -> 146816 bytes lib/rpc8e/Makefile | 3 +- lib/rpc8e/ctype.s | 161 +++++++++++ 70 files changed, 5558 insertions(+), 126 deletions(-) create mode 100644 include/ctype.h create mode 100644 include/errno.h create mode 100644 include/limits.h create mode 100644 include/stdarg.h create mode 100644 include/stdbool.h create mode 100644 include/stddef.h create mode 100644 include/stdint.h create mode 100644 include/stdio.h create mode 100644 include/stdlib.h create mode 100644 include/string.h create mode 100644 lib/asminc/ctype.inc create mode 100644 lib/common/abs.s create mode 100644 lib/common/atoi.s create mode 100644 lib/common/isalnum.s create mode 100644 lib/common/isalpha.s create mode 100644 lib/common/isblank.s create mode 100644 lib/common/iscntrl.s create mode 100644 lib/common/isdigit.s create mode 100644 lib/common/isgraph.s create mode 100644 lib/common/islower.s create mode 100644 lib/common/isprint.s create mode 100644 lib/common/ispunct.s create mode 100644 lib/common/isspace.s create mode 100644 lib/common/isupper.s create mode 100644 lib/common/isxdigit.s create mode 100644 lib/common/itoa.s create mode 100644 lib/common/memchr.s create mode 100644 lib/common/memcmp.s create mode 100644 lib/common/memcpy.s create mode 100644 lib/common/memmove.s create mode 100644 lib/common/memset.s create mode 100644 lib/common/strcat.s create mode 100644 lib/common/strchr.s create mode 100644 lib/common/strcmp.s create mode 100644 lib/common/strcoll.s create mode 100644 lib/common/strcpy.s create mode 100644 lib/common/strcspn.s create mode 100644 lib/common/strdup.s create mode 100644 lib/common/strerror.s create mode 100644 lib/common/strftime.c create mode 100644 lib/common/stricmp.s create mode 100644 lib/common/strlen.s create mode 100644 lib/common/strlower.s create mode 100644 lib/common/strncat.s create mode 100644 lib/common/strncmp.s create mode 100644 lib/common/strncpy.s create mode 100644 lib/common/strnicmp.s create mode 100644 lib/common/stroserr.s create mode 100644 lib/common/strpbrk.s create mode 100644 lib/common/strrchr.s create mode 100644 lib/common/strspn.s create mode 100644 lib/common/strstr.s create mode 100644 lib/common/strtoimax.s create mode 100644 lib/common/strtok.c create mode 100644 lib/common/strtok.s create mode 100644 lib/common/strtol.c create mode 100644 lib/common/strtol.s create mode 100644 lib/common/strtoul.c create mode 100644 lib/common/strtoul.s create mode 100644 lib/common/strtoumax.s create mode 100644 lib/common/strupper.s create mode 100644 lib/common/strxfrm.c create mode 100644 lib/common/strxfrm.s create mode 100644 lib/common/tolower.s create mode 100644 lib/common/toupper.s create mode 100644 lib/rpc8e/ctype.s diff --git a/.gitignore b/.gitignore index be91256..0c31482 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store *.o *.img +os/ \ No newline at end of file diff --git a/include/ctype.h b/include/ctype.h new file mode 100644 index 0000000..ac88534 --- /dev/null +++ b/include/ctype.h @@ -0,0 +1,176 @@ +/*****************************************************************************/ +/* */ +/* ctype.h */ +/* */ +/* Character handling */ +/* */ +/* */ +/* */ +/* (C) 1998-2004 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _CTYPE_H +#define _CTYPE_H + + +/* The array containing character classification data */ +extern unsigned char _ctype[256]; + +/* Bits used to specify characters classes */ +#define _CT_LOWER 0x01 /* 0 - Lower case char */ +#define _CT_UPPER 0x02 /* 1 - Upper case char */ +#define _CT_DIGIT 0x04 /* 2 - Numeric digit */ +#define _CT_XDIGIT 0x08 /* 3 - Hex digit (both, lower and upper) */ +#define _CT_CNTRL 0x10 /* 4 - Control character */ +#define _CT_SPACE 0x20 /* 5 - The space character itself */ +#define _CT_OTHER_WS 0x40 /* 6 - Other whitespace ('\f', '\n', '\r', '\t' and '\v') */ +#define _CT_SPACE_TAB 0x80 /* 7 - Space or tab character */ + +/* Bit combinations */ +#define _CT_ALNUM (_CT_LOWER | _CT_UPPER | _CT_DIGIT) +#define _CT_ALPHA (_CT_LOWER | _CT_UPPER) +#define _CT_NOT_GRAPH (_CT_CNTRL | _CT_SPACE) +#define _CT_NOT_PRINT (_CT_CNTRL) +#define _CT_NOT_PUNCT (_CT_SPACE | _CT_CNTRL | _CT_DIGIT | _CT_UPPER | _CT_LOWER) +#define _CT_WS (_CT_SPACE | _CT_OTHER_WS) + +/* Character classification functions */ +int __fastcall__ isalnum (int c); +int __fastcall__ isalpha (int c); +int __fastcall__ iscntrl (int c); +int __fastcall__ isdigit (int c); +int __fastcall__ isgraph (int c); +int __fastcall__ islower (int c); +int __fastcall__ isprint (int c); +int __fastcall__ ispunct (int c); +int __fastcall__ isspace (int c); +int __fastcall__ isupper (int c); +int __fastcall__ isxdigit (int c); +#if __CC65_STD__ >= __CC65_STD_C99__ +int __fastcall__ isblank (int c); /* New in C99 */ +#endif + +int __fastcall__ toupper (int c); /* Always external */ +int __fastcall__ tolower (int c); /* Always external */ + + + +/* When inlining of known function is enabled, overload most of the above + * functions by macros. The function prototypes are again available after + * #undef'ing the macros. + * Please note that the following macros do NOT handle EOF correctly, as + * stated in the manual. If you need correct behaviour for EOF, don't + * use -Os, or #undefine the following macros. + */ +#ifdef __OPT_s__ + +#define isalnum(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_ALNUM), \ + __AX__) + +#define isalpha(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_ALPHA), \ + __AX__) + +#if __CC65_STD__ >= __CC65_STD_C99__ +#define isblank(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_SPACE_TAB), \ + __AX__) +#endif + +#define iscntrl(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_CNTRL), \ + __AX__) + +#define isdigit(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_DIGIT), \ + __AX__) + +#define isgraph(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("eor #%b", _CT_NOT_GRAPH), \ + __asm__ ("and #%b", _CT_NOT_GRAPH), \ + __AX__) + +#define islower(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_LOWER), \ + __AX__) + +#define isprint(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("eor #%b", _CT_NOT_PRINT), \ + __asm__ ("and #%b", _CT_NOT_PRINT), \ + __AX__) + +#define ispunct(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("eor #%b", _CT_NOT_PUNCT), \ + __asm__ ("and #%b", _CT_NOT_PUNCT), \ + __AX__) + +#define isspace(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_WS), \ + __AX__) + +#define isupper(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_UPPER), \ + __AX__) + +#define isxdigit(c) (__AX__ = (c), \ + __asm__ ("tay"), \ + __asm__ ("lda %v,y", _ctype), \ + __asm__ ("and #%b", _CT_XDIGIT), \ + __AX__) + +#endif + + + +/* End of ctype.h */ +#endif + + + diff --git a/include/errno.h b/include/errno.h new file mode 100644 index 0000000..edb4a0e --- /dev/null +++ b/include/errno.h @@ -0,0 +1,81 @@ +/*****************************************************************************/ +/* */ +/* errno.h */ +/* */ +/* Error codes */ +/* */ +/* */ +/* */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _ERRNO_H +#define _ERRNO_H + + + +/* Operating system specific error codes */ +extern unsigned char _oserror; + +/* Mapper function, don't call directly */ +void _maperrno (void); + +/* This one is called under the hood. User callable. */ +int __fastcall__ _osmaperrno (unsigned char oserror); + +/* System error codes go here */ +extern int _errno; + +/* errno must be a macro, here the mapper is called */ +#define errno (_maperrno(), _errno) + + + +/* Possible error codes */ +#define ENOENT 1 /* No such file or directory */ +#define ENOMEM 2 /* Out of memory */ +#define EACCES 3 /* Permission denied */ +#define ENODEV 4 /* No such device */ +#define EMFILE 5 /* Too many open files */ +#define EBUSY 6 /* Device or resource busy */ +#define EINVAL 7 /* Invalid argument */ +#define ENOSPC 8 /* No space left on device */ +#define EEXIST 9 /* File exists */ +#define EAGAIN 10 /* Try again */ +#define EIO 11 /* I/O error */ +#define EINTR 12 /* Interrupted system call */ +#define ENOSYS 13 /* Function not implemented */ +#define ESPIPE 14 /* Illegal seek */ +#define ERANGE 15 /* Range error */ +#define EUNKNOWN 16 /* Unknown OS specific error */ + + + +#endif + + + diff --git a/include/limits.h b/include/limits.h new file mode 100644 index 0000000..d02d52d --- /dev/null +++ b/include/limits.h @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/* */ +/* limits.h */ +/* */ +/* Sizes of integer types */ +/* */ +/* */ +/* */ +/* (C) 1998-2002 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _LIMITS_H +#define _LIMITS_H + + + +#define CHAR_BIT 8 + +#define SCHAR_MIN ((signed char) 0x80) +#define SCHAR_MAX 127 + +#define UCHAR_MAX 255 + +#define CHAR_MIN 0 +#define CHAR_MAX 255 + +#define SHRT_MIN ((short) 0x8000) +#define SHRT_MAX 32767 + +#define USHRT_MAX 65535U + +#define INT_MIN ((int) 0x8000) +#define INT_MAX 32767 + +#define UINT_MAX 65535U + +#define LONG_MAX 2147483647L +#define LONG_MIN ((long) 0x80000000) + +#define ULONG_MAX 4294967295UL + + + +/* End of limits.h */ +#endif + + + diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100644 index 0000000..4fd822b --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,57 @@ +/*****************************************************************************/ +/* */ +/* stdarg.h */ +/* */ +/* Variable arguments */ +/* */ +/* */ +/* */ +/* (C) 1998-2004 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _STDARG_H +#define _STDARG_H + + + +typedef unsigned char* va_list; + +#define va_start(ap, fix) ap = ((va_list)&(fix)) +#define va_arg(ap,type) (*(type*)(ap -= ((sizeof (type) + 1) & ~1))) +#if __CC65_STD__ >= __CC65_STD_C99__ +#define va_copy(dest, src) ((dest)=(src)) +#endif +#define va_end(ap) + + + +/* End of stdarg.h */ +#endif + + + + diff --git a/include/stdbool.h b/include/stdbool.h new file mode 100644 index 0000000..638d35a --- /dev/null +++ b/include/stdbool.h @@ -0,0 +1,53 @@ +/*****************************************************************************/ +/* */ +/* stdbool.h */ +/* */ +/* C99 Boolean definitions */ +/* */ +/* */ +/* */ +/* (C) 2002 Greg King */ +/* */ +/* */ +/* This software is provided "as-is," without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment, in the product's documentation, */ +/* would be appreciated, but is not required. */ +/* 2. Alterred source versions must be marked plainly as such, */ +/* and must not be misrepresented as being the original software. */ +/* 3. This notice may not be removed or alterred */ +/* from any source distribution. */ +/*****************************************************************************/ + + + +#ifndef _STDBOOL_H +#define _STDBOOL_H + + + +#define bool _Bool +typedef unsigned char _Bool; + +/* Standard test-results. */ +#define false 0 +#define true 1 + +/* All three names are macroes. */ +#define __bool_true_false_are_defined 1 + + + +/* End of stdbool.h */ +#endif + + + diff --git a/include/stddef.h b/include/stddef.h new file mode 100644 index 0000000..eff0c55 --- /dev/null +++ b/include/stddef.h @@ -0,0 +1,70 @@ +/*****************************************************************************/ +/* */ +/* stddef.h */ +/* */ +/* Common definitions */ +/* */ +/* */ +/* */ +/* (C) 1998-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _STDDEF_H +#define _STDDEF_H + + + +/* Standard data types */ +#ifndef _HAVE_ptrdiff_t +#define _HAVE_ptrdiff_t +typedef int ptrdiff_t; +#endif +#ifndef _HAVE_wchar_t +#define _HAVE_wchar_t +typedef char wchar_t; +#endif +#ifndef _HAVE_size_t +#define _HAVE_size_t +typedef unsigned size_t; +#endif + +/* NULL pointer */ +#ifndef _HAVE_NULL +#define NULL 0 +#define _HAVE_NULL +#endif + +/* offsetof macro */ +#define offsetof(type, member) (size_t) (&((type*) 0)->member) + + + +/* End of stddef.h */ +#endif + + + diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..0053a9b --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,144 @@ +/*****************************************************************************/ +/* */ +/* stdint.h */ +/* */ +/* Standard integer types */ +/* */ +/* */ +/* */ +/* (C) 2002 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* Note: This file is not fully ISO 9899-1999 compliant because cc65 lacks + * a 64 bit data types. The declarations have been adjusted accordingly. + */ + + + +#ifndef _STDINT_H +#define _STDINT_H + + + +/* Exact-width integer types */ +typedef signed char int8_t; +typedef int int16_t; +typedef long int32_t; +typedef unsigned char uint8_t; +typedef unsigned uint16_t; +typedef unsigned long uint32_t; + +#define INT8_MIN ((int8_t) 0x80) +#define INT8_MAX ((int8_t) 0x7F) +#define INT16_MIN ((int16_t) 0x8000) +#define INT16_MAX ((int16_t) 0x7FFF) +#define INT32_MIN ((int32_t) 0x80000000) +#define INT32_MAX ((int32_t) 0x7FFFFFFF) +#define UINT8_MAX ((uint8_t) 0xFF) +#define UINT16_MAX ((uint16_t) 0xFFFF) +#define UINT32_MAX ((uint32_t) 0xFFFFFFFF) + +/* Minimum-width integer types */ +typedef signed char int_least8_t; +typedef int int_least16_t; +typedef long int_least32_t; +typedef unsigned char uint_least8_t; +typedef unsigned uint_least16_t; +typedef unsigned long uint_least32_t; + +#define INT_LEAST8_MIN ((int_least8_t) 0x80) +#define INT_LEAST8_MAX ((int_least8_t) 0x7F) +#define INT_LEAST16_MIN ((int_least16_t) 0x8000) +#define INT_LEAST16_MAX ((int_least16_t) 0x7FFF) +#define INT_LEAST32_MIN ((int_least32_t) 0x80000000) +#define INT_LEAST32_MAX ((int_least32_t) 0x7FFFFFFF) +#define UINT_LEAST8_MAX ((uint_least8_t) 0xFF) +#define UINT_LEAST16_MAX ((uint_least16_t) 0xFFFF) +#define UINT_LEAST32_MAX ((uint_least32_t) 0xFFFFFFFF) + +/* Fastest minimum-width integer types */ +typedef signed char int_fast8_t; +typedef int int_fast16_t; +typedef long int_fast32_t; +typedef unsigned char uint_fast8_t; +typedef unsigned uint_fast16_t; +typedef unsigned long uint_fast32_t; + +#define INT_FAST8_MIN ((int_fast8_t) 0x80) +#define INT_FAST8_MAX ((int_fast8_t) 0x7F) +#define INT_FAST16_MIN ((int_fast16_t) 0x8000) +#define INT_FAST16_MAX ((int_fast16_t) 0x7FFF) +#define INT_FAST32_MIN ((int_fast32_t) 0x80000000) +#define INT_FAST32_MAX ((int_fast32_t) 0x7FFFFFFF) +#define UINT_FAST8_MAX ((uint_fast8_t) 0xFF) +#define UINT_FAST16_MAX ((uint_fast16_t) 0xFFFF) +#define UINT_FAST32_MAX ((uint_fast32_t) 0xFFFFFFFF) + +/* Integer types capable of holding object pointers */ +typedef int intptr_t; +typedef unsigned uintptr_t; + +#define INTPTR_MIN ((intptr_t)0x8000) +#define INTPTR_MAX ((intptr_t)0x7FFF) +#define UINTPTR_MAX ((uintptr_t) 0xFFFF) + +/* Greatest width integer types */ +typedef long intmax_t; +typedef unsigned long uintmax_t; + +#define INTMAX_MIN ((intmax_t) 0x80000000) +#define INTMAX_MAX ((intmax_t) 0x7FFFFFFF) +#define UINTMAX_MAX ((uintmax_t) 0xFFFFFFFF) + +/* Limits of other integer types */ +#define PTRDIFF_MIN ((int) 0x8000) +#define PTRDIFF_MAX ((int) 0x7FFF) + +#define SIG_ATOMIC_MIN ((unsigned char) 0x00) +#define SIG_ATOMIC_MAX ((unsigned char) 0xFF) + +#define SIZE_MAX 0xFFFF + +/* Macros for minimum width integer constants */ +#define INT8_C(c) c +#define INT16_C(c) c +#define INT32_C(c) c##L +#define UINT8_C(c) c##U +#define UINT16_C(c) c##U +#define UINT32_C(c) c##UL + +/* Macros for greatest width integer constants */ +#define INTMAX_C(c) c##L +#define UINTMAX_C(c) c##UL + + + +/* End of stdint.h */ +#endif + + + diff --git a/include/stdio.h b/include/stdio.h new file mode 100644 index 0000000..f160160 --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,150 @@ +/*****************************************************************************/ +/* */ +/* stdio.h */ +/* */ +/* Input/output */ +/* */ +/* */ +/* */ +/* (C) 1998-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _STDIO_H +#define _STDIO_H + + + +#ifndef _STDDEF_H +# include +#endif +#ifndef _STDARG_H +# include +#endif + + + +/* Types */ +typedef struct _FILE FILE; +typedef unsigned long fpos_t; + +/* Standard file descriptors */ +extern FILE* stdin; +extern FILE* stdout; +extern FILE* stderr; + +/* Standard defines */ +#define _IOFBF 0 +#define _IOLBF 1 +#define _IONBF 2 +#define BUFSIZ 256 +#define EOF -1 +#define FOPEN_MAX 8 +#define SEEK_CUR 0 +#define SEEK_END 1 +#define SEEK_SET 2 +#define TMP_MAX 256 + +/* Standard defines that are platform dependent */ +#if defined(__APPLE2__) || defined(__APPLE2ENH__) +# define FILENAME_MAX (64+1) +#elif defined(__ATARI__) +# define FILENAME_MAX (12+1) +#elif defined(__LUNIX__) +# define FILENAME_MAX (80+1) +#else +# define FILENAME_MAX (16+1) +#endif +#define L_tmpnam FILENAME_MAX + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +/* Functions */ +void __fastcall__ clearerr (FILE* f); +int __fastcall__ fclose (FILE* f); +int __fastcall__ feof (FILE* f); +int __fastcall__ ferror (FILE* f); +int __fastcall__ fflush (FILE* f); +int __fastcall__ fgetc (FILE* f); +char* __fastcall__ fgets (char* buf, size_t size, FILE* f); +FILE* __fastcall__ fopen (const char* name, const char* mode); +int fprintf (FILE* f, const char* format, ...); +int __fastcall__ fputc (int c, FILE* f); +int __fastcall__ fputs (const char* s, FILE* f); +size_t __fastcall__ fread (void* buf, size_t size, size_t count, FILE* f); +FILE* __fastcall__ freopen (const char* name, const char* mode, FILE* f); +size_t __fastcall__ fwrite (const void* buf, size_t size, size_t count, FILE* f); +int __fastcall__ fgetpos (FILE* f, fpos_t *pos); +int __fastcall__ fsetpos (FILE* f, const fpos_t* pos); +long __fastcall__ ftell (FILE* f); +int __fastcall__ fseek (FILE* f, long offset, int whence); +void __fastcall__ rewind (FILE *f); +int __fastcall__ getchar (void); +char* __fastcall__ gets (char* s); +void __fastcall__ perror (const char* s); +int printf (const char* format, ...); +int __fastcall__ putchar (int c); +int __fastcall__ puts (const char* s); +int __fastcall__ remove (const char* name); +int __fastcall__ rename (const char* oldname, const char* newname); +int snprintf (char* buf, size_t size, const char* format, ...); +int sprintf (char* buf, const char* format, ...); +int __fastcall__ ungetc (int c, FILE* f); +int __fastcall__ vfprintf (FILE* f, const char* format, va_list ap); +int __fastcall__ vprintf (const char* format, va_list ap); +int __fastcall__ vsnprintf (char* buf, size_t size, const char* format, va_list ap); +int __fastcall__ vsprintf (char* buf, const char* format, va_list ap); + +int scanf (const char* format, ...); +int fscanf (FILE* f, const char* format, ...); +int sscanf (const char* s, const char* format, ...); +int __fastcall__ vscanf (const char* format, va_list ap); +int __fastcall__ vsscanf (const char* s, const char* format, va_list ap); +int __fastcall__ vfscanf (FILE* f, const char* format, va_list ap); + +#if __CC65_STD__ == __CC65_STD_CC65__ +FILE* __fastcall__ fdopen (int fd, const char* mode); /* Unix */ +int __fastcall__ fileno (FILE* f); /* Unix */ +#endif +void __fastcall__ _poserror (const char* msg); /* cc65 */ + +/* Masking macros for some functions */ +#define getc(f) fgetc (f) /* ANSI */ +#define putc(c, f) fputc (c, f) /* ANSI */ + + + +/* End of stdio.h */ +#endif + + + diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100644 index 0000000..a58d29c --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,136 @@ +/*****************************************************************************/ +/* */ +/* stdlib.h */ +/* */ +/* General utilities */ +/* */ +/* */ +/* */ +/* (C) 1998-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _STDLIB_H +#define _STDLIB_H + + + +/* size_t is needed */ +#ifndef _HAVE_size_t +typedef unsigned size_t; +#define _HAVE_size_t +#endif + +/* Standard exit codes */ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + +/* Return type of the div function */ +typedef struct { + int rem; + int quot; +} div_t; + +/* Return type of the ldiv function (which currently doesn't exist) */ +typedef struct { + long rem; + long quot; +} ldiv_t; + +/* Memory management */ +void* __fastcall__ malloc (size_t size); +void* __fastcall__ calloc (size_t count, size_t size); +void* __fastcall__ realloc (void* block, size_t size); +void __fastcall__ free (void* block); + +/* Non standard memory management functions */ + +#if __CC65_STD__ == __CC65_STD_CC65__ +int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size); +/* Allocate a block of memory with the given "size", which is aligned to a + * memory address that is a multiple of "alignment". "alignment" MUST NOT be + * zero, and MUST be a power of two; otherwise, this function will return + * EINVAL. The function returns ENOMEM if not enough memory is available + * to satisfy the request. "memptr" must point to a variable; that variable + * will return the address of the allocated memory. Use free() to release that + * allocated block. + */ +#endif + +void __fastcall__ _heapadd (void* mem, size_t size); +/* Add a block to the heap */ + +size_t __fastcall__ _heapblocksize (const void* block); +/* Return the size of an allocated block */ + +size_t __fastcall__ _heapmemavail (void); +/* Return the total free heap space */ + +size_t __fastcall__ _heapmaxavail (void); +/* Return the size of the largest free block on the heap */ + + +/* Random numbers */ +#define RAND_MAX 0x7FFF +int rand (void); +void __fastcall__ srand (unsigned seed); +void _randomize (void); /* Non-standard */ + +/* Other standard stuff */ +void abort (void); +int __fastcall__ abs (int val); +long __fastcall__ labs (long val); +int __fastcall__ atoi (const char* s); +long __fastcall__ atol (const char* s); +int __fastcall__ atexit (void (*exitfunc) (void)); +void* __fastcall__ bsearch (const void* key, const void* base, size_t n, + size_t size, int (*cmp) (const void*, const void*)); +div_t __fastcall__ div (int numer, int denom); +void __fastcall__ exit (int ret); +char* __fastcall__ getenv (const char* name); +void __fastcall__ qsort (void* base, size_t count, size_t size, + int (*compare) (const void*, const void*)); +long __fastcall__ strtol (const char* nptr, char** endptr, int base); +unsigned long __fastcall__ strtoul (const char* nptr, char** endptr, int base); +int __fastcall__ system (const char* s); + +/* Non-ANSI functions */ +void __fastcall__ _swap (void* p, void* q, size_t size); +#if __CC65_STD__ == __CC65_STD_CC65__ +char* __fastcall__ itoa (int val, char* buf, int radix); +char* __fastcall__ utoa (unsigned val, char* buf, int radix); +char* __fastcall__ ltoa (long val, char* buf, int radix); +char* __fastcall__ ultoa (unsigned long val, char* buf, int radix); +int __fastcall__ putenv (char* s); +#endif + + + +/* End of stdlib.h */ +#endif + + + diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000..7eb6995 --- /dev/null +++ b/include/string.h @@ -0,0 +1,95 @@ +/*****************************************************************************/ +/* */ +/* string.h */ +/* */ +/* String handling */ +/* */ +/* */ +/* */ +/* (C) 1998-2008 Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef _STRING_H +#define _STRING_H + + + +#include + + + +char* __fastcall__ strcat (char* dest, const char* src); +char* __fastcall__ strchr (const char* s, int c); +int __fastcall__ strcmp (const char* s1, const char* s2); +int __fastcall__ strcoll (const char* s1, const char* s2); +char* __fastcall__ strcpy (char* dest, const char* src); +size_t __fastcall__ strcspn (const char* s1, const char* s2); +char* __fastcall__ strerror (int errcode); +size_t __fastcall__ strlen (const char* s); +char* __fastcall__ strncat (char* s1, const char* s2, size_t count); +int __fastcall__ strncmp (const char* s1, const char* s2, size_t count); +char* __fastcall__ strncpy (char* dest, const char* src, size_t count); +char* __fastcall__ strrchr (const char* s, int c); +size_t __fastcall__ strspn (const char* s1, const char* s2); +char* __fastcall__ strstr (const char* str, const char* substr); +char* __fastcall__ strtok (char* s1, const char* s2); +size_t __fastcall__ strxfrm (char* s1, const char* s2, size_t count); +void* __fastcall__ memchr (const void* mem, int c, size_t count); +int __fastcall__ memcmp (const void* p1, const void* p2, size_t count); +void* __fastcall__ memcpy (void* dest, const void* src, size_t count); +void* __fastcall__ memmove (void* dest, const void* src, size_t count); +void* __fastcall__ memset (void* s, int c, size_t count); + +/* The following is an internal function, the compiler will replace memset + * with it if the fill value is zero. Never use this one directly! + */ +void* __fastcall__ _bzero (void* ptr, size_t n); + +/* Non standard: */ +#if __CC65_STD__ == __CC65_STD_CC65__ +void __fastcall__ bzero (void* ptr, size_t n); /* BSD */ +char* __fastcall__ strdup (const char* s); /* SYSV/BSD */ +int __fastcall__ stricmp (const char* s1, const char* s2); /* DOS/Windows */ +int __fastcall__ strcasecmp (const char* s1, const char* s2); /* Same for Unix */ +int __fastcall__ strnicmp (const char* s1, const char* s2, size_t count); /* DOS/Windows */ +int __fastcall__ strncasecmp (const char* s1, const char* s2, size_t count); /* Same for Unix */ +char* __fastcall__ strlwr (char* s); +char* __fastcall__ strlower (char* s); +char* __fastcall__ strupr (char* s); +char* __fastcall__ strupper (char* s); +#endif + +const char* __fastcall__ _stroserror (unsigned char errcode); +/* Map an operating system error number to an error message. */ + + + +/* End of string.h */ +#endif + + + diff --git a/lib/asminc/ctype.inc b/lib/asminc/ctype.inc new file mode 100644 index 0000000..2e29c72 --- /dev/null +++ b/lib/asminc/ctype.inc @@ -0,0 +1,29 @@ +; +; Definitions for the character type tables +; +; Ullrich von Bassewitz, 08.09.2001 +; + +; Make the __ctype table an exported/imported symbol + + .global __ctype + +; Define bitmapped constants for the table entries + +CT_NONE = $00 ; Nothing special +CT_LOWER = $01 ; 0 - Lower case char +CT_UPPER = $02 ; 1 - Upper case char +CT_DIGIT = $04 ; 2 - Numeric digit +CT_XDIGIT = $08 ; 3 - Hex digit (both, lower and upper) +CT_CTRL = $10 ; 4 - Control character +CT_SPACE = $20 ; 5 - The space character itself +CT_OTHER_WS = $40 ; 6 - Other whitespace ('\f', '\n', '\r', '\t' and '\v') +CT_SPACE_TAB = $80 ; 7 - Space or tab character + +; Combined stuff +CT_ALNUM = (CT_LOWER | CT_UPPER | CT_DIGIT) +CT_ALPHA = (CT_LOWER | CT_UPPER) +CT_CTRL_SPACE = (CT_CTRL | CT_SPACE) +CT_NOT_PUNCT = (CT_SPACE | CT_CTRL | CT_DIGIT | CT_UPPER | CT_LOWER) + + diff --git a/lib/common/Makefile b/lib/common/Makefile index b4a5617..3c25b6f 100644 --- a/lib/common/Makefile +++ b/lib/common/Makefile @@ -35,11 +35,17 @@ CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include --cpu $( %.lst : %.s @$(AS) $(AFLAGS) -l -o /dev/null $< + #-------------------------------------------------------------------------- # Object files # From C source-files -# C_OBJS = _afailed.o \ + C_OBJS = strtok.o \ + strtol.o \ + strtoul.o \ + strxfrm.o + # strftime.o \ +#_afailed.o \ # _hextab.o \ # _poserror.o \ # _scanf.o \ @@ -70,134 +76,137 @@ CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include --cpu $( # realloc.o \ # rewind.o \ # sleep.o \ -# strftime.o \ -# strtok.o \ -# strtol.o \ -# strtoul.o \ -# strxfrm.o \ + # system.o \ # timezone.o # From assembly source-files -S_OBJS = zerobss.o copydata.o -#_cwd.o \ - # _environ.o \ - # _fdesc.o \ - # _file.o \ - # _fopen.o \ - # _heap.o \ - # _heapadd.o \ - # _heapblocksize.o\ - # _heapmaxavail.o \ - # _heapmemavail.o \ - # _oserror.o \ - # _printf.o \ - # _seterrno.o \ - # _swap.o \ - # _sys.o \ - # abs.o \ - # atexit.o \ - # atoi.o \ - # calloc.o \ - # chdir.o \ - # copydata.o \ - # creat.o \ - # ctime.o \ - # divt.o \ - # errno.o \ - # fclose.o \ - # fmisc.o \ - # fopen.o \ - # fprintf.o \ - # fread.o \ - # free.o \ - # fscanf.o \ - # fwrite.o \ - # getcpu.o \ - # getcwd.o \ - # getenv.o \ - # interrupt.o \ - # isalnum.o \ - # isalpha.o \ - # isblank.o \ - # iscntrl.o \ - # isdigit.o \ - # isgraph.o \ - # islower.o \ - # isprint.o \ - # ispunct.o \ - # isspace.o \ - # isupper.o \ - # isxdigit.o \ - # itoa.o \ - # labs.o \ - # longjmp.o \ - # ltoa.o \ - # malloc.o \ - # maperrno.o \ - # memchr.o \ - # memcmp.o \ - # memcpy.o \ - # memmove.o \ - # memset.o \ - # mkdir.o \ - # modfree.o \ - # modload.o \ - # oserrcheck.o \ - # printf.o \ - # putchar.o \ - # putenv.o \ - # rand.o \ - # raise.o \ - # remove.o \ - # rename.o \ - # rmdir.o \ - # scanf.o \ - # searchenv.o \ - # setjmp.o \ - # signal.o \ - # sigtable.o \ - # snprintf.o \ - # sprintf.o \ - # sscanf.o \ - # strcat.o \ - # strchr.o \ - # strcmp.o \ - # strcoll.o \ - # strcpy.o \ - # strcspn.o \ - # strdup.o \ - # strerror.o \ - # stricmp.o \ - # strlen.o \ - # strlower.o \ - # strncat.o \ - # strncmp.o \ - # strncpy.o \ - # strnicmp.o \ - # stroserr.o \ - # strpbrk.o \ - # strrchr.o \ - # strspn.o \ - # strstr.o \ - # strtoimax.o \ - # strtoumax.o \ - # strupper.o \ - # time.o \ - # tolower.o \ - # toupper.o \ - # uname.o \ - # ungetc.o \ - # unlink.o \ - # utscopy.o \ - # vfprintf.o \ - # vfscanf.o \ - # vprintf.o \ - # vscanf.o \ - # vsnprintf.o \ - # vsprintf.o \ - # vsscanf.o \ - # zerobss.o +S_OBJS = zerobss.o \ + copydata.o \ + abs.o \ + atoi.o \ + isalnum.o \ + isalpha.o \ + isblank.o \ + iscntrl.o \ + isdigit.o \ + isgraph.o \ + islower.o \ + isprint.o \ + ispunct.o \ + isspace.o \ + isupper.o \ + isxdigit.o \ + itoa.o \ + memchr.o \ + memcmp.o \ + memcpy.o \ + memmove.o \ + memset.o \ +# mkdir.o \ + strcat.o \ + strchr.o \ + strcmp.o \ + strcoll.o \ + strcpy.o \ + strcspn.o \ + strdup.o \ + strerror.o \ + stricmp.o \ + strlen.o \ + strlower.o \ + strncat.o \ + strncmp.o \ + strncpy.o \ + strnicmp.o \ + stroserr.o \ + strpbrk.o \ + strrchr.o \ + strspn.o \ + strstr.o \ + strtoimax.o \ + strtoumax.o \ + strupper.o \ + tolower.o \ + toupper.o + # _cwd.o \ + # _environ.o \ + # _fdesc.o \ + # _file.o \ + # _fopen.o \ + # _heap.o \ + # _heapadd.o \ + # _heapblocksize.o\ + # _heapmaxavail.o \ + # _heapmemavail.o \ + # _oserror.o \ + # _printf.o \ + # _seterrno.o \ + # _swap.o \ + # _sys.o \ + + # atexit.o \ + + # calloc.o \ + # chdir.o \ + # copydata.o \ + # creat.o \ + # ctime.o \ + # divt.o \ + # errno.o \ + # fclose.o \ + # fmisc.o \ + # fopen.o \ + # fprintf.o \ + # fread.o \ + # free.o \ + # fscanf.o \ + # fwrite.o \ + # getcpu.o \ + # getcwd.o \ + # getenv.o \ + # interrupt.o \ + + # labs.o \ + # longjmp.o \ + # ltoa.o \ + # malloc.o \ + # maperrno.o \ + + # modfree.o \ + # modload.o \ + # oserrcheck.o \ + # printf.o \ + # putchar.o \ + # putenv.o \ + # rand.o \ + # raise.o \ + # remove.o \ + # rename.o \ + # rmdir.o \ + # scanf.o \ + # searchenv.o \ + # setjmp.o \ + # signal.o \ + # sigtable.o \ + # snprintf.o \ + # sprintf.o \ + # sscanf.o \ + + # time.o \ + + # uname.o \ + # ungetc.o \ + # unlink.o \s + # utscopy.o \ + # vfprintf.o \ + # vfscanf.o \ + # vprintf.o \ + # vscanf.o \ + # vsnprintf.o \ + # vsprintf.o \ + # vsscanf.o \ + # zerobss.o #-------------------------------------------------------------------------- diff --git a/lib/common/abs.s b/lib/common/abs.s new file mode 100644 index 0000000..273ec1c --- /dev/null +++ b/lib/common/abs.s @@ -0,0 +1,16 @@ +; +; Ullrich von Bassewitz, 17.06.1998 +; +; int abs (int x); +; + + .export _abs + .import negax + +_abs: cpx #$00 ; test hi byte + bpl L1 + jmp negax ; Negate if negative +L1: rts + + + diff --git a/lib/common/atoi.s b/lib/common/atoi.s new file mode 100644 index 0000000..d55ddb9 --- /dev/null +++ b/lib/common/atoi.s @@ -0,0 +1,138 @@ +; +; Ullrich von Bassewitz, 05.06.1998 +; +; int atoi (const char* s); +; long atol (const char* s); +; + + .export _atoi, _atol + .import negeax, __ctype + .importzp sreg, ptr1, ptr2, tmp1 + + .include "ctype.inc" + +; +; Conversion routine (32 bit) +; + +_atoi: +_atol: sta ptr1 ; Store s + stx ptr1+1 + ldy #0 + sty ptr2 + sty ptr2+1 ; initial value (32 bit) + sty sreg + sty sreg+1 + +; Skip whitespace + +L1: lda (ptr1),y + tax + lda __ctype,x ; get character classification + and #CT_SPACE_TAB ; tab or space? + beq L2 ; jump if no + iny + bne L1 + inc ptr1+1 + bne L1 ; branch always + +; Check for a sign. The character is in X + +L2: txa ; get char + ldx #0 ; flag: positive + cmp #'+' ; ### portable? + beq L3 + cmp #'-' ; ### portable? + bne L5 + dex ; flag: negative +L3: iny + bne L5 + inc ptr1+1 + +; Store the sign flag and setup for conversion + +L5: stx tmp1 ; remember sign flag + +L6: lda (ptr1),y ; get next char + tax + lda __ctype,x ; get character classification + and #$04 ; digit? + beq L8 ; done + +; Multiply ptr2 (the converted value) by 10 + + jsr mul2 ; * 2 + + lda sreg+1 + pha + lda sreg + pha + lda ptr2+1 + pha + lda ptr2 + pha ; Save value + + jsr mul2 ; * 4 + jsr mul2 ; * 8 + + clc + pla + adc ptr2 + sta ptr2 + pla + adc ptr2+1 + sta ptr2+1 + pla + adc sreg + sta sreg + pla + adc sreg+1 + sta sreg+1 ; x*2 + x*8 = x*10 + +; Get the character back and add it + + txa ; get char back + sec + sbc #'0' ; make numeric value + clc + adc ptr2 + sta ptr2 + bcc L7 + inc ptr2+1 + bne L7 + inc sreg + bne L7 + inc sreg+1 + +; Next character + +L7: iny + bne L6 + inc ptr1+1 + bne L6 + +; Conversion done. Load the low 16 bit into A/X + +L8: lda ptr2 + ldx ptr2+1 + +; Negate the value if necessary, otherwise we're done + + ldy tmp1 ; sign + beq L9 ; Branch if positive + +; Negate the 32 bit value in ptr2/sreg + + jmp negeax + +; +; Helper functions +; + +mul2: asl ptr2 + rol ptr2+1 + rol sreg + rol sreg+1 ; * 2 +L9: rts + + diff --git a/lib/common/isalnum.s b/lib/common/isalnum.s new file mode 100644 index 0000000..26fd7a2 --- /dev/null +++ b/lib/common/isalnum.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isalnum (int c); +; + + .export _isalnum + .include "ctype.inc" + +_isalnum: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_ALNUM ; Mask character/digit bits + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isalpha.s b/lib/common/isalpha.s new file mode 100644 index 0000000..624dec6 --- /dev/null +++ b/lib/common/isalpha.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isalpha (int c); +; + + .export _isalpha + .include "ctype.inc" + +_isalpha: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_ALPHA ; Mask character bits + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isblank.s b/lib/common/isblank.s new file mode 100644 index 0000000..6da645a --- /dev/null +++ b/lib/common/isblank.s @@ -0,0 +1,23 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isblank (int c); +; +; cc65 (and GNU) extension. +; + + .export _isblank + .include "ctype.inc" + +_isblank: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_SPACE_TAB ; Mask blank bit + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/iscntrl.s b/lib/common/iscntrl.s new file mode 100644 index 0000000..d94fddc --- /dev/null +++ b/lib/common/iscntrl.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int iscntrl (int c); +; + + .export _iscntrl + .include "ctype.inc" + +_iscntrl: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_CTRL ; Mask control character bit + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isdigit.s b/lib/common/isdigit.s new file mode 100644 index 0000000..339fef6 --- /dev/null +++ b/lib/common/isdigit.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isdigit (int c); +; + + .export _isdigit + .include "ctype.inc" + +_isdigit: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_DIGIT ; Mask digit bit + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isgraph.s b/lib/common/isgraph.s new file mode 100644 index 0000000..e52ae34 --- /dev/null +++ b/lib/common/isgraph.s @@ -0,0 +1,22 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isgraph (int c); +; + + .export _isgraph + .include "ctype.inc" + +_isgraph: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + eor #CT_CTRL_SPACE ; NOT control and NOT space + and #CT_CTRL_SPACE ; Mask character bits + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/islower.s b/lib/common/islower.s new file mode 100644 index 0000000..0078366 --- /dev/null +++ b/lib/common/islower.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int islower (int c); +; + + .export _islower + .include "ctype.inc" + +_islower: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_LOWER ; Mask lower char bit + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isprint.s b/lib/common/isprint.s new file mode 100644 index 0000000..956b54b --- /dev/null +++ b/lib/common/isprint.s @@ -0,0 +1,22 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isprint (int c); +; + + .export _isprint + .include "ctype.inc" + +_isprint: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + eor #CT_CTRL ; NOT a control char + and #CT_CTRL ; Mask control char bit + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/ispunct.s b/lib/common/ispunct.s new file mode 100644 index 0000000..380cf38 --- /dev/null +++ b/lib/common/ispunct.s @@ -0,0 +1,22 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int ispunct (int c); +; + + .export _ispunct + .include "ctype.inc" + +_ispunct: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + eor #CT_NOT_PUNCT ; NOT (space | control | digit | alpha) + and #CT_NOT_PUNCT ; Mask relevant bits + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isspace.s b/lib/common/isspace.s new file mode 100644 index 0000000..67530c9 --- /dev/null +++ b/lib/common/isspace.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isspace (int c); +; + + .export _isspace + .include "ctype.inc" + +_isspace: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #(CT_SPACE | CT_OTHER_WS) ; Mask space bits + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isupper.s b/lib/common/isupper.s new file mode 100644 index 0000000..b9d53a6 --- /dev/null +++ b/lib/common/isupper.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isupper (int c); +; + + .export _isupper + .include "ctype.inc" + +_isupper: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_UPPER ; Mask upper char bit + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/isxdigit.s b/lib/common/isxdigit.s new file mode 100644 index 0000000..50146e8 --- /dev/null +++ b/lib/common/isxdigit.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int isxdigit (int c); +; + + .export _isxdigit + .include "ctype.inc" + +_isxdigit: + cpx #$00 ; Char range ok? + bne @L1 ; Jump if no + tay + lda __ctype,y ; Get character classification + and #CT_XDIGIT ; Mask xdigit bit + rts + +@L1: lda #$00 ; Return false + tax + rts + diff --git a/lib/common/itoa.s b/lib/common/itoa.s new file mode 100644 index 0000000..37544c4 --- /dev/null +++ b/lib/common/itoa.s @@ -0,0 +1,146 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; char* itoa (int value, char* s, int radix); +; char* utoa (unsigned value, char* s, int radix); +; + + .export _itoa, _utoa + .import addysp1 + .import __hextab + .importzp sp, sreg, ptr2, ptr3, tmp1 + +.rodata +specval: + .byte '-', '3', '2', '7', '6', '8', 0 +.code + +; +; Common subroutine to pop the parameters and put them into core +; + +dopop: sta tmp1 ; will loose high byte + ldy #0 + lda (sp),y + sta ptr2 + sta ptr3 + iny + lda (sp),y + sta ptr2+1 + sta ptr3+1 + iny + lda (sp),y + sta sreg + iny + lda (sp),y + sta sreg+1 + jmp addysp1 ; Bump stack pointer + +; +; itoa +; + +_itoa: jsr dopop ; pop the arguments + +; We must handle $8000 in a special way, since it is the only negative +; number that has no positive 16-bit counterpart + + ldy tmp1 ; get radix + cpy #10 + bne utoa + cmp #$00 + bne L2 + cpx #$80 + bne L2 + + ldy #6 +L1: lda specval,y ; copy -32768 + sta (ptr2),y + dey + bpl L1 + jmp L10 + +; Check if the value is negative. If so, write a - sign and negate the +; number. + +L2: lda sreg+1 ; get high byte + bpl utoa + lda #'-' + ldy #0 + sta (ptr2),y ; store sign + inc ptr2 + bne L3 + inc ptr2+1 + +L3: lda sreg + eor #$FF + clc + adc #$01 + sta sreg + lda sreg+1 + eor #$FF + adc #$00 + sta sreg+1 + jmp utoa + +; +; utoa +; + +_utoa: jsr dopop ; pop the arguments + +; Convert to string by dividing and push the result onto the stack + +utoa: lda #$00 + pha ; sentinel + +; Divide sreg/tmp1 -> sreg, remainder in a + +L5: ldy #16 ; 16 bit + lda #0 ; remainder +L6: asl sreg + rol sreg+1 + rol a + cmp tmp1 + bcc L7 + sbc tmp1 + inc sreg +L7: dey + bne L6 + + tay ; get remainder into y + lda __hextab,y ; get hex character + pha ; save char value on stack + + lda sreg + ora sreg+1 + bne L5 + +; Get the characters from the stack into the string + + ldy #0 +L9: pla + sta (ptr2),y + beq L10 ; jump if sentinel + iny + bne L9 ; jump always + +; Done! Return the target string + +L10: lda ptr3 + ldx ptr3+1 + rts + + + + + + + + + + + + + + diff --git a/lib/common/memchr.s b/lib/common/memchr.s new file mode 100644 index 0000000..c455637 --- /dev/null +++ b/lib/common/memchr.s @@ -0,0 +1,57 @@ +; +; Ullrich von Bassewitz, 2003-05-05 +; +; void* __fastcall__ memchr (const void* p, int c, size_t n); +; + + .export _memchr + .import popax, return0 + .importzp ptr1, ptr2 + + +.proc _memchr + + eor #$FF + sta ptr2 + txa + eor #$FF + sta ptr2+1 ; Save ones complement of n + jsr popax ; get c + pha + jsr popax ; get p + sta ptr1 + stx ptr1+1 + + ldy #$00 + pla ; Get c + ldx ptr2 ; Use X as low counter byte + +L1: inx + beq L3 +L2: cmp (ptr1),y + beq found + iny + bne L1 + inc ptr1+1 + bne L1 ; Branch always + +L3: inc ptr2+1 ; Bump counter high byte + bne L2 + +; Not found, return NULL + +notfound: + jmp return0 + +; Found, return pointer to char + +found: ldx ptr1+1 ; get high byte of pointer + tya ; low byte offset + clc + adc ptr1 + bcc L9 + inx +L9: rts + +.endproc + diff --git a/lib/common/memcmp.s b/lib/common/memcmp.s new file mode 100644 index 0000000..5d82aa6 --- /dev/null +++ b/lib/common/memcmp.s @@ -0,0 +1,72 @@ +; +; Ullrich von Bassewitz, 15.09.2000 +; +; int memcmp (const void* p1, const void* p2, size_t count); +; + + .export _memcmp + .import popax, return0 + .importzp ptr1, ptr2, ptr3 + +_memcmp: + +; Calculate (-count-1) and store it into ptr3. This is some overhead here but +; saves time in the compare loop + + eor #$FF + sta ptr3 + txa + eor #$FF + sta ptr3+1 + +; Get the pointer parameters + + jsr popax ; Get p2 + sta ptr2 + stx ptr2+1 + jsr popax ; Get p1 + sta ptr1 + stx ptr1+1 + +; Loop initialization + + ldx ptr3 ; Load low counter byte into X + ldy #$00 ; Initialize pointer + +; Head of compare loop: Test for the end condition + +Loop: inx ; Bump low byte of (-count-1) + beq BumpHiCnt ; Jump on overflow + +; Do the compare + +Comp: lda (ptr1),y + cmp (ptr2),y + bne NotEqual ; Jump if bytes not equal + +; Bump the pointers + + iny ; Increment pointer + bne Loop + inc ptr1+1 ; Increment high bytes + inc ptr2+1 + bne Loop ; Branch always (pointer wrap is illegal) + +; Entry on low counter byte overflow + +BumpHiCnt: + inc ptr3+1 ; Bump high byte of (-count-1) + bne Comp ; Jump if not done + jmp return0 ; Count is zero, areas are identical + +; Not equal, check which one is greater + +NotEqual: + bcs Greater + ldx #$FF ; Make result negative + rts + +Greater: + ldx #$01 ; Make result positive + rts + diff --git a/lib/common/memcpy.s b/lib/common/memcpy.s new file mode 100644 index 0000000..d432ffa --- /dev/null +++ b/lib/common/memcpy.s @@ -0,0 +1,80 @@ +; +; Ullrich von Bassewitz, 2003-08-20 +; Performance increase (about 20%) by +; Christian Krueger, 2009-09-13 +; +; void* __fastcall__ memcpy (void* dest, const void* src, size_t n); +; +; NOTE: This function contains entry points for memmove, which will ressort +; to memcpy for an upwards copy. Don't change this module without looking +; at memmove! +; + + .export _memcpy, memcpy_upwards, memcpy_getparams + .import popax + .importzp sp, ptr1, ptr2, ptr3 + +; ---------------------------------------------------------------------- +_memcpy: + jsr memcpy_getparams + +memcpy_upwards: ; assert Y = 0 + ldx ptr3+1 ; Get high byte of n + beq L2 ; Jump if zero + +L1: .repeat 2 ; Unroll this a bit to make it faster... + lda (ptr1),Y ; copy a byte + sta (ptr2),Y + iny + .endrepeat + bne L1 + inc ptr1+1 + inc ptr2+1 + dex ; Next 256 byte block + bne L1 ; Repeat if any + + ; the following section could be 10% faster if we were able to copy + ; back to front - unfortunately we are forced to copy strict from + ; low to high since this function is also used for + ; memmove and blocks could be overlapping! + ; { +L2: ; assert Y = 0 + ldx ptr3 ; Get the low byte of n + beq done ; something to copy + +L3: lda (ptr1),Y ; copy a byte + sta (ptr2),Y + iny + dex + bne L3 + + ; } + +done: jmp popax ; Pop ptr and return as result + +; ---------------------------------------------------------------------- +; Get the parameters from stack as follows: +; +; size --> ptr3 +; src --> ptr1 +; dest --> ptr2 +; First argument (dest) will remain on stack and is returned in a/x! + +memcpy_getparams: ; IMPORTANT! Function has to leave with Y=0! + sta ptr3 + stx ptr3+1 ; save n to ptr3 + + jsr popax + sta ptr1 + stx ptr1+1 ; save src to ptr1 + + ; save dest to ptr2 + ldy #1 ; (direct stack access is three cycles faster + ; (total cycle count with return)) + lda (sp),y + tax + stx ptr2+1 ; save high byte of ptr2 + dey ; Y = 0 + lda (sp),y ; Get ptr2 low + sta ptr2 + rts diff --git a/lib/common/memmove.s b/lib/common/memmove.s new file mode 100644 index 0000000..983b972 --- /dev/null +++ b/lib/common/memmove.s @@ -0,0 +1,84 @@ +; +; Ullrich von Bassewitz, 2003-08-20 +; Performance increase (about 20%) by +; Christian Krueger, 2009-09-13 +; +; void* __fastcall__ memmove (void* dest, const void* src, size_t size); +; +; NOTE: This function uses entry points from memcpy! +; + + .export _memmove + .import memcpy_getparams, memcpy_upwards, popax + .importzp ptr1, ptr2, ptr3, ptr4, tmp1 + + .macpack generic + .macpack longbranch + +; ---------------------------------------------------------------------- +_memmove: + jsr memcpy_getparams + +; Check for the copy direction. If dest < src, we must copy upwards (start at +; low addresses and increase pointers), otherwise we must copy downwards +; (start at high addresses and decrease pointers). + + sec + sbc ptr1 + txa + sbc ptr1+1 + jcc memcpy_upwards ; Branch if dest < src (upwards copy) + +; Copy downwards. Adjust the pointers to the end of the memory regions. + + lda ptr1+1 + add ptr3+1 + sta ptr1+1 + + lda ptr2+1 + add ptr3+1 + sta ptr2+1 + +; handle fractions of a page size first + + ldy ptr3 ; count, low byte + bne @entry ; something to copy? + beq PageSizeCopy ; here like bra... + +@copyByte: + lda (ptr1),y + sta (ptr2),y +@entry: + dey + bne @copyByte + lda (ptr1),y ; copy remaining byte + sta (ptr2),y + +PageSizeCopy: ; assert Y = 0 + ldx ptr3+1 ; number of pages + beq done ; none? -> done + +@initBase: + dec ptr1+1 ; adjust base... + dec ptr2+1 + dey ; in entry case: 0 -> FF + lda (ptr1),y ; need to copy this 'intro byte' + sta (ptr2),y ; to 'land' later on Y=0! (as a result of the '.repeat'-block!) + dey ; FF ->FE +@copyBytes: + .repeat 2 ; Unroll this a bit to make it faster... + lda (ptr1),y + sta (ptr2),y + dey + .endrepeat +@copyEntry: ; in entry case: 0 -> FF + bne @copyBytes + lda (ptr1),y ; Y = 0, copy last byte + sta (ptr2),y + dex ; one page to copy less + bne @initBase ; still a page to copy? + +; Done, return dest + +done: jmp popax ; Pop ptr and return as result + diff --git a/lib/common/memset.s b/lib/common/memset.s new file mode 100644 index 0000000..fcdbd98 --- /dev/null +++ b/lib/common/memset.s @@ -0,0 +1,95 @@ +; +; void* __fastcall__ memset (void* ptr, int c, size_t n); +; void* __fastcall__ _bzero (void* ptr, size_t n); +; void __fastcall__ bzero (void* ptr, size_t n); +; +; Ullrich von Bassewitz, 29.05.1998 +; Performance increase (about 20%) by +; Christian Krueger, 12.09.2009 +; +; NOTE: bzero will return it's first argument as memset does. It is no problem +; to declare the return value as void, since it may be ignored. _bzero +; (note the leading underscore) is declared with the proper return type, +; because the compiler will replace memset by _bzero if the fill value +; is zero, and the optimizer looks at the return type to see if the value +; in a/x is of any use. +; + + .export _memset, _bzero, __bzero + .import popax + .importzp sp, ptr1, ptr2, ptr3 + +_bzero: +__bzero: + sta ptr3 + stx ptr3+1 ; Save n + ldx #0 ; Fill with zeros + beq common + +_memset: + sta ptr3 ; Save n + stx ptr3+1 + jsr popax ; Get c + tax + +; Common stuff for memset and bzero from here + +common: ; Fill value is in X! + ldy #1 + lda (sp),y + sta ptr1+1 ; save high byte of ptr + dey ; Y = 0 + lda (sp),y ; Get ptr + sta ptr1 + + lsr ptr3+1 ; divide number of + ror ptr3 ; bytes by two to increase + bcc evenCount ; speed (ptr3 = ptr3/2) +oddCount: + ; y is still 0 here + txa ; restore fill value + sta (ptr1),y ; save value and increase + inc ptr1 ; dest. pointer + bne evenCount + inc ptr1+1 +evenCount: + lda ptr1 ; build second pointer section + clc + adc ptr3 ; ptr2 = ptr1 + (length/2) <- ptr3 + sta ptr2 + lda ptr1+1 + adc ptr3+1 + sta ptr2+1 + + txa ; restore fill value + ldx ptr3+1 ; Get high byte of n + beq L2 ; Jump if zero + +; Set 256/512 byte blocks + ; y is still 0 here +L1: .repeat 2 ; Unroll this a bit to make it faster + sta (ptr1),y ; Set byte in lower section + sta (ptr2),y ; Set byte in upper section + iny + .endrepeat + bne L1 + inc ptr1+1 + inc ptr2+1 + dex ; Next 256 byte block + bne L1 ; Repeat if any + +; Set the remaining bytes if any + +L2: ldy ptr3 ; Get the low byte of n + bne L3 ; something to set? + jmp popax ; no -> Pop ptr and return as result + +L3a: sta (ptr1),y ; set bytes in low + sta (ptr2),y ; and high section +L3: dey + bne L3a + sta (ptr1),y ; Set remaining byte(s) + sta (ptr2),y + jmp popax ; Pop ptr and return as result + + diff --git a/lib/common/strcat.s b/lib/common/strcat.s new file mode 100644 index 0000000..8640626 --- /dev/null +++ b/lib/common/strcat.s @@ -0,0 +1,55 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; char* strcat (char* dest, const char* src); +; + + .export _strcat + .import popax + .importzp ptr1, ptr2, tmp3 + +_strcat: + sta ptr1 ; Save src + stx ptr1+1 + jsr popax ; Get dest + sta ptr2 + stx ptr2+1 + sta tmp3 ; Remember for function return + ldy #0 + +; find end of dest + +sc1: lda (ptr2),y + beq sc2 + iny + bne sc1 + inc ptr2+1 + bne sc1 + +; end found, get offset in y into pointer + +sc2: tya + clc + adc ptr2 + sta ptr2 + bcc sc3 + inc ptr2+1 + +; copy src + +sc3: ldy #0 +sc4: lda (ptr1),y + sta (ptr2),y + beq sc5 + iny + bne sc4 + inc ptr1+1 + inc ptr2+1 + bne sc4 + +; done, return pointer to dest + +sc5: lda tmp3 ; X does still contain high byte + rts + + diff --git a/lib/common/strchr.s b/lib/common/strchr.s new file mode 100644 index 0000000..d1761b9 --- /dev/null +++ b/lib/common/strchr.s @@ -0,0 +1,48 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; const char* strchr (const char* s, int c); +; + + .export _strchr + .import popax + .importzp ptr1, tmp1 + +_strchr: + sta tmp1 ; Save c + jsr popax ; get s + sta ptr1 + stx ptr1+1 + ldy #0 + +Loop: lda (ptr1),y ; Get next char + beq EOS ; Jump on end of string + cmp tmp1 ; Found? + beq Found ; Jump if yes + iny + bne Loop + inc ptr1+1 + bne Loop ; Branch always + +; End of string. Check if we're searching for the terminating zero + +EOS: lda tmp1 ; Get the char we're searching for + bne NotFound ; Jump if not searching for terminator + +; Found. Calculate pointer to c. + +Found: ldx ptr1+1 ; Load high byte of pointer + tya ; Low byte offset + clc + adc ptr1 + bcc Found1 + inx +Found1: rts + +; Not found, return NULL + +NotFound: + lda #0 + tax + rts + diff --git a/lib/common/strcmp.s b/lib/common/strcmp.s new file mode 100644 index 0000000..db85d9b --- /dev/null +++ b/lib/common/strcmp.s @@ -0,0 +1,35 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; int strcmp (const char* s1, const char* s2); +; + + .export _strcmp + .import popax + .importzp ptr1, ptr2 + +_strcmp: + sta ptr2 ; Save s2 + stx ptr2+1 + jsr popax ; Get s1 + sta ptr1 + stx ptr1+1 + ldy #0 + +loop: lda (ptr1),y + cmp (ptr2),y + bne L1 + tax ; end of strings? + beq L3 + iny + bne loop + inc ptr1+1 + inc ptr2+1 + bne loop + +L1: bcs L2 + ldx #$FF + rts + +L2: ldx #$01 +L3: rts diff --git a/lib/common/strcoll.s b/lib/common/strcoll.s new file mode 100644 index 0000000..664d1f4 --- /dev/null +++ b/lib/common/strcoll.s @@ -0,0 +1,13 @@ +; +; Ullrich von Bassewitz, 11.12.1998 +; +; int strcoll (const char* s1, const char* s2); +; +; Since we don't have locales, this function is equivalent to strcmp. +; + + .export _strcoll + .import _strcmp + +_strcoll = _strcmp + diff --git a/lib/common/strcpy.s b/lib/common/strcpy.s new file mode 100644 index 0000000..a48f0e3 --- /dev/null +++ b/lib/common/strcpy.s @@ -0,0 +1,30 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; char* strcpy (char* dest, const char* src); +; + + .export _strcpy + .import popax + .importzp ptr1, ptr2 + +_strcpy: + sta ptr1 ; Save src + stx ptr1+1 + jsr popax ; Get dest + sta ptr2 + stx ptr2+1 + ldy #$00 + +L1: lda (ptr1),y + sta (ptr2),y + beq L9 + iny + bne L1 + inc ptr1+1 + inc ptr2+1 + bne L1 + +L9: lda ptr2 ; X still contains high byte + rts + diff --git a/lib/common/strcspn.s b/lib/common/strcspn.s new file mode 100644 index 0000000..6c12561 --- /dev/null +++ b/lib/common/strcspn.s @@ -0,0 +1,54 @@ +; +; Ullrich von Bassewitz, 11.06.1998 +; +; size_t strcspn (const char* s1, const char* s2); +; + + .export _strcspn + .import popax + .importzp ptr1, ptr2, tmp1, tmp2, tmp3 + +_strcspn: + sta ptr2 ; Save s2 + stx ptr2+1 + jsr popax ; Get s1 + sta ptr1 + stx ptr1+1 + ldx #0 ; low counter byte + stx tmp1 ; high counter byte + ldy #$00 + +L1: lda (ptr1),y ; get next char from s1 + beq L6 ; jump if done + sta tmp2 ; save char + iny + bne L2 + inc ptr1+1 +L2: sty tmp3 ; save index into s1 + + ldy #0 ; get index into s2 +L3: lda (ptr2),y ; + beq L4 ; jump if done + cmp tmp2 + beq L6 + iny + bne L3 + +; The character was not found in s2. Increment the counter and start over + +L4: ldy tmp3 ; reload index + inx + bne L1 + inc tmp1 + bne L1 + +; The character was found, or we reached the end of s1. Return count of +; characters + +L6: txa ; get low counter byte + ldx tmp1 ; get high counter byte + rts + + + + diff --git a/lib/common/strdup.s b/lib/common/strdup.s new file mode 100644 index 0000000..57cf914 --- /dev/null +++ b/lib/common/strdup.s @@ -0,0 +1,85 @@ +; +; Ullrich von Bassewitz, 18.07.2000 +; +; char* __fastcall__ strdup (const char* S); +; +; Note: The code knowns which zero page locations are used by malloc. +; + + .importzp sp, tmp1, ptr4 + .import pushax, decsp4, incsp4 + .import _strlen, _malloc, _memcpy + .export _strdup + + .macpack cpu + .macpack generic + +_strdup: + +; Since we need some place to store the intermediate results, allocate a +; stack frame. To make this somewhat more efficient, create the stackframe +; as needed for the final call to the memcpy function. + + pha ; decsp will destroy A (but not X) + jsr decsp4 ; Target/source + +; Store the pointer into the source slot + + ldy #1 + txa + sta (sp),y + pla +.if (.cpu .bitand CPU_ISET_65SC02) + sta (sp) +.else + dey + sta (sp),y +.endif + +; Get length of S (which is still in a/x) + + jsr _strlen + +; Calculate strlen(S)+1 (the space needed) + + add #1 + bcc @L1 + inx + +; Save the space we're about to allocate in ptr4 + +@L1: sta ptr4 + stx ptr4+1 + +; Allocate memory. _malloc will not use ptr4 + + jsr _malloc + +; Store the result into the target stack slot + + ldy #2 + sta (sp),y ; Store low byte + sta tmp1 + txa ; Get high byte + iny + sta (sp),y ; Store high byte + +; Check for a NULL pointer + + ora tmp1 + beq OutOfMemory + +; Copy the string. memcpy will return the target string which is exactly +; what we need here. It will also drop the allocated stack frame. + + lda ptr4 + ldx ptr4+1 ; Load size + jmp _memcpy ; Copy string, drop stackframe + +; Out of memory, return NULL (A = 0) + +OutOfMemory: + tax + jmp incsp4 ; Drop stack frame + + diff --git a/lib/common/strerror.s b/lib/common/strerror.s new file mode 100644 index 0000000..98a5725 --- /dev/null +++ b/lib/common/strerror.s @@ -0,0 +1,35 @@ +; +; Ullrich von Bassewitz, 17.05.2000 +; +; char* __fastcall__ strerror (int errcode); +; /* Map an error number to an error message */ +; + + .export _strerror + .import __sys_errlist + + .include "errno.inc" + +_strerror: + cpx #$00 ; High byte must be zero + bne @L1 ; Jump if invalid error + cmp #EMAX ; Valid error code (map EUNKNOWN to 0)? + bcc @L2 ; Jump if ok + +; The given error code is invalid + +@L1: lda #EINVAL ; = 0 + sta __errno+1 +; lda #$00 ; A contains zero: "Unknown error" + +; Load the pointer to the error message and return + +@L2: asl a ; * 2 + tay + ldx __sys_errlist+1,y + lda __sys_errlist,y + rts + + diff --git a/lib/common/strftime.c b/lib/common/strftime.c new file mode 100644 index 0000000..803c3d8 --- /dev/null +++ b/lib/common/strftime.c @@ -0,0 +1,224 @@ +/*****************************************************************************/ +/* */ +/* strftime.c */ +/* */ +/* Convert broken down time to a string in a user specified format */ +/* */ +/* */ +/* */ +/* (C) 2002 Ullrich von Bassewitz */ +/* Wacholderweg 14 */ +/* D-70597 Stuttgart */ +/* EMail: uz@musoftware.de */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include +#include + + + +/* Use static local variables for speed */ +#pragma staticlocals (on); + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +size_t __fastcall__ strftime (char* buf, size_t bufsize, const char* format, + const struct tm* tm) +{ + static const char* days[7] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; + static const char* months[12] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; + + unsigned count; + unsigned len; + char c; + char arg[40]; + const char* argptr; + + /* Copy until we reach the end of the format string or a format specifier */ + count = 0; + while (1) { + if (count >= bufsize) { + /* Not enough buffer space available */ + return 0; + } + if ((c = *format++) == '\0') { + /* End of format string reached */ + *buf = '\0'; + return count; + } + if (c == '%') { + /* Format specifier */ + argptr = arg; + switch (*format++) { + + case '%': + arg[0] = '%'; + arg[1] = '\0'; + break; + + case 'A': + argptr = days[tm->tm_wday]; + break; + + case 'B': + argptr = months[tm->tm_mon]; + break; + + case 'D': + sprintf (arg, "%02d/%02d/%02d", tm->tm_mon + 1, + tm->tm_mday, tm->tm_year % 100); + break; + + case 'F': + /* C99 */ + sprintf (arg, "%04d-%02d-%02d", tm->tm_year + 1900, + tm->tm_mon + 1, tm->tm_mday); + break; + + case 'H': + sprintf (arg, "%02d", tm->tm_hour); + break; + + case 'I': + sprintf (arg, "%02d", tm->tm_hour % 12); + break; + + case 'M': + sprintf (arg, "%02d", tm->tm_min); + break; + + case 'P': + /* GNU extension */ + argptr = (tm->tm_hour >= 12)? "pm" : "am"; + break; + + case 'S': + sprintf (arg, "%02d", tm->tm_sec); + break; + + case 'U': + sprintf (arg, "%02d", (tm->tm_yday + 7 - tm->tm_wday) / 7); + break; + + case 'W': + sprintf (arg, "%02d", + (tm->tm_yday + 7 - (tm->tm_wday? tm->tm_wday - 1 : 6)) / 7); + break; + + case 'X': + sprintf (arg, "%02d:%02d:%02d", tm->tm_hour, + tm->tm_min, tm->tm_sec); + break; + + case 'Y': + sprintf (arg, "%4d", tm->tm_year + 1900); + break; + + case 'Z': + argptr = tm->tm_isdst? _tz.dstname : _tz.tzname; + break; + + case 'a': + sprintf (arg, "%.3s", days[tm->tm_wday]); + break; + + case 'b': + sprintf (arg, "%.3s", months[tm->tm_mon]); + break; + + case 'c': + sprintf (arg, "%.3s %.3s%3d %02d:%02d:%02d %d", + days[tm->tm_wday], months[tm->tm_mon], + tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec, tm->tm_year + 1900); + break; + + case 'd': + sprintf (arg, "%02d", tm->tm_mday); + break; + + case 'j': + sprintf (arg, "%03d", tm->tm_yday + 1); + break; + + case 'm': + sprintf (arg, "%02d", tm->tm_mon + 1); + break; + + case 'p': + argptr = (tm->tm_hour >= 12)? "PM" : "AM"; + break; + + case 'w': + sprintf (arg, "%d", tm->tm_wday); + break; + + case 'x': + sprintf (arg, "%04d-%02d-%02d", tm->tm_year + 1900, + tm->tm_mon + 1, tm->tm_mday); + break; + + case 'y': + sprintf (arg, "%02d", tm->tm_year % 100); + break; + + default: + /* Unknown format specifier, convert to empty string */ + arg[0] = '\0'; + break; + } + + /* Check if we have enough space to copy the argument string */ + len = strlen (argptr); + count += len; + if (count < bufsize) { + memcpy (buf, argptr, len); + buf += len; + } + + } else { + + /* No format character, just copy */ + *buf++ = c; + ++count; + + } + } +} + + + diff --git a/lib/common/stricmp.s b/lib/common/stricmp.s new file mode 100644 index 0000000..03638c8 --- /dev/null +++ b/lib/common/stricmp.s @@ -0,0 +1,60 @@ +; +; Ullrich von Bassewitz, 03.06.1998 +; +; int stricmp (const char* s1, const char* s2); /* DOS way */ +; int strcasecmp (const char* s1, const char* s2); /* UNIX way */ +; + + .export _stricmp, _strcasecmp + .import popax + .import __ctype + .importzp ptr1, ptr2, tmp1 + + .include "ctype.inc" + +_stricmp: +_strcasecmp: + sta ptr2 ; Save s2 + stx ptr2+1 + jsr popax ; get s1 + sta ptr1 + stx ptr1+1 + ldy #0 + +loop: lda (ptr2),y ; get char from second string + tax + lda __ctype,x ; get character classification + and #CT_LOWER ; lower case char? + beq L1 ; jump if no + txa ; get character back + clc + adc #<('A'-'a') ; make upper case char + tax ; +L1: stx tmp1 ; remember upper case equivalent + + lda (ptr1),y ; get character from first string + tax + lda __ctype,x ; get character classification + and #CT_LOWER ; lower case char? + beq L2 ; jump if no + txa ; get character back + clc + adc #<('A'-'a') ; make upper case char + tax + +L2: cpx tmp1 ; compare characters + bne L3 + txa ; end of strings? + beq L5 ; a/x both zero + iny + bne loop + inc ptr1+1 + inc ptr2+1 + bne loop + +L3: bcs L4 + ldx #$FF + rts + +L4: ldx #$01 +L5: rts diff --git a/lib/common/strlen.s b/lib/common/strlen.s new file mode 100644 index 0000000..6cef2ea --- /dev/null +++ b/lib/common/strlen.s @@ -0,0 +1,26 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; int strlen (const char* s); +; + + .export _strlen + .importzp ptr1 + +_strlen: + sta ptr1 ; Save s + stx ptr1+1 + ldx #0 ; YX used as counter + ldy #0 + +L1: lda (ptr1),y + beq L9 + iny + bne L1 + inc ptr1+1 + inx + bne L1 + +L9: tya ; get low byte of counter, hi's all set + rts + diff --git a/lib/common/strlower.s b/lib/common/strlower.s new file mode 100644 index 0000000..b76133c --- /dev/null +++ b/lib/common/strlower.s @@ -0,0 +1,47 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; char* strlower (char* s); +; char* strlwr (char* s); +; +; Non-ANSI +; + + .export _strlower, _strlwr + .import popax + .import __ctype + .importzp ptr1, ptr2 + + .include "ctype.inc" + +_strlower: +_strlwr: + sta ptr1 ; Save s (working copy) + stx ptr1+1 + sta ptr2 + sta ptr2+2 ; save function result + ldy #0 + +loop: lda (ptr1),y ; get character + beq L9 ; jump if done + tax + lda __ctype,x ; get character classification + and #CT_UPPER ; upper case char? + beq L1 ; jump if no + txa ; get character back into accu + sec + sbc #<('A'-'a') ; make lower case char + sta (ptr1),y ; store back +L1: iny ; next char + bne loop + inc ptr1+1 ; handle offset overflow + bne loop ; branch always + +; Done, return the argument string + +L9: lda ptr2 + ldx ptr2+1 + rts + + + diff --git a/lib/common/strncat.s b/lib/common/strncat.s new file mode 100644 index 0000000..5171ad9 --- /dev/null +++ b/lib/common/strncat.s @@ -0,0 +1,72 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; char* strncat (char* dest, const char* src, size_t n); +; + + .export _strncat + .import popax + .importzp ptr1, ptr2, ptr3, tmp1, tmp2 + +_strncat: + eor #$FF ; one's complement to count upwards + sta tmp1 + txa + eor #$FF + sta tmp2 + jsr popax ; get src + sta ptr1 + stx ptr1+1 + jsr popax ; get dest + sta ptr2 + stx ptr2+1 + sta ptr3 ; remember for function return + stx ptr3+1 + ldy #0 + +; find end of dest + +L1: lda (ptr2),y + beq L2 + iny + bne L1 + inc ptr2+1 + bne L1 + +; end found, get offset in y into pointer + +L2: tya + clc + adc ptr2 + sta ptr2 + bcc L3 + inc ptr2+1 + +; copy src. We've put the ones complement of the count into the counter, so +; we'll increment the counter on top of the loop + +L3: ldy #0 + ldx tmp1 ; low counter byte + +L4: inx + bne L5 + inc tmp2 + beq L6 ; jump if done +L5: lda (ptr1),y + sta (ptr2),y + beq L7 + iny + bne L4 + inc ptr1+1 + inc ptr2+1 + bne L4 + +; done, set the trailing zero and return pointer to dest + +L6: lda #0 + sta (ptr2),y +L7: lda ptr3 + ldx ptr3+1 + rts + + diff --git a/lib/common/strncmp.s b/lib/common/strncmp.s new file mode 100644 index 0000000..3af44fa --- /dev/null +++ b/lib/common/strncmp.s @@ -0,0 +1,81 @@ +; +; Ullrich von Bassewitz, 25.05.2000 +; +; int strncmp (const char* s1, const char* s2, unsigned n); +; + + .export _strncmp + .import popax + .importzp ptr1, ptr2, ptr3 + + +_strncmp: + +; Convert the given counter value in a/x from a downward counter into an +; upward counter, so we can increment the counter in the loop below instead +; of decrementing it. This adds some overhead now, but is cheaper than +; executing a more complex test in each iteration of the loop. We do also +; correct the value by one, so we can do the test on top of the loop. + + eor #$FF + sta ptr3 + txa + eor #$FF + sta ptr3+1 + +; Get the remaining arguments + + jsr popax ; get s2 + sta ptr2 + stx ptr2+1 + jsr popax ; get s1 + sta ptr1 + stx ptr1+1 + +; Loop setup + + ldy #0 + +; Start of compare loop. Check the counter. + +Loop: inc ptr3 + beq IncHi ; Increment high byte + +; Compare a byte from the strings + +Comp: lda (ptr1),y + cmp (ptr2),y + bne NotEqual ; Jump if strings different + tax ; End of strings? + beq Equal1 ; Jump if EOS reached, a/x == 0 + +; Increment the pointers + + iny + bne Loop + inc ptr1+1 + inc ptr2+1 + bne Loop ; Branch always + +; Increment hi byte + +IncHi: inc ptr3+1 + bne Comp ; Jump if counter not zero + +; Exit code if strings are equal. a/x not set + +Equal: lda #$00 + tax +Equal1: rts + +; Exit code if strings not equal + +NotEqual: + bcs L1 + ldx #$FF ; Make result negative + rts + +L1: ldx #$01 ; Make result positive + rts + + diff --git a/lib/common/strncpy.s b/lib/common/strncpy.s new file mode 100644 index 0000000..21de3a1 --- /dev/null +++ b/lib/common/strncpy.s @@ -0,0 +1,69 @@ +; +; Ullrich von Bassewitz, 2003-05-04 +; +; char* __fastcall__ strncpy (char* dest, const char* src, unsigned size); +; + + .export _strncpy + .import popax + .importzp ptr1, ptr2, tmp1, tmp2, tmp3 + +.proc _strncpy + + eor #$FF + sta tmp1 + txa + eor #$FF + sta tmp2 ; Store -size - 1 + + jsr popax ; get src + sta ptr1 + stx ptr1+1 + jsr popax ; get dest + sta ptr2 + stx ptr2+1 + stx tmp3 ; remember for function return + +; Copy src -> dest up to size bytes + + ldx tmp1 ; Load low byte of ones complement of size + ldy #$00 +L1: inx + bne L2 + inc tmp2 + beq L9 + +L2: lda (ptr1),y ; Copy one character + sta (ptr2),y + beq L5 ; Bail out if terminator reached (A = 0) + iny + bne L1 + inc ptr1+1 + inc ptr2+1 ; Bump high bytes + bne L1 ; Branch always + +; Fill the remaining bytes. + +L3: inx ; Counter low byte + beq L6 ; Branch on overflow +L4: sta (ptr2),y ; Clear one byte +L5: iny ; Bump pointer + bne L3 + inc ptr2+1 ; Bump high byte + bne L3 ; Branch always + +; Bump the counter high byte + +L6: inc tmp2 + bne L4 + +; Done, return dest + +L9: lda ptr2 ; Get low byte + ldx tmp3 ; Get unchanged high byte + rts + +.endproc + + + diff --git a/lib/common/strnicmp.s b/lib/common/strnicmp.s new file mode 100644 index 0000000..38bd21c --- /dev/null +++ b/lib/common/strnicmp.s @@ -0,0 +1,103 @@ +; +; Christian Groessler, 10.02.2009 +; derived from strncmp.s and stricmp.s +; +; int __fastcall__ strnicmp (const char* s1, const char* s2, size_t count); +; int __fastcall__ strncasecmp (const char* s1, const char* s2, size_t count); +; + + .export _strnicmp, _strncasecmp + .import popax, __ctype + .importzp ptr1, ptr2, ptr3, tmp1 + + .include "ctype.inc" + +_strnicmp: +_strncasecmp: + +; Convert the given counter value in a/x from a downward counter into an +; upward counter, so we can increment the counter in the loop below instead +; of decrementing it. This adds some overhead now, but is cheaper than +; executing a more complex test in each iteration of the loop. We do also +; correct the value by one, so we can do the test on top of the loop. + + eor #$FF + sta ptr3 + txa + eor #$FF + sta ptr3+1 + +; Get the remaining arguments + + jsr popax ; get s2 + sta ptr2 + stx ptr2+1 + jsr popax ; get s1 + sta ptr1 + stx ptr1+1 + +; Loop setup + + ldy #0 + +; Start of compare loop. Check the counter. + +Loop: inc ptr3 + beq IncHi ; Increment high byte + +; Compare a byte from the strings + +Comp: lda (ptr2),y + tax + lda __ctype,x ; get character classification + and #CT_LOWER ; lower case char? + beq L1 ; jump if no + txa ; get character back + sec + sbc #<('a'-'A') ; make upper case char + tax ; +L1: stx tmp1 ; remember upper case equivalent + + lda (ptr1),y ; get character from first string + tax + lda __ctype,x ; get character classification + and #CT_LOWER ; lower case char? + beq L2 ; jump if no + txa ; get character back + sec + sbc #<('a'-'A') ; make upper case char + tax + +L2: cpx tmp1 ; compare characters + bne NotEqual ; Jump if strings different + txa ; End of strings? + beq Equal1 ; Jump if EOS reached, a/x == 0 + +; Increment the pointers + + iny + bne Loop + inc ptr1+1 + inc ptr2+1 + bne Loop ; Branch always + +; Increment hi byte + +IncHi: inc ptr3+1 + bne Comp ; Jump if counter not zero + +; Exit code if strings are equal. a/x not set + +Equal: lda #$00 + tax +Equal1: rts + +; Exit code if strings not equal + +NotEqual: + bcs L3 + ldx #$FF ; Make result negative + rts + +L3: ldx #$01 ; Make result positive + rts diff --git a/lib/common/stroserr.s b/lib/common/stroserr.s new file mode 100644 index 0000000..c410b54 --- /dev/null +++ b/lib/common/stroserr.s @@ -0,0 +1,61 @@ +; +; Ullrich von Bassewitz, 17.07.2002 +; +; const char* __fastcall__ _stroserror (unsigned char errcode); +; /* Map an operating system error number to an error message. */ +; + + .export __stroserror + .import __sys_oserrlist + .importzp ptr1, tmp1 + + .macpack generic + + +; The table is built as a list of entries +; +; .byte entrylen +; .byte errorcode +; .asciiz errormsg +; +; and terminated by an entry with length zero that is returned if the +; error code could not be found. + +__stroserror: + sta tmp1 ; Save the error code + + ldy #<__sys_oserrlist + sty ptr1 + ldy #>__sys_oserrlist + sty ptr1+1 ; Setup pointer to message table + +@L1: ldy #0 + lda (ptr1),y ; Get the length + beq Done ; Bail out if end of list reached + + iny + lda (ptr1),y ; Compare the error code + cmp tmp1 + beq Done ; Jump if found + +; Not found, move pointer to next entry + + dey + clc + lda ptr1 + adc (ptr1),y + sta ptr1 + bcc @L1 + inc ptr1+1 + bcs @L1 ; Branch always + +; We've found the code or reached the end of the list + +Done: ldx ptr1+1 + lda ptr1 + add #2 ; Add a total of #2 + bcc @L1 + inx ; Bump high byte +@L1: rts + + diff --git a/lib/common/strpbrk.s b/lib/common/strpbrk.s new file mode 100644 index 0000000..e34468b --- /dev/null +++ b/lib/common/strpbrk.s @@ -0,0 +1,60 @@ +; +; Ullrich von Bassewitz, 11.06.1998 +; +; char* strpbrk (const char* s1, const char* s2); +; + + .export _strpbrk + .import popax, return0 + .importzp ptr1, ptr2, tmp1, tmp2, tmp3 + +_strpbrk: + jsr popax ; get s2 + sta ptr2 + stx ptr2+1 + jsr popax ; get s1 + sta ptr1 + stx ptr1+1 + ldy #$00 + +L1: lda (ptr1),y ; get next char from s1 + beq L9 ; jump if done + sta tmp2 ; save char + iny + bne L2 + inc ptr1+1 +L2: sty tmp3 ; save index into s1 + + ldy #0 ; get index into s2 +L3: lda (ptr2),y ; + beq L4 ; jump if done + cmp tmp2 + beq L6 + iny + bne L3 + +; The character was not found in s2. Increment the counter and start over + +L4: ldy tmp3 ; reload index + inx + bne L1 + inc tmp1 + bne L1 + +; A character was found. Calculate a pointer to this char in s1 and return it. + +L6: ldx ptr1+1 + lda tmp3 ; get y offset + clc + adc ptr1 + bcc L7 + inx +L7: rts + +; None of the characters in s2 was found - return NULL + +L9: jmp return0 + + + + diff --git a/lib/common/strrchr.s b/lib/common/strrchr.s new file mode 100644 index 0000000..bf09fbd --- /dev/null +++ b/lib/common/strrchr.s @@ -0,0 +1,47 @@ +; +; Ullrich von Bassewitz, 31.05.1998 +; +; char* strrchr (const char* s, int c); +; + + .export _strrchr + .import popax + .importzp ptr1, ptr2, tmp1 + +_strrchr: + sta tmp1 ; Save c + jsr popax ; get s + sta ptr1 + stx ptr1+1 + lda #0 ; function result = NULL + sta ptr2 + sta ptr2+1 + tay + +L1: lda (ptr1),y ; get next char + beq L3 ; jump if end of string + cmp tmp1 ; found? + bne L2 ; jump if no + +; Remember a pointer to the character + + tya + clc + adc ptr1 + sta ptr2 + lda ptr1+1 + adc #$00 + sta ptr2+1 + +; Next char + +L2: iny + bne L1 + inc ptr1+1 + bne L1 ; jump always + +; Return the pointer to the last occurrence + +L3: lda ptr2 + ldx ptr2+1 + rts diff --git a/lib/common/strspn.s b/lib/common/strspn.s new file mode 100644 index 0000000..884a337 --- /dev/null +++ b/lib/common/strspn.s @@ -0,0 +1,56 @@ +; +; Ullrich von Bassewitz, 11.06.1998 +; +; size_t strspn (const char* s1, const char* s2); +; + + .export _strspn + .import popax + .importzp ptr1, ptr2, tmp1, tmp2, tmp3 + +_strspn: + sta ptr2 ; Save s2 + stx ptr2+1 + jsr popax ; get s1 + sta ptr1 + stx ptr1+1 + ldx #0 ; low counter byte + stx tmp1 ; high counter byte + ldy #$00 + +L1: lda (ptr1),y ; get next char from s1 + beq L6 ; jump if done + sta tmp2 ; save char + iny + bne L2 + inc ptr1+1 +L2: sty tmp3 ; save index into s1 + + ldy #0 ; get index into s2 +L3: lda (ptr2),y ; + beq L6 ; jump if done + cmp tmp2 + beq L4 + iny + bne L3 + +; The character was found in s2. Increment the counter and start over + +L4: ldy tmp3 ; reload index + inx + bne L1 + inc tmp1 + bne L1 + +; The character was not found, or we reached the end of s1. Return count of +; characters + +L6: txa ; get low counter byte + ldx tmp1 ; get high counter byte + rts + + + + + + diff --git a/lib/common/strstr.s b/lib/common/strstr.s new file mode 100644 index 0000000..62e1944 --- /dev/null +++ b/lib/common/strstr.s @@ -0,0 +1,97 @@ +; +; Ullrich von Bassewitz, 11.12.1998 +; +; char* strstr (const char* haystack, const char* needle); +; + + .export _strstr + .import popax + .importzp ptr1, ptr2, ptr3, ptr4, tmp1 + +_strstr: + sta ptr2 ; Save needle + stx ptr2+1 + sta ptr4 ; Setup temp copy for later + + jsr popax ; Get haystack + sta ptr1 + stx ptr1+1 ; Save haystack + +; If needle is empty, return haystack + + ldy #$00 + lda (ptr2),y ; Get first byte of needle + beq @Found ; Needle is empty --> we're done + +; Search for the beginning of the string (this is not an optimal search +; strategy [in fact, it's pretty dumb], but it's simple to implement). + + sta tmp1 ; Save start of needle +@L1: lda (ptr1),y ; Get next char from haystack + beq @NotFound ; Jump if end + cmp tmp1 ; Start of needle found? + beq @L2 ; Jump if so + iny ; Next char + bne @L1 + inc ptr1+1 ; Bump high byte + bne @L1 ; Branch always + +; We found the start of needle in haystack + +@L2: tya ; Get offset + clc + adc ptr1 + sta ptr1 ; Make ptr1 point to start + bcc @L3 + inc ptr1+1 + +; ptr1 points to the start of needle now. Setup temporary pointers for the +; search. The low byte of ptr4 is already set. + +@L3: sta ptr3 + lda ptr1+1 + sta ptr3+1 + lda ptr2+1 + sta ptr4+1 + ldy #1 ; First char is identical, so start on second + +; Do the compare + +@L4: lda (ptr4),y ; Get char from needle + beq @Found ; Jump if end of needle (-> found) + cmp (ptr3),y ; Compare with haystack + bne @L5 ; Jump if not equal + iny ; Next char + bne @L4 + inc ptr3+1 + inc ptr4+1 ; Bump hi byte of pointers + bne @L4 ; Next char (branch always) + +; The strings did not compare equal, search next start of needle + +@L5: ldy #1 ; Start after this char + bne @L1 ; Branch always + +; We found the start of needle + +@Found: lda ptr1 + ldx ptr1+1 + rts + +; We reached end of haystack without finding needle + +@NotFound: + lda #$00 ; return NULL + tax + rts + + + + + + + + + + + diff --git a/lib/common/strtoimax.s b/lib/common/strtoimax.s new file mode 100644 index 0000000..10c0d42 --- /dev/null +++ b/lib/common/strtoimax.s @@ -0,0 +1,9 @@ +; +; Ullrich von Bassewitz, 2009-09-17 +; +; intmax_t __fastcall__ strtoimax (const char* nptr, char** endptr, int base); +; + + .import _strtol + .export _strtoimax = _strtol + diff --git a/lib/common/strtok.c b/lib/common/strtok.c new file mode 100644 index 0000000..3e5ff7d --- /dev/null +++ b/lib/common/strtok.c @@ -0,0 +1,77 @@ +/* + * strtok.c + * + * Ullrich von Bassewitz, 11.12.1998 + */ + + + +#include + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Memory location that holds the last input */ +static char* Last = 0; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +char* __fastcall__ strtok (register char* s1, const char* s2) +{ + char c; + char* start; + + /* Use the stored location if called with a NULL pointer */ + if (s1 == 0) { + s1 = Last; + } + + /* If s1 is empty, there are no more tokens. Return 0 in this case. */ + if (*s1 == '\0') { + return 0; + } + + /* Search the address of the first element in s1 that equals none + * of the characters in s2. + */ + while ((c = *s1) && strchr (s2, c) != 0) { + ++s1; + } + if (c == '\0') { + /* No more tokens found */ + Last = s1; + return 0; + } + + /* Remember the start of the token */ + start = s1; + + /* Search for the end of the token */ + while ((c = *s1) && strchr (s2, c) == 0) { + ++s1; + } + if (c == '\0') { + /* Last element */ + Last = s1; + } else { + *s1 = '\0'; + Last = s1 + 1; + } + + /* Return the start of the token */ + return start; +} + + + diff --git a/lib/common/strtok.s b/lib/common/strtok.s new file mode 100644 index 0000000..0318db2 --- /dev/null +++ b/lib/common/strtok.s @@ -0,0 +1,228 @@ +; +; File generated by cc65 v 2.13.3 +; + .fopt compiler,"cc65 v 2.13.3" + .setcpu "65C02" + .smart on + .autoimport on + .case on + .debuginfo on + .importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 + .macpack longbranch + .dbg file, "strtok.c", 1493, 1356265749 + .dbg file, "../../include/string.h", 4883, 1234293382 + .dbg file, "../../include/stddef.h", 2972, 1253259480 + .import _strchr + .export _strtok + +.segment "DATA" + +_Last: + .word $0000 + +; --------------------------------------------------------------- +; __near__ unsigned char* __near__ __fastcall__ strtok (register __near__ unsigned char*, __near__ const unsigned char*) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _strtok: near + +.segment "CODE" + +; +; { +; + .dbg line, "strtok.c", 31 + jsr pushax + ldy #$02 + ldx #$04 + jsr regswap2 +; +; if (s1 == 0) { +; + .dbg line, "strtok.c", 36 + jsr decsp3 + lda regbank+4 + ora regbank+4+1 + bne L0004 +; +; s1 = Last; +; + .dbg line, "strtok.c", 37 + lda _Last + sta regbank+4 + lda _Last+1 + sta regbank+4+1 +; +; if (*s1 == '\0') { +; + .dbg line, "strtok.c", 41 +L0004: lda (regbank+4) + bne L0009 +; +; return 0; +; + .dbg line, "strtok.c", 42 + tax + jmp L0003 +; +; while ((c = *s1) && strchr (s2, c) != 0) { +; + .dbg line, "strtok.c", 48 +L0009: lda (regbank+4) + ldy #$02 + sta (sp),y + tax + beq L000D + ldy #$04 + lda (sp),y + tax + dey + lda (sp),y + jsr pushax + ldy #$04 + lda (sp),y + ldx #$00 + jsr _strchr + cpx #$00 + bne L000E + cmp #$00 + beq L000D +; +; ++s1; +; + .dbg line, "strtok.c", 49 +L000E: inc regbank+4 + bne L0009 + inc regbank+4+1 +; +; } +; + .dbg line, "strtok.c", 50 + bra L0009 +; +; if (c == '\0') { +; + .dbg line, "strtok.c", 51 +L000D: ldy #$02 + lda (sp),y + bne L0018 +; +; Last = s1; +; + .dbg line, "strtok.c", 53 + lda regbank+4 + sta _Last + lda regbank+4+1 + sta _Last+1 +; +; return 0; +; + .dbg line, "strtok.c", 54 + txa + bra L0003 +; +; start = s1; +; + .dbg line, "strtok.c", 58 +L0018: lda regbank+4 + ldx regbank+4+1 + jsr stax0sp +; +; while ((c = *s1) && strchr (s2, c) == 0) { +; + .dbg line, "strtok.c", 61 +L001F: lda (regbank+4) + ldy #$02 + sta (sp),y + tax + beq L0020 + ldy #$04 + lda (sp),y + tax + dey + lda (sp),y + jsr pushax + ldy #$04 + lda (sp),y + ldx #$00 + jsr _strchr + cpx #$00 + bne L0020 + cmp #$00 + bne L0020 +; +; ++s1; +; + .dbg line, "strtok.c", 62 + inc regbank+4 + bne L001F + inc regbank+4+1 +; +; } +; + .dbg line, "strtok.c", 63 + bra L001F +; +; if (c == '\0') { +; + .dbg line, "strtok.c", 64 +L0020: ldy #$02 + lda (sp),y + bne L002B +; +; Last = s1; +; + .dbg line, "strtok.c", 66 + lda regbank+4 + sta _Last + lda regbank+4+1 + sta _Last+1 +; +; } else { +; + .dbg line, "strtok.c", 67 + bra L002F +; +; *s1 = '\0'; +; + .dbg line, "strtok.c", 68 +L002B: lda #$00 + sta (regbank+4) +; +; Last = s1 + 1; +; + .dbg line, "strtok.c", 69 + lda regbank+4 + ldx regbank+4+1 + ina + bne L0034 + inx +L0034: sta _Last + stx _Last+1 +; +; return start; +; + .dbg line, "strtok.c", 73 +L002F: dey + lda (sp),y + tax + lda (sp) +; +; } +; + .dbg line, "strtok.c", 74 +L0003: pha + ldy #$05 + lda (sp),y + sta regbank+4 + iny + lda (sp),y + sta regbank+5 + pla + jmp incsp7 + .dbg line + +.endproc + diff --git a/lib/common/strtol.c b/lib/common/strtol.c new file mode 100644 index 0000000..b36dd89 --- /dev/null +++ b/lib/common/strtol.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include + + + +long __fastcall__ strtol (const char* nptr, char** endptr, int base) +/* Convert a string to a long int */ +{ + register const char* S = nptr; + unsigned long Val = 0; + unsigned char Minus = 0; + unsigned char Ovf = 0; + unsigned CvtCount = 0; + unsigned char DigitVal; + unsigned long MaxVal; + unsigned char MaxDigit; + + + /* Skip white space */ + while (isspace (*S)) { + ++S; + } + + /* Check for leading + or - sign */ + switch (*S) { + case '-': + Minus = 1; + /* FALLTHROUGH */ + case '+': + ++S; + } + + /* If base is zero, we may have a 0 or 0x prefix. If base is 16, we may + * have a 0x prefix. + */ + if (base == 0) { + if (*S == '0') { + ++S; + if (*S == 'x' || *S == 'X') { + ++S; + base = 16; + } else { + base = 8; + } + } else { + base = 10; + } + } else if (base == 16 && *S == '0' && (S[1] == 'x' || S[1] == 'X')) { + S += 2; + } + + /* Determine the maximum valid number and (if the number is equal to this + * value) the maximum valid digit. + */ + if (Minus) { + MaxVal = LONG_MIN; + } else { + MaxVal = LONG_MAX; + } + MaxDigit = MaxVal % base; + MaxVal /= base; + + /* Convert the number */ + while (1) { + + /* Convert the digit into a numeric value */ + if (isdigit (*S)) { + DigitVal = *S - '0'; + } else if (isupper (*S)) { + DigitVal = *S - ('A' - 10); + } else if (islower (*S)) { + DigitVal = *S - ('a' - 10); + } else { + /* Unknown character */ + break; + } + + /* Don't accept a character that doesn't match base */ + if (DigitVal >= base) { + break; + } + + /* Don't accept anything that makes the final value invalid */ + if (Val > MaxVal || (Val == MaxVal && DigitVal > MaxDigit)) { + Ovf = 1; + } + + /* Calculate the next value if digit is not invalid */ + if (Ovf == 0) { + Val = (Val * base) + DigitVal; + ++CvtCount; + } + + /* Next character from input */ + ++S; + } + + /* Store the end pointer. If no conversion was performed, the value of + * nptr is returned in endptr. + */ + if (endptr) { + if (CvtCount > 0) { + *endptr = (char*) S - 1; + } else { + *endptr = (char*) nptr; + } + } + + /* Handle overflow */ + if (Ovf) { + errno = ERANGE; + if (Minus) { + return LONG_MIN; + } else { + return LONG_MAX; + } + } + + /* Return the result */ + if (Minus) { + return -(long)Val; + } else { + return Val; + } +} + diff --git a/lib/common/strtol.s b/lib/common/strtol.s new file mode 100644 index 0000000..7d3aef0 --- /dev/null +++ b/lib/common/strtol.s @@ -0,0 +1,592 @@ +; +; File generated by cc65 v 2.13.3 +; + .fopt compiler,"cc65 v 2.13.3" + .setcpu "65C02" + .smart on + .autoimport on + .case on + .debuginfo on + .importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 + .macpack longbranch + .dbg file, "strtol.c", 2969, 1356265749 + .dbg file, "../../include/limits.h", 2978, 1039954353 + .dbg file, "../../include/ctype.h", 7770, 1087856531 + .dbg file, "../../include/errno.h", 3647, 1060696125 + .dbg file, "../../include/stdlib.h", 5578, 1253048480 + .import __ctype + .import __maperrno + .import __errno + .export _strtol + +; --------------------------------------------------------------- +; long __near__ __fastcall__ strtol (__near__ const unsigned char*, __near__ __near__ unsigned char**, int) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _strtol: near + +.segment "CODE" + +; +; { +; + .dbg line, "strtol.c", 10 + jsr pushax +; +; register const char* S = nptr; +; + .dbg line, "strtol.c", 11 + lda regbank+4 + ldx regbank+5 + jsr pushax + ldy #$07 + lda (sp),y + tax + dey + lda (sp),y + sta regbank+4 + stx regbank+4+1 +; +; unsigned long Val = 0; +; + .dbg line, "strtol.c", 12 + ldx #$00 + txa + jsr push0ax +; +; unsigned char Minus = 0; +; + .dbg line, "strtol.c", 13 + jsr pusha +; +; unsigned char Ovf = 0; +; + .dbg line, "strtol.c", 14 + jsr pusha +; +; unsigned CvtCount = 0; +; + .dbg line, "strtol.c", 15 + jsr push0 +; +; while (isspace (*S)) { +; + .dbg line, "strtol.c", 22 + jsr decsp6 +L0009: lda (regbank+4) + tay + lda __ctype,y + and #$60 + beq L000A +; +; ++S; +; + .dbg line, "strtol.c", 23 + inc regbank+4 + bne L0009 + inc regbank+4+1 +; +; } +; + .dbg line, "strtol.c", 24 + bra L0009 +; +; switch (*S) { +; + .dbg line, "strtol.c", 27 +L000A: lda (regbank+4) +; +; } +; + .dbg line, "strtol.c", 33 + cmp #$2B + beq L001F + cmp #$2D + bne L0019 +; +; Minus = 1; +; + .dbg line, "strtol.c", 29 + lda #$01 + ldy #$09 + sta (sp),y +; +; ++S; +; + .dbg line, "strtol.c", 32 +L001F: inc regbank+4 + bne L0019 + inc regbank+4+1 +; +; if (base == 0) { +; + .dbg line, "strtol.c", 38 +L0019: ldy #$11 + lda (sp),y + tax + dey + lda (sp),y + cpx #$00 + bne L0022 + cmp #$00 + bne L0022 +; +; if (*S == '0') { +; + .dbg line, "strtol.c", 39 + lda (regbank+4) + cmp #$30 + bne L0025 +; +; ++S; +; + .dbg line, "strtol.c", 40 + inc regbank+4 + bne L0028 + inc regbank+4+1 +; +; if (*S == 'x' || *S == 'X') { +; + .dbg line, "strtol.c", 41 +L0028: lda (regbank+4) + cmp #$78 + beq L002A + lda (regbank+4) + cmp #$58 + bne L0029 +; +; ++S; +; + .dbg line, "strtol.c", 42 +L002A: inc regbank+4 + bne L002D + inc regbank+4+1 +; +; base = 16; +; + .dbg line, "strtol.c", 43 +L002D: tya +; +; } else { +; + .dbg line, "strtol.c", 44 + bra L00B0 +; +; base = 8; +; + .dbg line, "strtol.c", 45 +L0029: lda #$08 + ldy #$10 + jsr staxysp +; +; } else { +; + .dbg line, "strtol.c", 47 + bra L0037 +; +; base = 10; +; + .dbg line, "strtol.c", 48 +L0025: lda #$0A +L00B0: ldy #$10 + jsr staxysp +; +; } else if (base == 16 && *S == '0' && (S[1] == 'x' || S[1] == 'X')) { +; + .dbg line, "strtol.c", 50 + bra L0037 +L0022: iny + lda (sp),y + tax + dey + lda (sp),y + cpx #$00 + bne L0037 + cmp #$10 + bne L0037 + lda (regbank+4) + cmp #$30 + bne L0037 + ldy #$01 + lda (regbank+4),y + cmp #$78 + beq L0038 + lda (regbank+4),y + cmp #$58 + bne L0037 +; +; S += 2; +; + .dbg line, "strtol.c", 51 +L0038: lda #$02 + clc + adc regbank+4 + sta regbank+4 + bcc L0037 + inc regbank+4+1 +; +; if (Minus) { +; + .dbg line, "strtol.c", 57 +L0037: ldy #$09 + lda (sp),y + beq L0043 +; +; MaxVal = LONG_MIN; +; + .dbg line, "strtol.c", 58 + ldy #$01 + lda #$00 + sta (sp),y + iny + sta (sp),y + iny + sta (sp),y + lda #$80 +; +; } else { +; + .dbg line, "strtol.c", 59 + bra L00B1 +; +; MaxVal = LONG_MAX; +; + .dbg line, "strtol.c", 60 +L0043: ldy #$01 + dea + sta (sp),y + iny + sta (sp),y + iny + sta (sp),y + lda #$7F +L00B1: iny + sta (sp),y +; +; MaxDigit = MaxVal % base; +; + .dbg line, "strtol.c", 62 + jsr ldeaxysp + jsr pusheax + ldy #$15 + lda (sp),y + tax + dey + lda (sp),y + jsr axlong + jsr tosumodeax + sta (sp) +; +; MaxVal /= base; +; + .dbg line, "strtol.c", 63 + ldy #$04 + jsr ldeaxysp + jsr pusheax + ldy #$15 + lda (sp),y + tax + dey + lda (sp),y + jsr axlong + jsr tosudiveax + ldy #$01 + jsr steaxysp +; +; if (isdigit (*S)) { +; + .dbg line, "strtol.c", 69 +L004F: lda (regbank+4) + tay + lda __ctype,y + and #$04 + beq L0052 +; +; DigitVal = *S - '0'; +; + .dbg line, "strtol.c", 70 + lda (regbank+4) + sec + sbc #$30 +; +; } else if (isupper (*S)) { +; + .dbg line, "strtol.c", 71 + bra L00B3 +L0052: lda (regbank+4) + tay + lda __ctype,y + and #$02 + beq L0060 +; +; DigitVal = *S - ('A' - 10); +; + .dbg line, "strtol.c", 72 + lda (regbank+4) + sec + sbc #$37 +; +; } else if (islower (*S)) { +; + .dbg line, "strtol.c", 73 + bra L00B3 +L0060: lda (regbank+4) + tay + lda __ctype,y + and #$01 + jeq L0050 +; +; DigitVal = *S - ('a' - 10); +; + .dbg line, "strtol.c", 74 + lda (regbank+4) + sec + sbc #$57 +L00B3: ldy #$05 + sta (sp),y +; +; if (DigitVal >= base) { +; + .dbg line, "strtol.c", 81 + lda (sp),y + jsr pusha0 + ldy #$13 + lda (sp),y + tax + dey + lda (sp),y + jsr tosicmp +; +; break; +; + .dbg line, "strtol.c", 82 + bcs L0050 +; +; if (Val > MaxVal || (Val == MaxVal && DigitVal > MaxDigit)) { +; + .dbg line, "strtol.c", 86 + ldy #$0D + jsr ldeaxysp + jsr pusheax + ldy #$08 + jsr ldeaxysp + jsr tosugteax + bne L0081 + ldy #$0D + jsr ldeaxysp + jsr pusheax + ldy #$08 + jsr ldeaxysp + jsr toseqeax + beq L0080 + ldy #$05 + lda (sp),y + sec + sbc (sp) + sta tmp1 + lda tmp1 + beq L0080 + bcc L0080 +; +; Ovf = 1; +; + .dbg line, "strtol.c", 87 +L0081: lda #$01 + ldy #$08 + sta (sp),y +; +; if (Ovf == 0) { +; + .dbg line, "strtol.c", 91 +L0080: ldy #$08 + lda (sp),y + bne L0088 +; +; Val = (Val * base) + DigitVal; +; + .dbg line, "strtol.c", 92 + ldy #$0D + jsr ldeaxysp + jsr pusheax + ldy #$15 + lda (sp),y + tax + dey + lda (sp),y + jsr axlong + jsr tosumuleax + jsr pusheax + ldy #$09 + ldx #$00 + lda (sp),y + jsr tosadd0ax + ldy #$0A + jsr steaxysp +; +; ++CvtCount; +; + .dbg line, "strtol.c", 93 + ldy #$06 + ldx #$00 + lda #$01 + jsr addeqysp +; +; ++S; +; + .dbg line, "strtol.c", 97 +L0088: inc regbank+4 + jne L004F + inc regbank+4+1 +; +; } +; + .dbg line, "strtol.c", 98 + jmp L004F +; +; if (endptr) { +; + .dbg line, "strtol.c", 103 +L0050: ldy #$13 + lda (sp),y + dey + ora (sp),y + beq L0098 +; +; if (CvtCount > 0) { +; + .dbg line, "strtol.c", 104 + ldy #$07 + lda (sp),y + tax + dey + lda (sp),y + cpx #$00 + bne L00AF + cmp #$00 + beq L0092 +; +; *endptr = (char*) S - 1; +; + .dbg line, "strtol.c", 105 +L00AF: ldy #$13 + lda (sp),y + tax + dey + lda (sp),y + sta sreg + stx sreg+1 + lda regbank+4 + ldx regbank+4+1 + sec + sbc #$01 + bcs L0097 + dex +L0097: sta (sreg) + ldy #$01 + txa + sta (sreg),y +; +; } else { +; + .dbg line, "strtol.c", 106 + bra L0098 +; +; *endptr = (char*) nptr; +; + .dbg line, "strtol.c", 107 +L0092: ldy #$13 + lda (sp),y + tax + dey + lda (sp),y + jsr pushax + ldy #$17 + lda (sp),y + tax + dey + lda (sp),y + ldy #$00 + jsr staxspidx +; +; if (Ovf) { +; + .dbg line, "strtol.c", 112 +L0098: ldy #$08 + lda (sp),y + beq L00A5 +; +; errno = ERANGE; +; + .dbg line, "strtol.c", 113 + jsr __maperrno + ldx #$00 + lda #$0F + sta __errno + stz __errno+1 +; +; if (Minus) { +; + .dbg line, "strtol.c", 114 + ldy #$09 + lda (sp),y + beq L00A1 +; +; return LONG_MIN; +; + .dbg line, "strtol.c", 115 + stz sreg + lda #$80 + sta sreg+1 + txa + bra L00AA +; +; return LONG_MAX; +; + .dbg line, "strtol.c", 117 +L00A1: dex + stx sreg + lda #$7F + sta sreg+1 + txa + bra L00AA +; +; if (Minus) { +; + .dbg line, "strtol.c", 122 +L00A5: iny + lda (sp),y + beq L00A7 +; +; return -(long)Val; +; + .dbg line, "strtol.c", 123 + ldy #$0D + jsr ldeaxysp + jsr negeax + bra L00AA +; +; return Val; +; + .dbg line, "strtol.c", 125 +L00A7: ldy #$0D + jsr ldeaxysp +; +; } +; + .dbg line, "strtol.c", 127 +L00AA: pha + ldy #$0E + lda (sp),y + sta regbank+4 + iny + lda (sp),y + sta regbank+5 + pla + ldy #$16 + jmp addysp + .dbg line + +.endproc + diff --git a/lib/common/strtoul.c b/lib/common/strtoul.c new file mode 100644 index 0000000..15b01ec --- /dev/null +++ b/lib/common/strtoul.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include + + + +unsigned long __fastcall__ strtoul (const char* nptr, char** endptr, int base) +/* Convert a string to a long unsigned int */ +{ + register const char* S = nptr; + unsigned long Val = 0; + unsigned char Minus = 0; + unsigned char Ovf = 0; + unsigned CvtCount = 0; + unsigned char DigitVal; + unsigned long MaxVal; + unsigned char MaxDigit; + + + /* Skip white space */ + while (isspace (*S)) { + ++S; + } + + /* Check for leading + or - sign */ + switch (*S) { + case '-': + Minus = 1; + /* FALLTHROUGH */ + case '+': + ++S; + } + + /* If base is zero, we may have a 0 or 0x prefix. If base is 16, we may + * have a 0x prefix. + */ + if (base == 0) { + if (*S == '0') { + ++S; + if (*S == 'x' || *S == 'X') { + ++S; + base = 16; + } else { + base = 8; + } + } else { + base = 10; + } + } else if (base == 16 && *S == '0' && (S[1] == 'x' || S[1] == 'X')) { + S += 2; + } + + /* Determine the maximum valid number and (if the number is equal to this + * value) the maximum valid digit. + */ + MaxDigit = ULONG_MAX % base; + MaxVal = ULONG_MAX / base; + + /* Convert the number */ + while (1) { + + /* Convert the digit into a numeric value */ + if (isdigit (*S)) { + DigitVal = *S - '0'; + } else if (isupper (*S)) { + DigitVal = *S - ('A' - 10); + } else if (islower (*S)) { + DigitVal = *S - ('a' - 10); + } else { + /* Unknown character */ + break; + } + + /* Don't accept a character that doesn't match base */ + if (DigitVal >= base) { + break; + } + + /* Don't accept anything that makes the final value invalid */ + if (Val > MaxVal || (Val == MaxVal && DigitVal > MaxDigit)) { + Ovf = 1; + } + + /* Calculate the next value if digit is not invalid */ + if (Ovf == 0) { + Val = (Val * base) + DigitVal; + ++CvtCount; + } + + /* Next character from input */ + ++S; + } + + /* Store the end pointer. If no conversion was performed, the value of + * nptr is returned in endptr. + */ + if (endptr) { + if (CvtCount > 0) { + *endptr = (char*) S - 1; + } else { + *endptr = (char*) nptr; + } + } + + /* Handle overflow */ + if (Ovf) { + errno = ERANGE; + return ULONG_MAX; + } + + /* Return the result */ + if (Minus) { + return (unsigned long) -(long)Val; + } else { + return Val; + } +} + diff --git a/lib/common/strtoul.s b/lib/common/strtoul.s new file mode 100644 index 0000000..b251c7c --- /dev/null +++ b/lib/common/strtoul.s @@ -0,0 +1,541 @@ +; +; File generated by cc65 v 2.13.3 +; + .fopt compiler,"cc65 v 2.13.3" + .setcpu "65C02" + .smart on + .autoimport on + .case on + .debuginfo on + .importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 + .macpack longbranch + .dbg file, "strtoul.c", 2843, 1356265749 + .dbg file, "../../include/limits.h", 2978, 1039954353 + .dbg file, "../../include/ctype.h", 7770, 1087856531 + .dbg file, "../../include/errno.h", 3647, 1060696125 + .dbg file, "../../include/stdlib.h", 5578, 1253048480 + .import __ctype + .import __maperrno + .import __errno + .export _strtoul + +; --------------------------------------------------------------- +; unsigned long __near__ __fastcall__ strtoul (__near__ const unsigned char*, __near__ __near__ unsigned char**, int) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _strtoul: near + +.segment "CODE" + +; +; { +; + .dbg line, "strtoul.c", 10 + jsr pushax +; +; register const char* S = nptr; +; + .dbg line, "strtoul.c", 11 + lda regbank+4 + ldx regbank+5 + jsr pushax + ldy #$07 + lda (sp),y + tax + dey + lda (sp),y + sta regbank+4 + stx regbank+4+1 +; +; unsigned long Val = 0; +; + .dbg line, "strtoul.c", 12 + ldx #$00 + txa + jsr push0ax +; +; unsigned char Minus = 0; +; + .dbg line, "strtoul.c", 13 + jsr pusha +; +; unsigned char Ovf = 0; +; + .dbg line, "strtoul.c", 14 + jsr pusha +; +; unsigned CvtCount = 0; +; + .dbg line, "strtoul.c", 15 + jsr push0 +; +; while (isspace (*S)) { +; + .dbg line, "strtoul.c", 22 + jsr decsp6 +L0009: lda (regbank+4) + tay + lda __ctype,y + and #$60 + beq L000A +; +; ++S; +; + .dbg line, "strtoul.c", 23 + inc regbank+4 + bne L0009 + inc regbank+4+1 +; +; } +; + .dbg line, "strtoul.c", 24 + bra L0009 +; +; switch (*S) { +; + .dbg line, "strtoul.c", 27 +L000A: lda (regbank+4) +; +; } +; + .dbg line, "strtoul.c", 33 + cmp #$2B + beq L001F + cmp #$2D + bne L0019 +; +; Minus = 1; +; + .dbg line, "strtoul.c", 29 + lda #$01 + ldy #$09 + sta (sp),y +; +; ++S; +; + .dbg line, "strtoul.c", 32 +L001F: inc regbank+4 + bne L0019 + inc regbank+4+1 +; +; if (base == 0) { +; + .dbg line, "strtoul.c", 38 +L0019: ldy #$11 + lda (sp),y + tax + dey + lda (sp),y + cpx #$00 + bne L0022 + cmp #$00 + bne L0022 +; +; if (*S == '0') { +; + .dbg line, "strtoul.c", 39 + lda (regbank+4) + cmp #$30 + bne L0025 +; +; ++S; +; + .dbg line, "strtoul.c", 40 + inc regbank+4 + bne L0028 + inc regbank+4+1 +; +; if (*S == 'x' || *S == 'X') { +; + .dbg line, "strtoul.c", 41 +L0028: lda (regbank+4) + cmp #$78 + beq L002A + lda (regbank+4) + cmp #$58 + bne L0029 +; +; ++S; +; + .dbg line, "strtoul.c", 42 +L002A: inc regbank+4 + bne L002D + inc regbank+4+1 +; +; base = 16; +; + .dbg line, "strtoul.c", 43 +L002D: tya +; +; } else { +; + .dbg line, "strtoul.c", 44 + bra L00A2 +; +; base = 8; +; + .dbg line, "strtoul.c", 45 +L0029: lda #$08 + ldy #$10 + jsr staxysp +; +; } else { +; + .dbg line, "strtoul.c", 47 + bra L0037 +; +; base = 10; +; + .dbg line, "strtoul.c", 48 +L0025: lda #$0A +L00A2: ldy #$10 + jsr staxysp +; +; } else if (base == 16 && *S == '0' && (S[1] == 'x' || S[1] == 'X')) { +; + .dbg line, "strtoul.c", 50 + bra L0037 +L0022: iny + lda (sp),y + tax + dey + lda (sp),y + cpx #$00 + bne L0037 + cmp #$10 + bne L0037 + lda (regbank+4) + cmp #$30 + bne L0037 + ldy #$01 + lda (regbank+4),y + cmp #$78 + beq L0038 + lda (regbank+4),y + cmp #$58 + bne L0037 +; +; S += 2; +; + .dbg line, "strtoul.c", 51 +L0038: lda #$02 + clc + adc regbank+4 + sta regbank+4 + bcc L0037 + inc regbank+4+1 +; +; MaxDigit = ULONG_MAX % base; +; + .dbg line, "strtoul.c", 57 +L0037: ldx #$FF + stx sreg + stx sreg+1 + txa + jsr pusheax + ldy #$15 + lda (sp),y + tax + dey + lda (sp),y + jsr axlong + jsr tosumodeax + sta (sp) +; +; MaxVal = ULONG_MAX / base; +; + .dbg line, "strtoul.c", 58 + ldx #$FF + stx sreg + stx sreg+1 + txa + jsr pusheax + ldy #$15 + lda (sp),y + tax + dey + lda (sp),y + jsr axlong + jsr tosudiveax + ldy #$01 + jsr steaxysp +; +; if (isdigit (*S)) { +; + .dbg line, "strtoul.c", 64 +L0047: lda (regbank+4) + tay + lda __ctype,y + and #$04 + beq L004A +; +; DigitVal = *S - '0'; +; + .dbg line, "strtoul.c", 65 + lda (regbank+4) + sec + sbc #$30 +; +; } else if (isupper (*S)) { +; + .dbg line, "strtoul.c", 66 + bra L00A4 +L004A: lda (regbank+4) + tay + lda __ctype,y + and #$02 + beq L0058 +; +; DigitVal = *S - ('A' - 10); +; + .dbg line, "strtoul.c", 67 + lda (regbank+4) + sec + sbc #$37 +; +; } else if (islower (*S)) { +; + .dbg line, "strtoul.c", 68 + bra L00A4 +L0058: lda (regbank+4) + tay + lda __ctype,y + and #$01 + jeq L0048 +; +; DigitVal = *S - ('a' - 10); +; + .dbg line, "strtoul.c", 69 + lda (regbank+4) + sec + sbc #$57 +L00A4: ldy #$05 + sta (sp),y +; +; if (DigitVal >= base) { +; + .dbg line, "strtoul.c", 76 + lda (sp),y + jsr pusha0 + ldy #$13 + lda (sp),y + tax + dey + lda (sp),y + jsr tosicmp +; +; break; +; + .dbg line, "strtoul.c", 77 + bcs L0048 +; +; if (Val > MaxVal || (Val == MaxVal && DigitVal > MaxDigit)) { +; + .dbg line, "strtoul.c", 81 + ldy #$0D + jsr ldeaxysp + jsr pusheax + ldy #$08 + jsr ldeaxysp + jsr tosugteax + bne L0079 + ldy #$0D + jsr ldeaxysp + jsr pusheax + ldy #$08 + jsr ldeaxysp + jsr toseqeax + beq L0078 + ldy #$05 + lda (sp),y + sec + sbc (sp) + sta tmp1 + lda tmp1 + beq L0078 + bcc L0078 +; +; Ovf = 1; +; + .dbg line, "strtoul.c", 82 +L0079: lda #$01 + ldy #$08 + sta (sp),y +; +; if (Ovf == 0) { +; + .dbg line, "strtoul.c", 86 +L0078: ldy #$08 + lda (sp),y + bne L0080 +; +; Val = (Val * base) + DigitVal; +; + .dbg line, "strtoul.c", 87 + ldy #$0D + jsr ldeaxysp + jsr pusheax + ldy #$15 + lda (sp),y + tax + dey + lda (sp),y + jsr axlong + jsr tosumuleax + jsr pusheax + ldy #$09 + ldx #$00 + lda (sp),y + jsr tosadd0ax + ldy #$0A + jsr steaxysp +; +; ++CvtCount; +; + .dbg line, "strtoul.c", 88 + ldy #$06 + ldx #$00 + lda #$01 + jsr addeqysp +; +; ++S; +; + .dbg line, "strtoul.c", 92 +L0080: inc regbank+4 + jne L0047 + inc regbank+4+1 +; +; } +; + .dbg line, "strtoul.c", 93 + jmp L0047 +; +; if (endptr) { +; + .dbg line, "strtoul.c", 98 +L0048: ldy #$13 + lda (sp),y + dey + ora (sp),y + beq L0090 +; +; if (CvtCount > 0) { +; + .dbg line, "strtoul.c", 99 + ldy #$07 + lda (sp),y + tax + dey + lda (sp),y + cpx #$00 + bne L00A1 + cmp #$00 + beq L008A +; +; *endptr = (char*) S - 1; +; + .dbg line, "strtoul.c", 100 +L00A1: ldy #$13 + lda (sp),y + tax + dey + lda (sp),y + sta sreg + stx sreg+1 + lda regbank+4 + ldx regbank+4+1 + sec + sbc #$01 + bcs L008F + dex +L008F: sta (sreg) + ldy #$01 + txa + sta (sreg),y +; +; } else { +; + .dbg line, "strtoul.c", 101 + bra L0090 +; +; *endptr = (char*) nptr; +; + .dbg line, "strtoul.c", 102 +L008A: ldy #$13 + lda (sp),y + tax + dey + lda (sp),y + jsr pushax + ldy #$17 + lda (sp),y + tax + dey + lda (sp),y + ldy #$00 + jsr staxspidx +; +; if (Ovf) { +; + .dbg line, "strtoul.c", 107 +L0090: ldy #$08 + lda (sp),y + beq L0093 +; +; errno = ERANGE; +; + .dbg line, "strtoul.c", 108 + jsr __maperrno + lda #$0F + sta __errno + stz __errno+1 +; +; return ULONG_MAX; +; + .dbg line, "strtoul.c", 109 + ldx #$FF + stx sreg + stx sreg+1 + txa + bra L009D +; +; if (Minus) { +; + .dbg line, "strtoul.c", 113 +L0093: iny + lda (sp),y + beq L009A +; +; return (unsigned long) -(long)Val; +; + .dbg line, "strtoul.c", 114 + ldy #$0D + jsr ldeaxysp + jsr negeax + bra L009D +; +; return Val; +; + .dbg line, "strtoul.c", 116 +L009A: ldy #$0D + jsr ldeaxysp +; +; } +; + .dbg line, "strtoul.c", 118 +L009D: pha + ldy #$0E + lda (sp),y + sta regbank+4 + iny + lda (sp),y + sta regbank+5 + pla + ldy #$16 + jmp addysp + .dbg line + +.endproc + diff --git a/lib/common/strtoumax.s b/lib/common/strtoumax.s new file mode 100644 index 0000000..c59d51c --- /dev/null +++ b/lib/common/strtoumax.s @@ -0,0 +1,9 @@ +; +; Ullrich von Bassewitz, 2009-09-17 +; +; uintmax_t __fastcall__ strtoumax (const char* nptr, char** endptr, int base); +; + + .import _strtoul + .export _strtoumax = _strtoul + diff --git a/lib/common/strupper.s b/lib/common/strupper.s new file mode 100644 index 0000000..70b593f --- /dev/null +++ b/lib/common/strupper.s @@ -0,0 +1,47 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; char* strupper (char* s); +; char* strupr (char* s); +; +; Non-ANSI +; + + .export _strupper, _strupr + .import popax + .import __ctype + .importzp ptr1, ptr2 + + .include "ctype.inc" + +_strupper: +_strupr: + sta ptr1 ; Save s (working copy) + stx ptr1+1 + sta ptr2 + sta ptr2+2 ; save function result + ldy #0 + +loop: lda (ptr1),y ; get character + beq L9 ; jump if done + tax + lda __ctype,x ; get character classification + and #CT_LOWER ; lower case char? + beq L1 ; jump if no + txa ; get character back into accu + clc + adc #<('A'-'a') ; make upper case char + sta (ptr1),y ; store back +L1: iny ; next char + bne loop + inc ptr1+1 ; handle offset overflow + bne loop ; branch always + +; Done, return the argument string + +L9: lda ptr2 + ldx ptr2+1 + rts + + + diff --git a/lib/common/strxfrm.c b/lib/common/strxfrm.c new file mode 100644 index 0000000..8bf9795 --- /dev/null +++ b/lib/common/strxfrm.c @@ -0,0 +1,20 @@ +/* + * strxfrm.c + * + * Ullrich von Bassewitz, 11.12.1998 + */ + + + +#include + + + +size_t __fastcall__ strxfrm (char* dest, const char* src, size_t count) +{ + strncpy (dest, src, count); + return strlen (src); +} + + + diff --git a/lib/common/strxfrm.s b/lib/common/strxfrm.s new file mode 100644 index 0000000..3a299a5 --- /dev/null +++ b/lib/common/strxfrm.s @@ -0,0 +1,82 @@ +; +; File generated by cc65 v 2.13.3 +; + .fopt compiler,"cc65 v 2.13.3" + .setcpu "65C02" + .smart on + .autoimport on + .case on + .debuginfo on + .importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2 + .macpack longbranch + .dbg file, "strxfrm.c", 222, 1356265749 + .dbg file, "../../include/string.h", 4883, 1234293382 + .dbg file, "../../include/stddef.h", 2972, 1253259480 + .import _strlen + .import _strncpy + .export _strxfrm + +; --------------------------------------------------------------- +; unsigned int __near__ __fastcall__ strxfrm (__near__ unsigned char*, __near__ const unsigned char*, unsigned int) +; --------------------------------------------------------------- + +.segment "CODE" + +.proc _strxfrm: near + +.segment "CODE" + +; +; { +; + .dbg line, "strxfrm.c", 14 + jsr pushax +; +; strncpy (dest, src, count); +; + .dbg line, "strxfrm.c", 15 + jsr decsp4 + ldy #$09 + lda (sp),y + tax + dey + lda (sp),y + ldy #$02 + sta (sp),y + iny + txa + sta (sp),y + ldy #$07 + lda (sp),y + tax + dey + lda (sp),y + sta (sp) + ldy #$01 + txa + sta (sp),y + ldy #$05 + lda (sp),y + tax + dey + lda (sp),y + jsr _strncpy +; +; return strlen (src); +; + .dbg line, "strxfrm.c", 16 + ldy #$03 + lda (sp),y + tax + dey + lda (sp),y + jsr _strlen +; +; } +; + .dbg line, "strxfrm.c", 17 + jmp incsp6 + .dbg line + +.endproc + diff --git a/lib/common/tolower.s b/lib/common/tolower.s new file mode 100644 index 0000000..f44aa9c --- /dev/null +++ b/lib/common/tolower.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int tolower (int c); +; + + .export _tolower + .import __ctype + +_tolower: + cpx #$00 ; Outside valid range? + bne L9 ; If so, return the argument unchanged + tay ; Get C into Y + lda __ctype,y ; Get character classification + lsr a + lsr a ; Get bit 1 (upper case char) into carry + tya ; Get char back into A + bcc L9 ; Jump if no upper case char + sbc #<('A'-'a') ; Make lower case char (carry already set) +L9: rts + diff --git a/lib/common/toupper.s b/lib/common/toupper.s new file mode 100644 index 0000000..adc3d4a --- /dev/null +++ b/lib/common/toupper.s @@ -0,0 +1,21 @@ +; +; Ullrich von Bassewitz, 02.06.1998 +; +; int toupper (int c); +; + + .export _toupper + .import __ctype + +_toupper: + cpx #$00 ; Outside valid range? + bne L9 ; If so, return the argument unchanged + tay ; Get c into Y + lda __ctype,y ; Get character classification + lsr a ; Get bit 0 (lower char) into carry + tya ; Get C back into A + bcc L9 ; Jump if not lower char + clc + adc #<('A'-'a') ; make upper case char +L9: rts ; CC are set + diff --git a/lib/rpc8e.lib b/lib/rpc8e.lib index 59d3d691dfb1a5552cfaf7ef6e656af8d83de309..61a67af089e0fe940c77d2cd55cc19371a835a9d 100644 GIT binary patch delta 36150 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 PKL0zuv}@;H`-T4vGm&;r delta 121 zcmZqp&9VF(8&_UpXcadD1H(;?My{<~jG;=~w`en7VBGFu%2>j*eaAdTGbYBv+utu> z{8=r?QIwjJR9dW;&%n@M*BcP7H2t?M(-C2=_____ + .byte CT_NONE ; 63/3f _____?_____ + + .byte CT_NONE ; 64/40 _____@_____ + .byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____ + .byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____ + .byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____ + .byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____ + .byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____ + .byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____ + .byte CT_UPPER ; 71/47 _____G_____ + .byte CT_UPPER ; 72/48 _____H_____ + .byte CT_UPPER ; 73/49 _____I_____ + .byte CT_UPPER ; 74/4a _____J_____ + .byte CT_UPPER ; 75/4b _____K_____ + .byte CT_UPPER ; 76/4c _____L_____ + .byte CT_UPPER ; 77/4d _____M_____ + .byte CT_UPPER ; 78/4e _____N_____ + .byte CT_UPPER ; 79/4f _____O_____ + .byte CT_UPPER ; 80/50 _____P_____ + .byte CT_UPPER ; 81/51 _____Q_____ + .byte CT_UPPER ; 82/52 _____R_____ + .byte CT_UPPER ; 83/53 _____S_____ + .byte CT_UPPER ; 84/54 _____T_____ + .byte CT_UPPER ; 85/55 _____U_____ + .byte CT_UPPER ; 86/56 _____V_____ + .byte CT_UPPER ; 87/57 _____W_____ + .byte CT_UPPER ; 88/58 _____X_____ + .byte CT_UPPER ; 89/59 _____Y_____ + .byte CT_UPPER ; 90/5a _____Z_____ + .byte CT_NONE ; 91/5b _____[_____ + .byte CT_NONE ; 92/5c _____\_____ + .byte CT_NONE ; 93/5d _____]_____ + .byte CT_NONE ; 94/5e _____^_____ + .byte CT_NONE ; 95/5f _UNDERLINE_ + .byte CT_NONE ; 96/60 ___grave___ + .byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____ + .byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____ + .byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____ + .byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____ + .byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____ + .byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____ + .byte CT_LOWER ; 103/67 _____g_____ + .byte CT_LOWER ; 104/68 _____h_____ + .byte CT_LOWER ; 105/69 _____i_____ + .byte CT_LOWER ; 106/6a _____j_____ + .byte CT_LOWER ; 107/6b _____k_____ + .byte CT_LOWER ; 108/6c _____l_____ + .byte CT_LOWER ; 109/6d _____m_____ + .byte CT_LOWER ; 110/6e _____n_____ + .byte CT_LOWER ; 111/6f _____o_____ + .byte CT_LOWER ; 112/70 _____p_____ + .byte CT_LOWER ; 113/71 _____q_____ + .byte CT_LOWER ; 114/72 _____r_____ + .byte CT_LOWER ; 115/73 _____s_____ + .byte CT_LOWER ; 116/74 _____t_____ + .byte CT_LOWER ; 117/75 _____u_____ + .byte CT_LOWER ; 118/76 _____v_____ + .byte CT_LOWER ; 119/77 _____w_____ + .byte CT_LOWER ; 120/78 _____x_____ + .byte CT_LOWER ; 121/79 _____y_____ + .byte CT_LOWER ; 122/7a _____z_____ + .byte CT_NONE ; 123/7b _____{_____ + .byte CT_NONE ; 124/7c _____|_____ + .byte CT_NONE ; 125/7d _____}_____ + .byte CT_NONE ; 126/7e _____~_____ + .byte CT_OTHER_WS ; 127/7f ____DEL____ + .endrepeat + +