Added some parts of standard library
WARNING, this stuff should compile fine but it's untested. There's no support for many functions atm.master
parent
e60e83ce68
commit
35b97557e7
@ -1,3 +1,4 @@
|
||||
.DS_Store
|
||||
*.o
|
||||
*.img
|
||||
os/
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 <stddef.h>
|
||||
#endif
|
||||
#ifndef _STDARG_H
|
||||
# include <stdarg.h>
|
||||
#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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 <stddef.h>
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
sta __errno
|
||||
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
|
||||
|
||||
|
@ -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 <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* strtok.c
|
||||
*
|
||||
* Ullrich von Bassewitz, 11.12.1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,128 @@
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,119 @@
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* strxfrm.c
|
||||
*
|
||||
* Ullrich von Bassewitz, 11.12.1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
size_t __fastcall__ strxfrm (char* dest, const char* src, size_t count)
|
||||
{
|
||||
strncpy (dest, src, count);
|
||||
return strlen (src);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Binary file not shown.
@ -0,0 +1,161 @@
|
||||
;
|
||||
; Stefan Haubenthal with minor changes from Ullrich von Bassewitz, 2003-05-02
|
||||
;
|
||||
; Character specification table.
|
||||
;
|
||||
|
||||
.include "ctype.inc"
|
||||
|
||||
; The tables are readonly, put them into the rodata segment
|
||||
|
||||
.rodata
|
||||
|
||||
; The following 256 byte wide table specifies attributes for the isxxx type
|
||||
; of functions. Doing it by a table means some overhead in space, but it
|
||||
; has major advantages:
|
||||
;
|
||||
; * It is fast. If it were'nt for the slow parameter passing of cc65, one
|
||||
; could even define macros for the isxxx functions (this is usually
|
||||
; done on other platforms).
|
||||
;
|
||||
; * It is highly portable. The only unportable part is the table itself,
|
||||
; all real code goes into the common library.
|
||||
;
|
||||
; * We save some code in the isxxx functions.
|
||||
|
||||
|
||||
__ctype:
|
||||
.repeat 2
|
||||
.byte CT_CTRL ; 0/00 ___ctrl_@___
|
||||
.byte CT_CTRL ; 1/01 ___ctrl_A___
|
||||
.byte CT_CTRL ; 2/02 ___ctrl_B___
|
||||
.byte CT_CTRL ; 3/03 ___ctrl_C___
|
||||
.byte CT_CTRL ; 4/04 ___ctrl_D___
|
||||
.byte CT_CTRL ; 5/05 ___ctrl_E___
|
||||
.byte CT_CTRL ; 6/06 ___ctrl_F___
|
||||
.byte CT_CTRL ; 7/07 ___ctrl_G___
|
||||
.byte CT_CTRL ; 8/08 ___ctrl_H___
|
||||
.byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB
|
||||
; 9/09 ___ctrl_I___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___
|
||||
.byte CT_CTRL ; 14/0e ___ctrl_N___
|
||||
.byte CT_CTRL ; 15/0f ___ctrl_O___
|
||||
.byte CT_CTRL ; 16/10 ___ctrl_P___
|
||||
.byte CT_CTRL ; 17/11 ___ctrl_Q___
|
||||
.byte CT_CTRL ; 18/12 ___ctrl_R___
|
||||
.byte CT_CTRL ; 19/13 ___ctrl_S___
|
||||
.byte CT_CTRL ; 20/14 ___ctrl_T___
|
||||
.byte CT_CTRL ; 21/15 ___ctrl_U___
|
||||
.byte CT_CTRL ; 22/16 ___ctrl_V___
|
||||
.byte CT_CTRL ; 23/17 ___ctrl_W___
|
||||
.byte CT_CTRL ; 24/18 ___ctrl_X___
|
||||
.byte CT_CTRL ; 25/19 ___ctrl_Y___
|
||||
.byte CT_CTRL ; 26/1a ___ctrl_Z___
|
||||
.byte CT_CTRL ; 27/1b ___ctrl_[___
|
||||
.byte CT_CTRL ; 28/1c ___ctrl_\___
|
||||
.byte CT_CTRL ; 29/1d ___ctrl_]___
|
||||
.byte CT_CTRL ; 30/1e ___ctrl_^___
|
||||
.byte CT_CTRL ; 31/1f ___ctrl_____
|
||||
.byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___
|
||||
.byte CT_NONE ; 33/21 _____!_____
|
||||
.byte CT_NONE ; 34/22 _____"_____
|
||||
.byte CT_NONE ; 35/23 _____#_____
|
||||
.byte CT_NONE ; 36/24 _____$_____
|
||||
.byte CT_NONE ; 37/25 _____%_____
|
||||
.byte CT_NONE ; 38/26 _____&_____
|
||||
.byte CT_NONE ; 39/27 _____'_____
|
||||
.byte CT_NONE ; 40/28 _____(_____
|
||||
.byte CT_NONE ; 41/29 _____)_____
|
||||
.byte CT_NONE ; 42/2a _____*_____
|
||||
.byte CT_NONE ; 43/2b _____+_____
|
||||
.byte CT_NONE ; 44/2c _____,_____
|
||||
.byte CT_NONE ; 45/2d _____-_____
|
||||
.byte CT_NONE ; 46/2e _____._____
|
||||
.byte CT_NONE ; 47/2f _____/_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____
|
||||
.byte CT_NONE ; 58/3a _____:_____
|
||||
.byte CT_NONE ; 59/3b _____;_____
|
||||
.byte CT_NONE ; 60/3c _____<_____
|
||||
.byte CT_NONE ; 61/3d _____=_____
|
||||
.byte CT_NONE ; 62/3e _____>_____
|
||||
.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
|
||||
|
||||
|
Loading…
Reference in New Issue