Removed (pretty inconsistently used) tab chars from source code base.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
; by the constructor defined in this module.
|
||||
;
|
||||
|
||||
.export __cwd
|
||||
.export __cwd
|
||||
.export __cwd_buf_size
|
||||
.constructor cwd_init
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
.bss
|
||||
|
||||
__cwd: .res __cwd_buf_size
|
||||
__cwd: .res __cwd_buf_size
|
||||
|
||||
|
||||
; NOTE: Some of the code working with directories is not able to handle
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
;
|
||||
|
||||
.export __environ, __envcount, __envsize
|
||||
.import initenv
|
||||
.constructor env_init
|
||||
|
||||
env_init := initenv
|
||||
|
||||
.import initenv
|
||||
.constructor env_init
|
||||
|
||||
env_init := initenv
|
||||
|
||||
.bss
|
||||
|
||||
__environ:
|
||||
|
||||
@@ -5,27 +5,27 @@
|
||||
; /* Find a free descriptor slot */
|
||||
|
||||
|
||||
.export __fdesc
|
||||
.import return0
|
||||
.export __fdesc
|
||||
.import return0
|
||||
|
||||
.include "stdio.inc"
|
||||
.include "_file.inc"
|
||||
|
||||
.proc __fdesc
|
||||
|
||||
ldy #0
|
||||
ldy #0
|
||||
lda #_FOPEN
|
||||
Loop: and __filetab + _FILE::f_flags,y ; load flags
|
||||
beq Found ; jump if closed
|
||||
Loop: and __filetab + _FILE::f_flags,y ; load flags
|
||||
beq Found ; jump if closed
|
||||
.repeat .sizeof(_FILE)
|
||||
iny
|
||||
iny
|
||||
.endrepeat
|
||||
cpy #(FOPEN_MAX * .sizeof(_FILE)) ; Done?
|
||||
bne Loop
|
||||
cpy #(FOPEN_MAX * .sizeof(_FILE)) ; Done?
|
||||
bne Loop
|
||||
|
||||
; File table is full
|
||||
|
||||
jmp return0
|
||||
jmp return0
|
||||
|
||||
; Free slot found, get address
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
/* Definition of struct _FILE */
|
||||
struct _FILE {
|
||||
char f_fd;
|
||||
char f_flags;
|
||||
char f_fd;
|
||||
char f_flags;
|
||||
unsigned char f_pushback;
|
||||
};
|
||||
|
||||
@@ -27,10 +27,10 @@ struct _FILE {
|
||||
extern FILE _filetab[FOPEN_MAX];
|
||||
|
||||
/* Flags field */
|
||||
#define _FCLOSED 0x00
|
||||
#define _FOPEN 0x01
|
||||
#define _FEOF 0x02
|
||||
#define _FERROR 0x04
|
||||
#define _FCLOSED 0x00
|
||||
#define _FOPEN 0x01
|
||||
#define _FEOF 0x02
|
||||
#define _FERROR 0x04
|
||||
#define _FPUSHBACK 0x08
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; Data for the stdio file stream.
|
||||
;
|
||||
|
||||
.export __filetab
|
||||
.export __filetab
|
||||
|
||||
.include "stdio.inc"
|
||||
.include "fcntl.inc"
|
||||
@@ -27,12 +27,12 @@ __filetab:
|
||||
; Standard file descriptors
|
||||
|
||||
_stdin:
|
||||
.word __filetab + (STDIN_FILENO * .sizeof(_FILE))
|
||||
.word __filetab + (STDIN_FILENO * .sizeof(_FILE))
|
||||
|
||||
_stdout:
|
||||
.word __filetab + (STDOUT_FILENO * .sizeof(_FILE))
|
||||
.word __filetab + (STDOUT_FILENO * .sizeof(_FILE))
|
||||
|
||||
_stderr:
|
||||
.word __filetab + (STDERR_FILENO * .sizeof(_FILE))
|
||||
.word __filetab + (STDERR_FILENO * .sizeof(_FILE))
|
||||
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
; Heap variables and initialization.
|
||||
;
|
||||
|
||||
.constructor initheap, 24
|
||||
.import __BSS_RUN__, __BSS_SIZE__, __STACKSIZE__
|
||||
.importzp sp
|
||||
.constructor initheap, 24
|
||||
.import __BSS_RUN__, __BSS_SIZE__, __STACKSIZE__
|
||||
.importzp sp
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
.data
|
||||
|
||||
__heaporg:
|
||||
.word __BSS_RUN__+__BSS_SIZE__ ; Linker calculates this symbol
|
||||
.word __BSS_RUN__+__BSS_SIZE__ ; Linker calculates this symbol
|
||||
__heapptr:
|
||||
.word __BSS_RUN__+__BSS_SIZE__ ; Dito
|
||||
.word __BSS_RUN__+__BSS_SIZE__ ; Dito
|
||||
__heapend:
|
||||
.word __BSS_RUN__+__BSS_SIZE__
|
||||
.word __BSS_RUN__+__BSS_SIZE__
|
||||
__heapfirst:
|
||||
.word 0
|
||||
.word 0
|
||||
__heaplast:
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
|
||||
; Initialization. Will be called from startup!
|
||||
@@ -30,13 +30,13 @@ __heaplast:
|
||||
.segment "INIT"
|
||||
|
||||
initheap:
|
||||
sec
|
||||
lda sp
|
||||
sbc #<__STACKSIZE__
|
||||
sta __heapend
|
||||
lda sp+1
|
||||
sbc #>__STACKSIZE__
|
||||
sta __heapend+1
|
||||
rts
|
||||
sec
|
||||
lda sp
|
||||
sbc #<__STACKSIZE__
|
||||
sta __heapend
|
||||
lda sp+1
|
||||
sbc #>__STACKSIZE__
|
||||
sta __heapend+1
|
||||
rts
|
||||
|
||||
|
||||
|
||||
@@ -7,46 +7,46 @@
|
||||
;
|
||||
;
|
||||
|
||||
.importzp ptr1, ptr2
|
||||
.import popax
|
||||
.import heapadd
|
||||
.export __heapadd
|
||||
.importzp ptr1, ptr2
|
||||
.import popax
|
||||
.import heapadd
|
||||
.export __heapadd
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Code
|
||||
|
||||
__heapadd:
|
||||
sta ptr1 ; Store size in ptr1
|
||||
stx ptr1+1
|
||||
jsr popax ; Get the block pointer
|
||||
sta ptr2
|
||||
stx ptr2+1 ; Store block pointer in ptr2
|
||||
sta ptr1 ; Store size in ptr1
|
||||
stx ptr1+1
|
||||
jsr popax ; Get the block pointer
|
||||
sta ptr2
|
||||
stx ptr2+1 ; Store block pointer in ptr2
|
||||
|
||||
; Check if size is greater or equal than min_size. Otherwise we don't care
|
||||
; about the block (this may only happen for user supplied blocks, blocks
|
||||
; from the heap are always large enough to hold a freeblock structure).
|
||||
|
||||
lda ptr1 ; Load low byte
|
||||
ldx ptr1+1 ; Load/check high byte
|
||||
bne @L1
|
||||
cmp #HEAP_MIN_BLOCKSIZE
|
||||
bcs @L1
|
||||
lda ptr1 ; Load low byte
|
||||
ldx ptr1+1 ; Load/check high byte
|
||||
bne @L1
|
||||
cmp #HEAP_MIN_BLOCKSIZE
|
||||
bcs @L1
|
||||
|
||||
rts ; Block not large enough
|
||||
rts ; Block not large enough
|
||||
|
||||
; The block is large enough. Set the size field in the block.
|
||||
|
||||
@L1: ldy #usedblock::size
|
||||
sta (ptr2),y
|
||||
iny
|
||||
txa
|
||||
sta (ptr2),y
|
||||
@L1: ldy #usedblock::size
|
||||
sta (ptr2),y
|
||||
iny
|
||||
txa
|
||||
sta (ptr2),y
|
||||
|
||||
; Call the internal function since variables are now setup correctly
|
||||
|
||||
jmp heapadd
|
||||
jmp heapadd
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
; Return the size of an allocated block.
|
||||
;
|
||||
|
||||
.importzp ptr1, ptr2
|
||||
.export __heapblocksize
|
||||
.importzp ptr1, ptr2
|
||||
.export __heapblocksize
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
;
|
||||
;
|
||||
|
||||
.importzp ptr1, ptr2
|
||||
.export __heapmaxavail
|
||||
.importzp ptr1, ptr2
|
||||
.export __heapmaxavail
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Code
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
;
|
||||
;
|
||||
|
||||
.importzp ptr1, ptr2
|
||||
.export __heapmemavail
|
||||
.importzp ptr1, ptr2
|
||||
.export __heapmemavail
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Code
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
; /* Operating system specific errors from the low level functions */
|
||||
|
||||
|
||||
.export __oserror
|
||||
.export __oserror
|
||||
|
||||
.bss
|
||||
|
||||
__oserror:
|
||||
.res 1
|
||||
.res 1
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@ typedef void (*outfunc) (struct outdesc* desc, const char* buf, unsigned count);
|
||||
* so check this when altering the structure.
|
||||
*/
|
||||
struct outdesc {
|
||||
int ccount; /* Character counter */
|
||||
outfunc fout; /* Routine used to output data */
|
||||
void* ptr; /* Data internal to print routine */
|
||||
unsigned uns; /* Data internal to print routine */
|
||||
int ccount; /* Character counter */
|
||||
outfunc fout; /* Routine used to output data */
|
||||
void* ptr; /* Data internal to print routine */
|
||||
unsigned uns; /* Data internal to print routine */
|
||||
};
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SetJmp return codes */
|
||||
/* SetJmp return codes */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -48,28 +48,28 @@ enum {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static const char* format; /* Copy of function argument */
|
||||
static const struct scanfdata* D_; /* Copy of function argument */
|
||||
static va_list ap; /* Copy of function argument */
|
||||
static jmp_buf JumpBuf; /* "Label" that is used for failures */
|
||||
static char F; /* Character from format string */
|
||||
static va_list ap; /* Copy of function argument */
|
||||
static jmp_buf JumpBuf; /* "Label" that is used for failures */
|
||||
static char F; /* Character from format string */
|
||||
static unsigned CharCount; /* Characters read so far */
|
||||
static int C; /* Character from input */
|
||||
static unsigned Width; /* Maximum field width */
|
||||
static long IntVal; /* Converted int value */
|
||||
static int Assignments; /* Number of assignments */
|
||||
static int C; /* Character from input */
|
||||
static unsigned Width; /* Maximum field width */
|
||||
static long IntVal; /* Converted int value */
|
||||
static int Assignments; /* Number of assignments */
|
||||
static unsigned char IntBytes; /* Number of bytes-1 for int conversions */
|
||||
|
||||
/* Flags */
|
||||
static bool Converted; /* Some object was converted */
|
||||
static bool Positive; /* Flag for positive value */
|
||||
static bool NoAssign; /* Suppress assignment */
|
||||
static bool Invert; /* Do we need to invert the charset? */
|
||||
static bool Converted; /* Some object was converted */
|
||||
static bool Positive; /* Flag for positive value */
|
||||
static bool NoAssign; /* Suppress assignment */
|
||||
static bool Invert; /* Do we need to invert the charset? */
|
||||
static unsigned char CharSet[(1+UCHAR_MAX)/CHAR_BIT];
|
||||
static const unsigned char Bits[CHAR_BIT] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
|
||||
@@ -87,7 +87,7 @@ static const unsigned char Bits[CHAR_BIT] = {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Character sets */
|
||||
/* Character sets */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ static unsigned char IsCharInSet (void)
|
||||
/* Get the character from C. */
|
||||
asm ("lda #$00");
|
||||
asm ("ldx %v+1", C);
|
||||
asm ("bne L1"); /* EOF never is in the set */
|
||||
asm ("bne L1"); /* EOF never is in the set */
|
||||
asm ("lda %v", C);
|
||||
FindBit();
|
||||
asm ("and %v,x", CharSet);
|
||||
@@ -165,7 +165,7 @@ static void InvertCharSet (void)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ static void __fastcall__ ScanInt (unsigned char Base)
|
||||
case 'x':
|
||||
case 'X':
|
||||
Base = 16;
|
||||
Converted = true;
|
||||
Converted = true;
|
||||
ReadChar ();
|
||||
break;
|
||||
default:
|
||||
@@ -481,7 +481,7 @@ static char GetFormat (void)
|
||||
|
||||
|
||||
int __fastcall__ _scanf (const struct scanfdata* D,
|
||||
const char* format_, va_list ap_)
|
||||
const char* format_, va_list ap_)
|
||||
/* This is the routine used to do the actual work. It is called from several
|
||||
* types of wrappers to implement the actual ISO xxscanf functions.
|
||||
*/
|
||||
@@ -519,16 +519,16 @@ Again:
|
||||
/* Check for a conversion */
|
||||
if (F != '%') {
|
||||
|
||||
/* Check for a match */
|
||||
if ((bool) isspace ((int) F)) {
|
||||
/* Check for a match */
|
||||
if ((bool) isspace ((int) F)) {
|
||||
|
||||
/* Special white space handling: Any whitespace in the
|
||||
/* Special white space handling: Any whitespace in the
|
||||
* format string matches any amount of whitespace including
|
||||
* none(!). So this match will never fail.
|
||||
*/
|
||||
SkipWhite ();
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
SkipWhite ();
|
||||
continue;
|
||||
}
|
||||
|
||||
Percent:
|
||||
/* ### Note: The opposite test (C == F)
|
||||
@@ -540,27 +540,27 @@ Percent:
|
||||
* and return the number of assigned conversions.
|
||||
*/
|
||||
goto NoConv;
|
||||
}
|
||||
}
|
||||
|
||||
/* A match -- get the next input character, and continue. */
|
||||
goto Again;
|
||||
|
||||
} else {
|
||||
|
||||
/* A conversion. Skip the percent sign. */
|
||||
/* 0. Check for %% */
|
||||
if (GetFormat () == '%') {
|
||||
goto Percent;
|
||||
}
|
||||
/* A conversion. Skip the percent sign. */
|
||||
/* 0. Check for %% */
|
||||
if (GetFormat () == '%') {
|
||||
goto Percent;
|
||||
}
|
||||
|
||||
/* 1. Assignment suppression */
|
||||
/* 1. Assignment suppression */
|
||||
NoAssign = (F == '*');
|
||||
if (NoAssign) {
|
||||
GetFormat ();
|
||||
}
|
||||
|
||||
/* 2. Maximum field width */
|
||||
Width = UINT_MAX;
|
||||
Width = UINT_MAX;
|
||||
HaveWidth = (bool) isdigit (F);
|
||||
if (HaveWidth) {
|
||||
Width = 0;
|
||||
@@ -594,7 +594,7 @@ Percent:
|
||||
IntBytes = sizeof(char) - 1;
|
||||
++format;
|
||||
}
|
||||
GetFormat ();
|
||||
GetFormat ();
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
@@ -605,14 +605,14 @@ Percent:
|
||||
/* FALLTHROUGH */
|
||||
case 'j': /* intmax_t */
|
||||
IntBytes = sizeof(long) - 1;
|
||||
/* FALLTHROUGH */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 'z': /* size_t */
|
||||
case 't': /* ptrdiff_t */
|
||||
/* Same size as int */
|
||||
/* Same size as int */
|
||||
|
||||
case 'L': /* long double - ignore this one */
|
||||
GetFormat ();
|
||||
GetFormat ();
|
||||
}
|
||||
|
||||
/* 4. Conversion specifier */
|
||||
@@ -621,92 +621,92 @@ Percent:
|
||||
* standard says that even the 'u' modifier allows an
|
||||
* optionally signed integer.
|
||||
*/
|
||||
case 'd': /* Optionally signed decimal integer */
|
||||
case 'd': /* Optionally signed decimal integer */
|
||||
case 'u':
|
||||
ScanInt (10);
|
||||
break;
|
||||
ScanInt (10);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
/* Optionally signed integer with a base */
|
||||
ScanInt (0);
|
||||
break;
|
||||
case 'i':
|
||||
/* Optionally signed integer with a base */
|
||||
ScanInt (0);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
/* Optionally signed octal integer */
|
||||
ScanInt (8);
|
||||
break;
|
||||
case 'o':
|
||||
/* Optionally signed octal integer */
|
||||
ScanInt (8);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
/* Optionally signed hexadecimal integer */
|
||||
ScanInt (16);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
/* Optionally signed hexadecimal integer */
|
||||
ScanInt (16);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
/* Whitespace-terminated string */
|
||||
SkipWhite ();
|
||||
CheckEnd (); /* Is it an input failure? */
|
||||
case 's':
|
||||
/* Whitespace-terminated string */
|
||||
SkipWhite ();
|
||||
CheckEnd (); /* Is it an input failure? */
|
||||
Converted = true; /* No, conversion will succeed */
|
||||
if (NoAssign == false) {
|
||||
S = va_arg (ap, char*);
|
||||
}
|
||||
while (C != EOF
|
||||
&& (bool) isspace (C) == false
|
||||
&& ++Width) {
|
||||
if (NoAssign == false) {
|
||||
*S++ = C;
|
||||
}
|
||||
ReadChar ();
|
||||
}
|
||||
/* Terminate the string just read */
|
||||
if (NoAssign == false) {
|
||||
*S = '\0';
|
||||
++Assignments;
|
||||
}
|
||||
break;
|
||||
if (NoAssign == false) {
|
||||
S = va_arg (ap, char*);
|
||||
}
|
||||
while (C != EOF
|
||||
&& (bool) isspace (C) == false
|
||||
&& ++Width) {
|
||||
if (NoAssign == false) {
|
||||
*S++ = C;
|
||||
}
|
||||
ReadChar ();
|
||||
}
|
||||
/* Terminate the string just read */
|
||||
if (NoAssign == false) {
|
||||
*S = '\0';
|
||||
++Assignments;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
/* Fixed-length string, NOT zero-terminated */
|
||||
if (HaveWidth == false) {
|
||||
/* No width given, default is 1 */
|
||||
Width = ~1u;
|
||||
}
|
||||
CheckEnd (); /* Is it an input failure? */
|
||||
Converted = true; /* No, at least 1 char. available */
|
||||
if (NoAssign == false) {
|
||||
S = va_arg (ap, char*);
|
||||
/* ## This loop is convenient for us, but it isn't
|
||||
* standard C. The standard implies that a failure
|
||||
* shouldn't put anything into the array argument.
|
||||
*/
|
||||
/* Fixed-length string, NOT zero-terminated */
|
||||
if (HaveWidth == false) {
|
||||
/* No width given, default is 1 */
|
||||
Width = ~1u;
|
||||
}
|
||||
CheckEnd (); /* Is it an input failure? */
|
||||
Converted = true; /* No, at least 1 char. available */
|
||||
if (NoAssign == false) {
|
||||
S = va_arg (ap, char*);
|
||||
/* ## This loop is convenient for us, but it isn't
|
||||
* standard C. The standard implies that a failure
|
||||
* shouldn't put anything into the array argument.
|
||||
*/
|
||||
while (++Width) {
|
||||
CheckEnd (); /* Is it a matching failure? */
|
||||
CheckEnd (); /* Is it a matching failure? */
|
||||
*S++ = C;
|
||||
ReadChar ();
|
||||
}
|
||||
++Assignments;
|
||||
} else {
|
||||
++Assignments;
|
||||
} else {
|
||||
/* Just skip as many chars as given */
|
||||
while (++Width) {
|
||||
CheckEnd (); /* Is it a matching failure? */
|
||||
CheckEnd (); /* Is it a matching failure? */
|
||||
ReadChar ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
/* String using characters from a set */
|
||||
/* String using characters from a set */
|
||||
/* Clear the set */
|
||||
memset (CharSet, 0, sizeof (CharSet));
|
||||
/* Skip the left-bracket, and test for inversion. */
|
||||
Invert = (GetFormat () == '^');
|
||||
/* Skip the left-bracket, and test for inversion. */
|
||||
Invert = (GetFormat () == '^');
|
||||
if (Invert) {
|
||||
GetFormat ();
|
||||
}
|
||||
if (F == ']') {
|
||||
/* Empty sets aren't allowed; so, a right-bracket
|
||||
* at the beginning must be a member of the set.
|
||||
*/
|
||||
/* Empty sets aren't allowed; so, a right-bracket
|
||||
* at the beginning must be a member of the set.
|
||||
*/
|
||||
AddCharToSet (F);
|
||||
GetFormat ();
|
||||
}
|
||||
@@ -761,10 +761,10 @@ Percent:
|
||||
*/
|
||||
Match = false;
|
||||
if (NoAssign == false) {
|
||||
S = va_arg (ap, char*);
|
||||
S = va_arg (ap, char*);
|
||||
}
|
||||
while (IsCharInSet () && ++Width) {
|
||||
if (NoAssign == false) {
|
||||
if (NoAssign == false) {
|
||||
*S++ = C;
|
||||
}
|
||||
Match = Converted = true;
|
||||
@@ -778,17 +778,17 @@ Percent:
|
||||
*S = '\0';
|
||||
++Assignments;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
/* Pointer, general format is 0xABCD.
|
||||
/* Pointer, general format is 0xABCD.
|
||||
* %hhp --> zero-page pointer
|
||||
* %hp --> near pointer
|
||||
* %lp --> far pointer
|
||||
*/
|
||||
SkipWhite ();
|
||||
*/
|
||||
SkipWhite ();
|
||||
if (CHAR (C) != '0') {
|
||||
goto NoConv;
|
||||
goto NoConv;
|
||||
}
|
||||
Converted = true;
|
||||
ReadChar ();
|
||||
@@ -809,32 +809,32 @@ Percent:
|
||||
* (the read-ahead character hasn't been consumed).
|
||||
*/
|
||||
IntVal = (long) (CharCount - (C == EOF ? 0u : 1u));
|
||||
AssignInt ();
|
||||
AssignInt ();
|
||||
/* Don't count it. */
|
||||
if (NoAssign == false) {
|
||||
--Assignments;
|
||||
--Assignments;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
case 'C':
|
||||
case 'S':
|
||||
case 'C':
|
||||
/* Wide characters */
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'g':
|
||||
case 'G':
|
||||
/* Optionally signed float */
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'g':
|
||||
case 'G':
|
||||
/* Optionally signed float */
|
||||
|
||||
/* Those 2 groups aren't implemented. */
|
||||
_seterrno (ENOSYS);
|
||||
Assignments = EOF;
|
||||
PushBack ();
|
||||
return Assignments;
|
||||
PushBack ();
|
||||
return Assignments;
|
||||
|
||||
default:
|
||||
/* Invalid specification */
|
||||
@@ -853,7 +853,7 @@ NoConv:
|
||||
* the number of assignments is returned (the default behaviour).
|
||||
*/
|
||||
if (C == EOF && Converted == false) {
|
||||
Assignments = EOF; /* Special case: error */
|
||||
Assignments = EOF; /* Special case: error */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@ typedef int __fastcall__ (*ungetfunc) (int c, void* data);
|
||||
* file, so check this when altering the structure.
|
||||
*/
|
||||
struct scanfdata {
|
||||
getfunc get; /* Pointer to input routine */
|
||||
ungetfunc unget; /* Pointer to pushback routine */
|
||||
void* data; /* Pointer to struct. used outside of _scanf() */
|
||||
getfunc get; /* Pointer to input routine */
|
||||
ungetfunc unget; /* Pointer to pushback routine */
|
||||
void* data; /* Pointer to struct. used outside of _scanf() */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
; currently only called from asm code.
|
||||
;
|
||||
|
||||
.include "errno.inc"
|
||||
.include "errno.inc"
|
||||
|
||||
.code
|
||||
|
||||
|
||||
@@ -4,42 +4,42 @@
|
||||
; void __fastcall__ _swap (void* p, void* q, size_t size);
|
||||
;
|
||||
|
||||
.export __swap
|
||||
.import popax
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.export __swap
|
||||
.import popax
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
|
||||
|
||||
__swap: eor #$FF
|
||||
sta ptr3
|
||||
__swap: eor #$FF
|
||||
sta ptr3
|
||||
txa
|
||||
eor #$FF
|
||||
sta ptr3+1 ; Save -(size+1) into ptr3
|
||||
sta ptr3+1 ; Save -(size+1) into ptr3
|
||||
|
||||
jsr popax ; Get q
|
||||
sta ptr2
|
||||
stx ptr2+1
|
||||
jsr popax ; Get q
|
||||
sta ptr2
|
||||
stx ptr2+1
|
||||
|
||||
jsr popax ; Get p
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
jsr popax ; Get p
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
; Prepare for swap
|
||||
|
||||
ldy #$00
|
||||
ldy #$00
|
||||
|
||||
; Swap loop
|
||||
|
||||
@L1: inc ptr3 ; Bump counter low byte
|
||||
beq @L3 ; Branch on overflow
|
||||
|
||||
@L2: lda (ptr1),y
|
||||
tax
|
||||
lda (ptr2),y
|
||||
sta (ptr1),y
|
||||
txa
|
||||
sta (ptr2),y
|
||||
iny
|
||||
bne @L1
|
||||
@L2: lda (ptr1),y
|
||||
tax
|
||||
lda (ptr2),y
|
||||
sta (ptr1),y
|
||||
txa
|
||||
sta (ptr2),y
|
||||
iny
|
||||
bne @L1
|
||||
inc ptr1+1
|
||||
inc ptr2+1
|
||||
bne @L1 ; Branch always (hopefully)
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
; Ullrich von Bassewitz, 16.12.1998
|
||||
;
|
||||
|
||||
.export __sys
|
||||
.import jmpvec
|
||||
.importzp ptr1
|
||||
.export __sys
|
||||
.import jmpvec
|
||||
.importzp ptr1
|
||||
|
||||
|
||||
__sys: sta ptr1
|
||||
stx ptr1+1 ; Save the pointer to r
|
||||
__sys: sta ptr1
|
||||
stx ptr1+1 ; Save the pointer to r
|
||||
|
||||
; Fetch the PC and store it into the jump vector
|
||||
|
||||
ldy #5
|
||||
lda (ptr1),y
|
||||
sta jmpvec+2
|
||||
dey
|
||||
lda (ptr1),y
|
||||
sta jmpvec+1
|
||||
ldy #5
|
||||
lda (ptr1),y
|
||||
sta jmpvec+2
|
||||
dey
|
||||
lda (ptr1),y
|
||||
sta jmpvec+1
|
||||
|
||||
; Remember the flags so we can restore them to a known state after calling the
|
||||
; routine
|
||||
@@ -29,51 +29,51 @@ __sys: sta ptr1
|
||||
; Get the flags, keep the state of bit 4 and 5 using the other flags from
|
||||
; the flags value passed by the caller. Push the new flags and push A.
|
||||
|
||||
dey
|
||||
dey
|
||||
php
|
||||
pla ; Current flags -> A
|
||||
eor (ptr1),y
|
||||
and #%00110000
|
||||
eor (ptr1),y
|
||||
pha ; Push new flags value
|
||||
ldy #0
|
||||
lda (ptr1),y
|
||||
pha
|
||||
pha ; Push new flags value
|
||||
ldy #0
|
||||
lda (ptr1),y
|
||||
pha
|
||||
|
||||
; Get and assign X and Y
|
||||
|
||||
iny
|
||||
lda (ptr1),y
|
||||
tax
|
||||
iny
|
||||
lda (ptr1),y
|
||||
tay
|
||||
iny
|
||||
lda (ptr1),y
|
||||
tax
|
||||
iny
|
||||
lda (ptr1),y
|
||||
tay
|
||||
|
||||
; Set a and the flags, call the machine code routine
|
||||
|
||||
pla
|
||||
plp
|
||||
jsr jmpvec
|
||||
pla
|
||||
plp
|
||||
jsr jmpvec
|
||||
|
||||
; Back from the routine. Save the flags and A.
|
||||
|
||||
php
|
||||
pha
|
||||
php
|
||||
pha
|
||||
|
||||
; Put the register values into the regs structure
|
||||
|
||||
tya
|
||||
ldy #2
|
||||
sta (ptr1),y
|
||||
dey
|
||||
txa
|
||||
sta (ptr1),y
|
||||
dey
|
||||
pla
|
||||
sta (ptr1),y
|
||||
ldy #3
|
||||
pla
|
||||
sta (ptr1),y
|
||||
tya
|
||||
ldy #2
|
||||
sta (ptr1),y
|
||||
dey
|
||||
txa
|
||||
sta (ptr1),y
|
||||
dey
|
||||
pla
|
||||
sta (ptr1),y
|
||||
ldy #3
|
||||
pla
|
||||
sta (ptr1),y
|
||||
|
||||
; Restore the old flags value
|
||||
|
||||
@@ -81,5 +81,5 @@ __sys: sta ptr1
|
||||
|
||||
; Done
|
||||
|
||||
rts
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
; int abs (int x);
|
||||
;
|
||||
|
||||
.export _abs
|
||||
.import negax
|
||||
.export _abs
|
||||
.import negax
|
||||
|
||||
_abs: cpx #$00 ; test hi byte
|
||||
bpl L1
|
||||
jmp negax ; Negate if negative
|
||||
L1: rts
|
||||
_abs: cpx #$00 ; test hi byte
|
||||
bpl L1
|
||||
jmp negax ; Negate if negative
|
||||
L1: rts
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,44 +4,44 @@
|
||||
; int atexit (void (*f) (void));
|
||||
;
|
||||
|
||||
.export _atexit
|
||||
.destructor doatexit, 17
|
||||
.import callax
|
||||
.export _atexit
|
||||
.destructor doatexit, 17
|
||||
.import callax
|
||||
|
||||
.include "errno.inc"
|
||||
.include "errno.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
.proc _atexit
|
||||
.proc _atexit
|
||||
|
||||
ldy exitfunc_index
|
||||
cpy #exitfunc_max ; Slot available?
|
||||
beq @Error ; Jump if no
|
||||
ldy exitfunc_index
|
||||
cpy #exitfunc_max ; Slot available?
|
||||
beq @Error ; Jump if no
|
||||
|
||||
; Enter the function into the table
|
||||
|
||||
sta exitfunc_table,y
|
||||
iny
|
||||
txa
|
||||
sta exitfunc_table,y
|
||||
iny
|
||||
sty exitfunc_index
|
||||
sta exitfunc_table,y
|
||||
iny
|
||||
txa
|
||||
sta exitfunc_table,y
|
||||
iny
|
||||
sty exitfunc_index
|
||||
|
||||
; Done, return zero
|
||||
|
||||
lda #0
|
||||
tax
|
||||
rts
|
||||
lda #0
|
||||
tax
|
||||
rts
|
||||
|
||||
; Error, no space left
|
||||
|
||||
@Error: lda #ENOSPC ; No space left
|
||||
@Error: lda #ENOSPC ; No space left
|
||||
jsr __seterrno
|
||||
ldx #$FF ; Return -1
|
||||
txa
|
||||
rts
|
||||
ldx #$FF ; Return -1
|
||||
txa
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
@@ -51,24 +51,24 @@
|
||||
|
||||
.code
|
||||
|
||||
.proc doatexit
|
||||
.proc doatexit
|
||||
|
||||
ldy exitfunc_index ; Get index
|
||||
beq @L9 ; Jump if done
|
||||
dey
|
||||
lda exitfunc_table,y
|
||||
tax
|
||||
dey
|
||||
lda exitfunc_table,y
|
||||
sty exitfunc_index
|
||||
jsr callax ; Call the function
|
||||
ldy exitfunc_index ; Get index
|
||||
beq @L9 ; Jump if done
|
||||
dey
|
||||
lda exitfunc_table,y
|
||||
tax
|
||||
dey
|
||||
lda exitfunc_table,y
|
||||
sty exitfunc_index
|
||||
jsr callax ; Call the function
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
bra doatexit
|
||||
bra doatexit
|
||||
.else
|
||||
jmp doatexit ; Next one
|
||||
jmp doatexit ; Next one
|
||||
.endif
|
||||
|
||||
@L9: rts
|
||||
@L9: rts
|
||||
|
||||
.endproc
|
||||
|
||||
@@ -77,8 +77,8 @@
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
.bss
|
||||
exitfunc_index: .res 1 ; Index into table, inc'ed by 2
|
||||
exitfunc_table: .res 10 ; 5 exit functions
|
||||
exitfunc_max = <(* - exitfunc_table)
|
||||
exitfunc_index: .res 1 ; Index into table, inc'ed by 2
|
||||
exitfunc_table: .res 10 ; 5 exit functions
|
||||
exitfunc_max = <(* - exitfunc_table)
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
; long atol (const char* s);
|
||||
;
|
||||
|
||||
.export _atoi, _atol
|
||||
.import negeax, __ctype
|
||||
.importzp sreg, ptr1, ptr2, tmp1
|
||||
.export _atoi, _atol
|
||||
.import negeax, __ctype
|
||||
.importzp sreg, ptr1, ptr2, tmp1
|
||||
|
||||
.include "ctype.inc"
|
||||
|
||||
@@ -16,100 +16,100 @@
|
||||
;
|
||||
|
||||
_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
|
||||
_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
|
||||
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
|
||||
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
|
||||
bne L5
|
||||
inc ptr1+1
|
||||
|
||||
; Store the sign flag and setup for conversion
|
||||
|
||||
L5: stx tmp1 ; remember sign flag
|
||||
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
|
||||
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
|
||||
jsr mul2 ; * 2
|
||||
|
||||
lda sreg+1
|
||||
pha
|
||||
lda sreg
|
||||
pha
|
||||
lda ptr2+1
|
||||
pha
|
||||
lda ptr2
|
||||
pha ; Save value
|
||||
lda sreg+1
|
||||
pha
|
||||
lda sreg
|
||||
pha
|
||||
lda ptr2+1
|
||||
pha
|
||||
lda ptr2
|
||||
pha ; Save value
|
||||
|
||||
jsr mul2 ; * 4
|
||||
jsr mul2 ; * 8
|
||||
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
|
||||
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
|
||||
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
|
||||
L7: iny
|
||||
bne L6
|
||||
inc ptr1+1
|
||||
bne L6
|
||||
|
||||
; Conversion done. Load the low 16 bit into A/X
|
||||
|
||||
@@ -118,8 +118,8 @@ L8: lda ptr2
|
||||
|
||||
; Negate the value if necessary, otherwise we're done
|
||||
|
||||
ldy tmp1 ; sign
|
||||
beq L9 ; Branch if positive
|
||||
ldy tmp1 ; sign
|
||||
beq L9 ; Branch if positive
|
||||
|
||||
; Negate the 32 bit value in ptr2/sreg
|
||||
|
||||
@@ -129,10 +129,10 @@ L8: lda ptr2
|
||||
; Helper functions
|
||||
;
|
||||
|
||||
mul2: asl ptr2
|
||||
rol ptr2+1
|
||||
rol sreg
|
||||
rol sreg+1 ; * 2
|
||||
mul2: asl ptr2
|
||||
rol ptr2+1
|
||||
rol sreg
|
||||
rol sreg+1 ; * 2
|
||||
L9: rts
|
||||
|
||||
|
||||
|
||||
@@ -22,23 +22,23 @@ void* __fastcall__ bsearch (const void* key, const void* base, size_t n,
|
||||
/* Binary search */
|
||||
while (first <= last) {
|
||||
|
||||
/* Set current to mid of range */
|
||||
current = (last + first) / 2;
|
||||
/* Set current to mid of range */
|
||||
current = (last + first) / 2;
|
||||
|
||||
/* Do a compare */
|
||||
result = cmp ((void*) (((int) base) + current*size), key);
|
||||
/* Do a compare */
|
||||
result = cmp ((void*) (((int) base) + current*size), key);
|
||||
if (result < 0) {
|
||||
first = current + 1;
|
||||
} else {
|
||||
last = current - 1;
|
||||
if (result == 0) {
|
||||
/* Found one entry that matches the search key. However there may be
|
||||
* more than one entry with the same key value and ANSI guarantees
|
||||
* that we return the first of a row of items with the same key.
|
||||
*/
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
first = current + 1;
|
||||
} else {
|
||||
last = current - 1;
|
||||
if (result == 0) {
|
||||
/* Found one entry that matches the search key. However there may be
|
||||
* more than one entry with the same key value and ANSI guarantees
|
||||
* that we return the first of a row of items with the same key.
|
||||
*/
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we find the entry? */
|
||||
|
||||
@@ -6,49 +6,49 @@
|
||||
; void* __fastcall__ calloc (size_t count, size_t size);
|
||||
;
|
||||
|
||||
.export _calloc
|
||||
.import _malloc, __bzero
|
||||
.import tosumulax, pushax
|
||||
.export _calloc
|
||||
.import _malloc, __bzero
|
||||
.import tosumulax, pushax
|
||||
|
||||
|
||||
; -------------------------------------------------------------------------
|
||||
|
||||
.proc _calloc
|
||||
.proc _calloc
|
||||
|
||||
; We have the first argument in a/x and the second on the stack. Calling
|
||||
; tosumulax will give the product of both in a/x.
|
||||
|
||||
jsr tosumulax
|
||||
jsr tosumulax
|
||||
|
||||
; Save size for later
|
||||
|
||||
sta Size
|
||||
stx Size+1
|
||||
sta Size
|
||||
stx Size+1
|
||||
|
||||
; malloc() is a fastcall function, so we do already have the argument in
|
||||
; the right place
|
||||
|
||||
jsr _malloc
|
||||
jsr _malloc
|
||||
|
||||
; Check for a NULL pointer
|
||||
|
||||
cpx #0
|
||||
bne ClearBlock
|
||||
cmp #0
|
||||
bne ClearBlock
|
||||
cpx #0
|
||||
bne ClearBlock
|
||||
cmp #0
|
||||
bne ClearBlock
|
||||
|
||||
; We have a NULL pointer, bail out
|
||||
|
||||
rts
|
||||
rts
|
||||
|
||||
; No NULL pointer, clear the block. _bzero will return a pointer to the
|
||||
; block which is exactly what we want.
|
||||
|
||||
ClearBlock:
|
||||
jsr pushax ; ptr
|
||||
lda Size
|
||||
ldx Size+1 ; Size
|
||||
jmp __bzero
|
||||
jsr pushax ; ptr
|
||||
lda Size
|
||||
ldx Size+1 ; Size
|
||||
jmp __bzero
|
||||
|
||||
.endproc
|
||||
|
||||
@@ -57,7 +57,7 @@ ClearBlock:
|
||||
|
||||
.bss
|
||||
|
||||
Size: .res 2
|
||||
Size: .res 2
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; CC65 library: 32by16 => 16 signed division
|
||||
;
|
||||
|
||||
.export _cc65_idiv32by16r16
|
||||
.export _cc65_idiv32by16r16
|
||||
.import idiv32by16r16, incsp4
|
||||
|
||||
.include "zeropage.inc"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; CC65 library: 32by16 => 16 unsigned division
|
||||
;
|
||||
|
||||
.export _cc65_udiv32by16r16
|
||||
.export _cc65_udiv32by16r16
|
||||
.import udiv32by16r16m, incsp4
|
||||
|
||||
.include "zeropage.inc"
|
||||
|
||||
@@ -4,21 +4,21 @@
|
||||
; Copy the data segment from the LOAD to the RUN location
|
||||
;
|
||||
|
||||
.export copydata
|
||||
.import __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
|
||||
.importzp ptr1, ptr2, tmp1
|
||||
.export copydata
|
||||
.import __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
|
||||
.importzp ptr1, ptr2, tmp1
|
||||
|
||||
|
||||
copydata:
|
||||
lda #<__DATA_LOAD__ ; Source pointer
|
||||
sta ptr1
|
||||
lda #>__DATA_LOAD__
|
||||
sta ptr1+1
|
||||
lda #<__DATA_LOAD__ ; Source pointer
|
||||
sta ptr1
|
||||
lda #>__DATA_LOAD__
|
||||
sta ptr1+1
|
||||
|
||||
lda #<__DATA_RUN__ ; Target pointer
|
||||
sta ptr2
|
||||
lda #>__DATA_RUN__
|
||||
sta ptr2+1
|
||||
lda #<__DATA_RUN__ ; Target pointer
|
||||
sta ptr2
|
||||
lda #>__DATA_RUN__
|
||||
sta ptr2+1
|
||||
|
||||
ldx #<~__DATA_SIZE__
|
||||
lda #>~__DATA_SIZE__ ; Use -(__DATASIZE__+1)
|
||||
@@ -30,13 +30,13 @@ copydata:
|
||||
@L1: inx
|
||||
beq @L3
|
||||
|
||||
@L2: lda (ptr1),y
|
||||
sta (ptr2),y
|
||||
@L2: lda (ptr1),y
|
||||
sta (ptr2),y
|
||||
iny
|
||||
bne @L1
|
||||
inc ptr1+1
|
||||
inc ptr2+1 ; Bump pointers
|
||||
bne @L1 ; Branch always (hopefully)
|
||||
inc ptr1+1
|
||||
inc ptr2+1 ; Bump pointers
|
||||
bne @L1 ; Branch always (hopefully)
|
||||
|
||||
; Bump the high counter byte
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; char* __fastcall__ ctime (time_t* timep);
|
||||
;
|
||||
|
||||
.export _ctime
|
||||
.export _ctime
|
||||
.import _localtime, _asctime
|
||||
|
||||
|
||||
|
||||
@@ -12,23 +12,23 @@
|
||||
; div_t __fastcall__ div (int numer, int denom);
|
||||
;
|
||||
|
||||
.export _div
|
||||
.export _div
|
||||
|
||||
.import tosdivax, negax
|
||||
.importzp sreg, ptr1, tmp1
|
||||
.import tosdivax, negax
|
||||
.importzp sreg, ptr1, tmp1
|
||||
|
||||
_div: jsr tosdivax ; Division-operator does most of the work
|
||||
sta sreg ; Quotient is in sreg
|
||||
_div: jsr tosdivax ; Division-operator does most of the work
|
||||
sta sreg ; Quotient is in sreg
|
||||
stx sreg+1
|
||||
lda ptr1 ; Unsigned remainder is in ptr1
|
||||
lda ptr1 ; Unsigned remainder is in ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Adjust the sign of the remainder.
|
||||
; It must be the same as the sign of the dividend.
|
||||
;
|
||||
bit tmp1 ; Load high-byte of left argument
|
||||
bpl Pos ; Jump if sign-of-result is positive
|
||||
jmp negax ; Result is negative, adjust the sign
|
||||
bit tmp1 ; Load high-byte of left argument
|
||||
bpl Pos ; Jump if sign-of-result is positive
|
||||
jmp negax ; Result is negative, adjust the sign
|
||||
|
||||
Pos: rts
|
||||
Pos: rts
|
||||
|
||||
|
||||
@@ -43,5 +43,5 @@ ok: rts
|
||||
.bss
|
||||
|
||||
__errno:
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ FILE* __fastcall__ fdopen (int handle, const char* /*mode*/)
|
||||
f->f_fd = handle;
|
||||
f->f_flags = _FOPEN;
|
||||
} else {
|
||||
/* No slots */
|
||||
_seterrno (EMFILE); /* Too many files */
|
||||
/* No slots */
|
||||
_seterrno (EMFILE); /* Too many files */
|
||||
}
|
||||
|
||||
/* Return the file descriptor */
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ int __fastcall__ fgetc (register FILE* f)
|
||||
|
||||
/* Check if the file is open or if there is an error condition */
|
||||
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
|
||||
return EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have a pushed back character, return it */
|
||||
@@ -38,18 +38,18 @@ int __fastcall__ fgetc (register FILE* f)
|
||||
switch (read (f->f_fd, &c, 1)) {
|
||||
|
||||
case -1:
|
||||
/* Error */
|
||||
f->f_flags |= _FERROR;
|
||||
return EOF;
|
||||
/* Error */
|
||||
f->f_flags |= _FERROR;
|
||||
return EOF;
|
||||
|
||||
case 0:
|
||||
/* EOF */
|
||||
f->f_flags |= _FEOF;
|
||||
return EOF;
|
||||
/* EOF */
|
||||
f->f_flags |= _FEOF;
|
||||
return EOF;
|
||||
|
||||
default:
|
||||
/* Char read */
|
||||
return c;
|
||||
/* Char read */
|
||||
return c;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -33,28 +33,28 @@ char* __fastcall__ fgets (char* s, unsigned size, register FILE* f)
|
||||
i = 0;
|
||||
while (--size) {
|
||||
|
||||
/* Get next character */
|
||||
if ((c = fgetc (f)) == EOF) {
|
||||
/* Error or EOF */
|
||||
if ((f->f_flags & _FERROR) != 0 || i == 0) {
|
||||
/* ERROR or EOF on first char */
|
||||
/* Get next character */
|
||||
if ((c = fgetc (f)) == EOF) {
|
||||
/* Error or EOF */
|
||||
if ((f->f_flags & _FERROR) != 0 || i == 0) {
|
||||
/* ERROR or EOF on first char */
|
||||
*p = '\0';
|
||||
return 0;
|
||||
} else {
|
||||
/* EOF with data already read */
|
||||
return 0;
|
||||
} else {
|
||||
/* EOF with data already read */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* One char more */
|
||||
*p = c;
|
||||
/* One char more */
|
||||
*p = c;
|
||||
++p;
|
||||
++i;
|
||||
|
||||
/* Stop at end of line */
|
||||
if ((char)c == '\n') {
|
||||
break;
|
||||
}
|
||||
/* Stop at end of line */
|
||||
if ((char)c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the string */
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
; Several small file stream functions
|
||||
;
|
||||
|
||||
.export _clearerr, _feof, _ferror, _fileno, _fflush
|
||||
.import return0
|
||||
.importzp ptr1
|
||||
.export _clearerr, _feof, _ferror, _fileno, _fflush
|
||||
.import return0
|
||||
.importzp ptr1
|
||||
|
||||
.include "_file.inc"
|
||||
.include "errno.inc"
|
||||
@@ -16,12 +16,12 @@
|
||||
; and zero flag set in case of an error.
|
||||
|
||||
.proc getf
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y ; get f->f_flags
|
||||
and #_FOPEN ; file open?
|
||||
rts
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y ; get f->f_flags
|
||||
and #_FOPEN ; file open?
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;
|
||||
@@ -29,12 +29,12 @@
|
||||
;
|
||||
|
||||
.proc _clearerr
|
||||
jsr getf
|
||||
beq err
|
||||
lda (ptr1),y
|
||||
and #<~(_FEOF | _FERROR)
|
||||
sta (ptr1),y
|
||||
err: rts
|
||||
jsr getf
|
||||
beq err
|
||||
lda (ptr1),y
|
||||
and #<~(_FEOF | _FERROR)
|
||||
sta (ptr1),y
|
||||
err: rts
|
||||
.endproc
|
||||
|
||||
;
|
||||
@@ -42,12 +42,12 @@ err: rts
|
||||
;
|
||||
|
||||
.proc _feof
|
||||
jsr getf
|
||||
jsr getf
|
||||
beq @L1 ; Return 0 on error
|
||||
lda (ptr1),y
|
||||
and #_FEOF
|
||||
@L1: ldx #0
|
||||
rts
|
||||
lda (ptr1),y
|
||||
and #_FEOF
|
||||
@L1: ldx #0
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;
|
||||
@@ -55,12 +55,12 @@ err: rts
|
||||
;
|
||||
|
||||
.proc _ferror
|
||||
jsr getf
|
||||
jsr getf
|
||||
beq @L1 ; Return 0 on error
|
||||
lda (ptr1),y
|
||||
and #_FERROR
|
||||
@L1: ldx #0
|
||||
rts
|
||||
lda (ptr1),y
|
||||
and #_FERROR
|
||||
@L1: ldx #0
|
||||
rts
|
||||
.endproc
|
||||
|
||||
;
|
||||
@@ -68,12 +68,12 @@ err: rts
|
||||
;
|
||||
|
||||
.proc _fileno
|
||||
jsr getf
|
||||
jsr getf
|
||||
beq error
|
||||
ldy #_FILE::f_fd
|
||||
lda (ptr1),y
|
||||
ldx #0
|
||||
rts
|
||||
ldy #_FILE::f_fd
|
||||
lda (ptr1),y
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
; If the file is not valid, fileno must set errno and return -1
|
||||
|
||||
@@ -88,6 +88,6 @@ error: lda #<EBADF
|
||||
; int __fastcall__ fflush (FILE* f);
|
||||
;
|
||||
|
||||
_fflush = return0
|
||||
_fflush = return0
|
||||
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; Ullrich von Bassewitz, 1.12.2000
|
||||
;
|
||||
|
||||
.export _fprintf
|
||||
.import addysp, decsp4, _vfprintf
|
||||
.importzp sp, ptr1
|
||||
.export _fprintf
|
||||
.import addysp, decsp4, _vfprintf
|
||||
.importzp sp, ptr1
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Code
|
||||
@@ -24,7 +24,7 @@ ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
|
||||
_fprintf:
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
|
||||
; We have to push f and format, both in the order they already have on stack.
|
||||
; To make this somewhat more efficient, we will create space on the stack and
|
||||
@@ -33,37 +33,37 @@ _fprintf:
|
||||
; of the fixed arguments, this will allow us to calculate the pointer to the
|
||||
; fixed size arguments easier (they're just ParamSize bytes away).
|
||||
|
||||
jsr decsp4
|
||||
jsr decsp4
|
||||
|
||||
; Calculate a pointer to the Format argument
|
||||
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
|
||||
; Now copy both, f and format
|
||||
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
|
||||
; Load va_list (last and __fastcall__ parameter to vfprintf)
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Call vfprintf
|
||||
|
||||
jsr _vfprintf
|
||||
jsr _vfprintf
|
||||
|
||||
; Cleanup the stack. We will return what we got from vfprintf
|
||||
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -22,15 +22,15 @@ int __fastcall__ fputc (int c, register FILE* f)
|
||||
{
|
||||
/* Check if the file is open or if there is an error condition */
|
||||
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
|
||||
goto ReturnEOF;
|
||||
goto ReturnEOF;
|
||||
}
|
||||
|
||||
/* Write the byte */
|
||||
if (write (f->f_fd, &c, 1) != 1) {
|
||||
/* Error */
|
||||
f->f_flags |= _FERROR;
|
||||
/* Error */
|
||||
f->f_flags |= _FERROR;
|
||||
ReturnEOF:
|
||||
return EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Return the byte written */
|
||||
|
||||
@@ -17,7 +17,7 @@ int __fastcall__ fputs (const char* s, register FILE* f)
|
||||
{
|
||||
/* Check if the file is open or if there is an error condition */
|
||||
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
|
||||
return EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Write the string */
|
||||
|
||||
@@ -40,25 +40,25 @@
|
||||
|
||||
; Save the file pointer into the register bank
|
||||
|
||||
sta file
|
||||
stx file+1
|
||||
sta file
|
||||
stx file+1
|
||||
|
||||
; Check if the file is open
|
||||
|
||||
ldy #_FILE::f_flags
|
||||
lda (file),y
|
||||
and #_FOPEN ; Is the file open?
|
||||
beq @L1 ; Branch if no
|
||||
ldy #_FILE::f_flags
|
||||
lda (file),y
|
||||
and #_FOPEN ; Is the file open?
|
||||
beq @L1 ; Branch if no
|
||||
|
||||
; Check if the stream is in an error state
|
||||
|
||||
lda (file),y ; get file->f_flags again
|
||||
and #_FERROR
|
||||
beq @L2
|
||||
lda (file),y ; get file->f_flags again
|
||||
and #_FERROR
|
||||
beq @L2
|
||||
|
||||
; File not open or in error state
|
||||
|
||||
@L1: lda #EINVAL
|
||||
@L1: lda #EINVAL
|
||||
jsr __seterrno ; Set __errno, return zero in A
|
||||
tax ; a/x = 0
|
||||
jmp @L99 ; Bail out
|
||||
@@ -208,6 +208,6 @@
|
||||
; Data
|
||||
|
||||
.bss
|
||||
save: .res 2
|
||||
save: .res 2
|
||||
pb: .res 1
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
; /* Remove the last block */
|
||||
; _hptr = (unsigned*) (((int) _hptr) - f->size);
|
||||
; if (_hlast = f->prev) {
|
||||
; /* Block before is now last block */
|
||||
; /* Block before is now last block */
|
||||
; f->prev->next = 0;
|
||||
; } else {
|
||||
; /* The freelist is empty now */
|
||||
@@ -52,30 +52,30 @@
|
||||
;
|
||||
; } else {
|
||||
;
|
||||
; /* Not at heap top, enter the block into the free list */
|
||||
; _hadd (b, size);
|
||||
; /* Not at heap top, enter the block into the free list */
|
||||
; _hadd (b, size);
|
||||
;
|
||||
; }
|
||||
; }
|
||||
;
|
||||
|
||||
.importzp ptr1, ptr2, ptr3, ptr4
|
||||
.export _free, heapadd
|
||||
.importzp ptr1, ptr2, ptr3, ptr4
|
||||
.export _free, heapadd
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Code
|
||||
|
||||
_free: sta ptr2
|
||||
stx ptr2+1 ; Save block
|
||||
_free: sta ptr2
|
||||
stx ptr2+1 ; Save block
|
||||
|
||||
; Is the argument NULL? If so, bail out.
|
||||
|
||||
ora ptr2+1 ; Is the argument NULL?
|
||||
bne @L1 ; Jump if no
|
||||
ora ptr2+1 ; Is the argument NULL?
|
||||
bne @L1 ; Jump if no
|
||||
rts ; Bail out if yes
|
||||
|
||||
; There's a pointer below the user space that points to the real start of the
|
||||
@@ -84,7 +84,7 @@ _free: sta ptr2
|
||||
; block. Remember the block size in ptr1.
|
||||
|
||||
@L1: dec ptr2+1 ; Decrement high pointer byte
|
||||
ldy #$FF
|
||||
ldy #$FF
|
||||
lda (ptr2),y ; High byte of real block address
|
||||
tax
|
||||
dey
|
||||
@@ -93,91 +93,91 @@ _free: sta ptr2
|
||||
sta ptr2 ; Set ptr2 to start of real block
|
||||
|
||||
ldy #usedblock::size+1
|
||||
lda (ptr2),y ; High byte of size
|
||||
sta ptr1+1 ; Save it
|
||||
dey
|
||||
lda (ptr2),y
|
||||
sta ptr1
|
||||
lda (ptr2),y ; High byte of size
|
||||
sta ptr1+1 ; Save it
|
||||
dey
|
||||
lda (ptr2),y
|
||||
sta ptr1
|
||||
|
||||
; Check if the block is on top of the heap
|
||||
|
||||
add ptr2
|
||||
tay
|
||||
lda ptr2+1
|
||||
adc ptr1+1
|
||||
cpy __heapptr
|
||||
bne heapadd ; Add to free list
|
||||
cmp __heapptr+1
|
||||
bne heapadd
|
||||
add ptr2
|
||||
tay
|
||||
lda ptr2+1
|
||||
adc ptr1+1
|
||||
cpy __heapptr
|
||||
bne heapadd ; Add to free list
|
||||
cmp __heapptr+1
|
||||
bne heapadd
|
||||
|
||||
; The pointer is located at the heap top. Lower the heap top pointer to
|
||||
; release the block.
|
||||
|
||||
@L3: lda ptr2
|
||||
sta __heapptr
|
||||
lda ptr2+1
|
||||
sta __heapptr+1
|
||||
@L3: lda ptr2
|
||||
sta __heapptr
|
||||
lda ptr2+1
|
||||
sta __heapptr+1
|
||||
|
||||
; Check if the last block in the freelist is now at heap top. If so, remove
|
||||
; this block from the freelist.
|
||||
|
||||
lda __heaplast
|
||||
sta ptr1
|
||||
ora __heaplast+1
|
||||
beq @L9 ; Jump if free list empty
|
||||
lda __heaplast+1
|
||||
sta ptr1+1 ; Pointer to last block now in ptr1
|
||||
lda __heaplast
|
||||
sta ptr1
|
||||
ora __heaplast+1
|
||||
beq @L9 ; Jump if free list empty
|
||||
lda __heaplast+1
|
||||
sta ptr1+1 ; Pointer to last block now in ptr1
|
||||
|
||||
ldy #freeblock::size
|
||||
lda (ptr1),y ; Low byte of block size
|
||||
add ptr1
|
||||
tax
|
||||
iny ; High byte of block size
|
||||
lda (ptr1),y
|
||||
adc ptr1+1
|
||||
ldy #freeblock::size
|
||||
lda (ptr1),y ; Low byte of block size
|
||||
add ptr1
|
||||
tax
|
||||
iny ; High byte of block size
|
||||
lda (ptr1),y
|
||||
adc ptr1+1
|
||||
|
||||
cmp __heapptr+1
|
||||
bne @L9 ; Jump if last block not on top of heap
|
||||
cpx __heapptr
|
||||
bne @L9 ; Jump if last block not on top of heap
|
||||
cmp __heapptr+1
|
||||
bne @L9 ; Jump if last block not on top of heap
|
||||
cpx __heapptr
|
||||
bne @L9 ; Jump if last block not on top of heap
|
||||
|
||||
; Remove the last block
|
||||
|
||||
lda ptr1
|
||||
sta __heapptr
|
||||
lda ptr1+1
|
||||
sta __heapptr+1
|
||||
lda ptr1
|
||||
sta __heapptr
|
||||
lda ptr1+1
|
||||
sta __heapptr+1
|
||||
|
||||
; Correct the next pointer of the now last block
|
||||
|
||||
ldy #freeblock::prev+1 ; Offset of ->prev field
|
||||
lda (ptr1),y
|
||||
sta ptr2+1 ; Remember f->prev in ptr2
|
||||
sta __heaplast+1
|
||||
dey
|
||||
lda (ptr1),y
|
||||
sta ptr2 ; Remember f->prev in ptr2
|
||||
sta __heaplast
|
||||
ora __heaplast+1 ; -> prev == 0?
|
||||
bne @L8 ; Jump if free list not empty
|
||||
ldy #freeblock::prev+1 ; Offset of ->prev field
|
||||
lda (ptr1),y
|
||||
sta ptr2+1 ; Remember f->prev in ptr2
|
||||
sta __heaplast+1
|
||||
dey
|
||||
lda (ptr1),y
|
||||
sta ptr2 ; Remember f->prev in ptr2
|
||||
sta __heaplast
|
||||
ora __heaplast+1 ; -> prev == 0?
|
||||
bne @L8 ; Jump if free list not empty
|
||||
|
||||
; Free list is now empty (A = 0)
|
||||
|
||||
sta __heapfirst
|
||||
sta __heapfirst+1
|
||||
sta __heapfirst
|
||||
sta __heapfirst+1
|
||||
|
||||
; Done
|
||||
|
||||
@L9: rts
|
||||
@L9: rts
|
||||
|
||||
; Block before is now last block. ptr2 points to f->prev.
|
||||
|
||||
@L8: lda #$00
|
||||
dey ; Points to high byte of ->next
|
||||
sta (ptr2),y
|
||||
dey ; Low byte of f->prev->next
|
||||
sta (ptr2),y
|
||||
rts ; Done
|
||||
@L8: lda #$00
|
||||
dey ; Points to high byte of ->next
|
||||
sta (ptr2),y
|
||||
dey ; Low byte of f->prev->next
|
||||
sta (ptr2),y
|
||||
rts ; Done
|
||||
|
||||
; The block is not on top of the heap. Add it to the free list. This was
|
||||
; formerly a separate function called __hadd that was implemented in C as
|
||||
@@ -196,81 +196,81 @@ _free: sta ptr2
|
||||
;
|
||||
; if (size >= sizeof (struct freeblock)) {
|
||||
;
|
||||
; /* Set the admin data */
|
||||
; f = (struct freeblock*) mem;
|
||||
; f->size = size;
|
||||
; /* Set the admin data */
|
||||
; f = (struct freeblock*) mem;
|
||||
; f->size = size;
|
||||
;
|
||||
; /* Check if the freelist is empty */
|
||||
; if (_hfirst == 0) {
|
||||
; /* Check if the freelist is empty */
|
||||
; if (_hfirst == 0) {
|
||||
;
|
||||
; /* The freelist is empty until now, insert the block */
|
||||
; f->prev = 0;
|
||||
; f->next = 0;
|
||||
; _hfirst = f;
|
||||
; _hlast = f;
|
||||
; /* The freelist is empty until now, insert the block */
|
||||
; f->prev = 0;
|
||||
; f->next = 0;
|
||||
; _hfirst = f;
|
||||
; _hlast = f;
|
||||
;
|
||||
; } else {
|
||||
; } else {
|
||||
;
|
||||
; /* We have to search the free list. As we are doing so, we check
|
||||
; * if it is possible to combine this block with another already
|
||||
; * existing block. Beware: The block may be the "missing link"
|
||||
; /* We have to search the free list. As we are doing so, we check
|
||||
; * if it is possible to combine this block with another already
|
||||
; * existing block. Beware: The block may be the "missing link"
|
||||
; * between *two* other blocks.
|
||||
; */
|
||||
; left = 0;
|
||||
; right = _hfirst;
|
||||
; while (right && f > right) {
|
||||
; left = right;
|
||||
; right = right->next;
|
||||
; }
|
||||
; */
|
||||
; left = 0;
|
||||
; right = _hfirst;
|
||||
; while (right && f > right) {
|
||||
; left = right;
|
||||
; right = right->next;
|
||||
; }
|
||||
;
|
||||
;
|
||||
; /* Ok, the current block must be inserted between left and right (but
|
||||
; * beware: one of the two may be zero!). Also check for the condition
|
||||
; * that we have to merge two or three blocks.
|
||||
; */
|
||||
; if (right) {
|
||||
; /* Check if we must merge the block with the right one */
|
||||
; if (((unsigned) f) + size == (unsigned) right) {
|
||||
; /* Merge with the right block */
|
||||
; f->size += right->size;
|
||||
; if (f->next = right->next) {
|
||||
; f->next->prev = f;
|
||||
; } else {
|
||||
; /* This is now the last block */
|
||||
; _hlast = f;
|
||||
; }
|
||||
; } else {
|
||||
; /* No merge, just set the link */
|
||||
; f->next = right;
|
||||
; right->prev = f;
|
||||
; }
|
||||
; } else {
|
||||
; f->next = 0;
|
||||
; /* Special case: This is the new freelist end */
|
||||
; _hlast = f;
|
||||
; }
|
||||
; if (left) {
|
||||
; /* Check if we must merge the block with the left one */
|
||||
; if ((unsigned) f == ((unsigned) left) + left->size) {
|
||||
; /* Merge with the left block */
|
||||
; left->size += f->size;
|
||||
; if (left->next = f->next) {
|
||||
; left->next->prev = left;
|
||||
; } else {
|
||||
; /* This is now the last block */
|
||||
; _hlast = left;
|
||||
; }
|
||||
; } else {
|
||||
; /* No merge, just set the link */
|
||||
; left->next = f;
|
||||
; f->prev = left;
|
||||
; }
|
||||
; } else {
|
||||
; f->prev = 0;
|
||||
; /* Special case: This is the new freelist start */
|
||||
; _hfirst = f;
|
||||
; }
|
||||
; }
|
||||
; /* Ok, the current block must be inserted between left and right (but
|
||||
; * beware: one of the two may be zero!). Also check for the condition
|
||||
; * that we have to merge two or three blocks.
|
||||
; */
|
||||
; if (right) {
|
||||
; /* Check if we must merge the block with the right one */
|
||||
; if (((unsigned) f) + size == (unsigned) right) {
|
||||
; /* Merge with the right block */
|
||||
; f->size += right->size;
|
||||
; if (f->next = right->next) {
|
||||
; f->next->prev = f;
|
||||
; } else {
|
||||
; /* This is now the last block */
|
||||
; _hlast = f;
|
||||
; }
|
||||
; } else {
|
||||
; /* No merge, just set the link */
|
||||
; f->next = right;
|
||||
; right->prev = f;
|
||||
; }
|
||||
; } else {
|
||||
; f->next = 0;
|
||||
; /* Special case: This is the new freelist end */
|
||||
; _hlast = f;
|
||||
; }
|
||||
; if (left) {
|
||||
; /* Check if we must merge the block with the left one */
|
||||
; if ((unsigned) f == ((unsigned) left) + left->size) {
|
||||
; /* Merge with the left block */
|
||||
; left->size += f->size;
|
||||
; if (left->next = f->next) {
|
||||
; left->next->prev = left;
|
||||
; } else {
|
||||
; /* This is now the last block */
|
||||
; _hlast = left;
|
||||
; }
|
||||
; } else {
|
||||
; /* No merge, just set the link */
|
||||
; left->next = f;
|
||||
; f->prev = left;
|
||||
; }
|
||||
; } else {
|
||||
; f->prev = 0;
|
||||
; /* Special case: This is the new freelist start */
|
||||
; _hfirst = f;
|
||||
; }
|
||||
; }
|
||||
; }
|
||||
; }
|
||||
;
|
||||
@@ -283,30 +283,30 @@ _free: sta ptr2
|
||||
; Check if the free list is empty, storing _hfirst into ptr3 for later
|
||||
|
||||
heapadd:
|
||||
lda __heapfirst
|
||||
sta ptr3
|
||||
lda __heapfirst+1
|
||||
sta ptr3+1
|
||||
ora ptr3
|
||||
bne SearchFreeList
|
||||
lda __heapfirst
|
||||
sta ptr3
|
||||
lda __heapfirst+1
|
||||
sta ptr3+1
|
||||
ora ptr3
|
||||
bne SearchFreeList
|
||||
|
||||
; The free list is empty, so this is the first and only block. A contains
|
||||
; zero if we come here.
|
||||
|
||||
ldy #freeblock::next-1
|
||||
@L2: iny ; f->next = f->prev = 0;
|
||||
sta (ptr2),y
|
||||
cpy #freeblock::prev+1 ; Done?
|
||||
bne @L2
|
||||
ldy #freeblock::next-1
|
||||
@L2: iny ; f->next = f->prev = 0;
|
||||
sta (ptr2),y
|
||||
cpy #freeblock::prev+1 ; Done?
|
||||
bne @L2
|
||||
|
||||
lda ptr2
|
||||
ldx ptr2+1
|
||||
sta __heapfirst
|
||||
stx __heapfirst+1 ; _heapfirst = f;
|
||||
sta __heaplast
|
||||
stx __heaplast+1 ; _heaplast = f;
|
||||
lda ptr2
|
||||
ldx ptr2+1
|
||||
sta __heapfirst
|
||||
stx __heapfirst+1 ; _heapfirst = f;
|
||||
sta __heaplast
|
||||
stx __heaplast+1 ; _heaplast = f;
|
||||
|
||||
rts ; Done
|
||||
rts ; Done
|
||||
|
||||
; We have to search the free list. As we are doing so, check if it is possible
|
||||
; to combine this block with another, already existing block. Beware: The
|
||||
@@ -316,225 +316,225 @@ heapadd:
|
||||
; ptr3) is not zero on entry.
|
||||
|
||||
SearchFreeList:
|
||||
lda #0
|
||||
sta ptr4
|
||||
sta ptr4+1 ; left = 0;
|
||||
ldy #freeblock::next+1
|
||||
ldx ptr3
|
||||
lda #0
|
||||
sta ptr4
|
||||
sta ptr4+1 ; left = 0;
|
||||
ldy #freeblock::next+1
|
||||
ldx ptr3
|
||||
|
||||
@Loop: lda ptr3+1 ; High byte of right
|
||||
cmp ptr2+1
|
||||
bne @L1
|
||||
cpx ptr2
|
||||
beq @L2
|
||||
@L1: bcs CheckRightMerge
|
||||
@Loop: lda ptr3+1 ; High byte of right
|
||||
cmp ptr2+1
|
||||
bne @L1
|
||||
cpx ptr2
|
||||
beq @L2
|
||||
@L1: bcs CheckRightMerge
|
||||
|
||||
@L2: stx ptr4 ; left = right;
|
||||
sta ptr4+1
|
||||
@L2: stx ptr4 ; left = right;
|
||||
sta ptr4+1
|
||||
|
||||
dey ; Points to next
|
||||
lda (ptr3),y ; right = right->next;
|
||||
tax
|
||||
iny ; Points to next+1
|
||||
lda (ptr3),y
|
||||
stx ptr3
|
||||
sta ptr3+1
|
||||
ora ptr3
|
||||
bne @Loop
|
||||
dey ; Points to next
|
||||
lda (ptr3),y ; right = right->next;
|
||||
tax
|
||||
iny ; Points to next+1
|
||||
lda (ptr3),y
|
||||
stx ptr3
|
||||
sta ptr3+1
|
||||
ora ptr3
|
||||
bne @Loop
|
||||
|
||||
; If we come here, the right pointer is zero, so we don't need to check for
|
||||
; a merge. The new block is the new freelist end.
|
||||
; A is zero when we come here, Y points to next+1
|
||||
|
||||
sta (ptr2),y ; Clear high byte of f->next
|
||||
dey
|
||||
sta (ptr2),y ; Clear low byte of f->next
|
||||
sta (ptr2),y ; Clear high byte of f->next
|
||||
dey
|
||||
sta (ptr2),y ; Clear low byte of f->next
|
||||
|
||||
lda ptr2 ; _heaplast = f;
|
||||
sta __heaplast
|
||||
lda ptr2+1
|
||||
sta __heaplast+1
|
||||
lda ptr2 ; _heaplast = f;
|
||||
sta __heaplast
|
||||
lda ptr2+1
|
||||
sta __heaplast+1
|
||||
|
||||
; Since we have checked the case that the freelist is empty before, if the
|
||||
; right pointer is NULL, the left *cannot* be NULL here. So skip the
|
||||
; pointer check and jump right to the left block merge
|
||||
|
||||
jmp CheckLeftMerge2
|
||||
jmp CheckLeftMerge2
|
||||
|
||||
; The given block must be inserted between left and right, and right is not
|
||||
; zero.
|
||||
|
||||
CheckRightMerge:
|
||||
lda ptr2
|
||||
add ptr1 ; f + size
|
||||
tax
|
||||
lda ptr2+1
|
||||
adc ptr1+1
|
||||
lda ptr2
|
||||
add ptr1 ; f + size
|
||||
tax
|
||||
lda ptr2+1
|
||||
adc ptr1+1
|
||||
|
||||
cpx ptr3
|
||||
bne NoRightMerge
|
||||
cmp ptr3+1
|
||||
bne NoRightMerge
|
||||
cpx ptr3
|
||||
bne NoRightMerge
|
||||
cmp ptr3+1
|
||||
bne NoRightMerge
|
||||
|
||||
; Merge with the right block. Do f->size += right->size;
|
||||
|
||||
ldy #freeblock::size
|
||||
lda ptr1
|
||||
add (ptr3),y
|
||||
sta (ptr2),y
|
||||
iny ; Points to size+1
|
||||
lda ptr1+1
|
||||
adc (ptr3),y
|
||||
sta (ptr2),y
|
||||
ldy #freeblock::size
|
||||
lda ptr1
|
||||
add (ptr3),y
|
||||
sta (ptr2),y
|
||||
iny ; Points to size+1
|
||||
lda ptr1+1
|
||||
adc (ptr3),y
|
||||
sta (ptr2),y
|
||||
|
||||
; Set f->next = right->next and remember f->next in ptr1 (we don't need the
|
||||
; size stored there any longer)
|
||||
|
||||
iny ; Points to next
|
||||
lda (ptr3),y ; Low byte of right->next
|
||||
sta (ptr2),y ; Store to low byte of f->next
|
||||
sta ptr1
|
||||
iny ; Points to next+1
|
||||
lda (ptr3),y ; High byte of right->next
|
||||
sta (ptr2),y ; Store to high byte of f->next
|
||||
sta ptr1+1
|
||||
ora ptr1
|
||||
beq @L1 ; Jump if f->next zero
|
||||
iny ; Points to next
|
||||
lda (ptr3),y ; Low byte of right->next
|
||||
sta (ptr2),y ; Store to low byte of f->next
|
||||
sta ptr1
|
||||
iny ; Points to next+1
|
||||
lda (ptr3),y ; High byte of right->next
|
||||
sta (ptr2),y ; Store to high byte of f->next
|
||||
sta ptr1+1
|
||||
ora ptr1
|
||||
beq @L1 ; Jump if f->next zero
|
||||
|
||||
; f->next->prev = f;
|
||||
|
||||
iny ; Points to prev
|
||||
lda ptr2 ; Low byte of f
|
||||
sta (ptr1),y ; Low byte of f->next->prev
|
||||
iny ; Points to prev+1
|
||||
lda ptr2+1 ; High byte of f
|
||||
sta (ptr1),y ; High byte of f->next->prev
|
||||
jmp CheckLeftMerge ; Done
|
||||
iny ; Points to prev
|
||||
lda ptr2 ; Low byte of f
|
||||
sta (ptr1),y ; Low byte of f->next->prev
|
||||
iny ; Points to prev+1
|
||||
lda ptr2+1 ; High byte of f
|
||||
sta (ptr1),y ; High byte of f->next->prev
|
||||
jmp CheckLeftMerge ; Done
|
||||
|
||||
; f->next is zero, this is now the last block
|
||||
|
||||
@L1: lda ptr2 ; _heaplast = f;
|
||||
sta __heaplast
|
||||
lda ptr2+1
|
||||
sta __heaplast+1
|
||||
jmp CheckLeftMerge
|
||||
@L1: lda ptr2 ; _heaplast = f;
|
||||
sta __heaplast
|
||||
lda ptr2+1
|
||||
sta __heaplast+1
|
||||
jmp CheckLeftMerge
|
||||
|
||||
; No right merge, just set the link.
|
||||
|
||||
NoRightMerge:
|
||||
ldy #freeblock::next ; f->next = right;
|
||||
lda ptr3
|
||||
sta (ptr2),y
|
||||
iny ; Points to next+1
|
||||
lda ptr3+1
|
||||
sta (ptr2),y
|
||||
ldy #freeblock::next ; f->next = right;
|
||||
lda ptr3
|
||||
sta (ptr2),y
|
||||
iny ; Points to next+1
|
||||
lda ptr3+1
|
||||
sta (ptr2),y
|
||||
|
||||
iny ; Points to prev
|
||||
lda ptr2 ; right->prev = f;
|
||||
sta (ptr3),y
|
||||
iny ; Points to prev+1
|
||||
lda ptr2+1
|
||||
sta (ptr3),y
|
||||
iny ; Points to prev
|
||||
lda ptr2 ; right->prev = f;
|
||||
sta (ptr3),y
|
||||
iny ; Points to prev+1
|
||||
lda ptr2+1
|
||||
sta (ptr3),y
|
||||
|
||||
; Check if the left pointer is zero
|
||||
|
||||
CheckLeftMerge:
|
||||
lda ptr4 ; left == NULL?
|
||||
ora ptr4+1
|
||||
bne CheckLeftMerge2 ; Jump if there is a left block
|
||||
lda ptr4 ; left == NULL?
|
||||
ora ptr4+1
|
||||
bne CheckLeftMerge2 ; Jump if there is a left block
|
||||
|
||||
; We don't have a left block, so f is actually the new freelist start
|
||||
|
||||
ldy #freeblock::prev
|
||||
sta (ptr2),y ; f->prev = 0;
|
||||
iny
|
||||
sta (ptr2),y
|
||||
ldy #freeblock::prev
|
||||
sta (ptr2),y ; f->prev = 0;
|
||||
iny
|
||||
sta (ptr2),y
|
||||
|
||||
lda ptr2 ; _heapfirst = f;
|
||||
sta __heapfirst
|
||||
lda ptr2+1
|
||||
sta __heapfirst+1
|
||||
lda ptr2 ; _heapfirst = f;
|
||||
sta __heapfirst
|
||||
lda ptr2+1
|
||||
sta __heapfirst+1
|
||||
|
||||
rts ; Done
|
||||
rts ; Done
|
||||
|
||||
; Check if the left block is adjacent to the following one
|
||||
|
||||
CheckLeftMerge2:
|
||||
ldy #freeblock::size ; Calculate left + left->size
|
||||
lda (ptr4),y ; Low byte of left->size
|
||||
add ptr4
|
||||
tax
|
||||
iny ; Points to size+1
|
||||
lda (ptr4),y ; High byte of left->size
|
||||
adc ptr4+1
|
||||
ldy #freeblock::size ; Calculate left + left->size
|
||||
lda (ptr4),y ; Low byte of left->size
|
||||
add ptr4
|
||||
tax
|
||||
iny ; Points to size+1
|
||||
lda (ptr4),y ; High byte of left->size
|
||||
adc ptr4+1
|
||||
|
||||
cpx ptr2
|
||||
bne NoLeftMerge
|
||||
cmp ptr2+1
|
||||
bne NoLeftMerge ; Jump if blocks not adjacent
|
||||
cpx ptr2
|
||||
bne NoLeftMerge
|
||||
cmp ptr2+1
|
||||
bne NoLeftMerge ; Jump if blocks not adjacent
|
||||
|
||||
; Merge with the left block. Do left->size += f->size;
|
||||
|
||||
dey ; Points to size
|
||||
lda (ptr4),y
|
||||
add (ptr2),y
|
||||
sta (ptr4),y
|
||||
iny ; Points to size+1
|
||||
lda (ptr4),y
|
||||
adc (ptr2),y
|
||||
sta (ptr4),y
|
||||
dey ; Points to size
|
||||
lda (ptr4),y
|
||||
add (ptr2),y
|
||||
sta (ptr4),y
|
||||
iny ; Points to size+1
|
||||
lda (ptr4),y
|
||||
adc (ptr2),y
|
||||
sta (ptr4),y
|
||||
|
||||
; Set left->next = f->next and remember left->next in ptr1.
|
||||
|
||||
iny ; Points to next
|
||||
lda (ptr2),y ; Low byte of f->next
|
||||
sta (ptr4),y
|
||||
sta ptr1
|
||||
iny ; Points to next+1
|
||||
lda (ptr2),y ; High byte of f->next
|
||||
sta (ptr4),y
|
||||
sta ptr1+1
|
||||
ora ptr1 ; left->next == NULL?
|
||||
beq @L1
|
||||
iny ; Points to next
|
||||
lda (ptr2),y ; Low byte of f->next
|
||||
sta (ptr4),y
|
||||
sta ptr1
|
||||
iny ; Points to next+1
|
||||
lda (ptr2),y ; High byte of f->next
|
||||
sta (ptr4),y
|
||||
sta ptr1+1
|
||||
ora ptr1 ; left->next == NULL?
|
||||
beq @L1
|
||||
|
||||
; Do left->next->prev = left
|
||||
|
||||
iny ; Points to prev
|
||||
lda ptr4 ; Low byte of left
|
||||
sta (ptr1),y
|
||||
iny
|
||||
lda ptr4+1 ; High byte of left
|
||||
sta (ptr1),y
|
||||
rts ; Done
|
||||
iny ; Points to prev
|
||||
lda ptr4 ; Low byte of left
|
||||
sta (ptr1),y
|
||||
iny
|
||||
lda ptr4+1 ; High byte of left
|
||||
sta (ptr1),y
|
||||
rts ; Done
|
||||
|
||||
; This is now the last block, do _heaplast = left
|
||||
|
||||
@L1: lda ptr4
|
||||
sta __heaplast
|
||||
lda ptr4+1
|
||||
sta __heaplast+1
|
||||
rts ; Done
|
||||
@L1: lda ptr4
|
||||
sta __heaplast
|
||||
lda ptr4+1
|
||||
sta __heaplast+1
|
||||
rts ; Done
|
||||
|
||||
; No merge of the left block, just set the link. Y points to size+1 if
|
||||
; we come here. Do left->next = f.
|
||||
|
||||
NoLeftMerge:
|
||||
iny ; Points to next
|
||||
lda ptr2 ; Low byte of left
|
||||
sta (ptr4),y
|
||||
iny
|
||||
lda ptr2+1 ; High byte of left
|
||||
sta (ptr4),y
|
||||
iny ; Points to next
|
||||
lda ptr2 ; Low byte of left
|
||||
sta (ptr4),y
|
||||
iny
|
||||
lda ptr2+1 ; High byte of left
|
||||
sta (ptr4),y
|
||||
|
||||
; Do f->prev = left
|
||||
|
||||
iny ; Points to prev
|
||||
lda ptr4
|
||||
sta (ptr2),y
|
||||
iny
|
||||
lda ptr4+1
|
||||
sta (ptr2),y
|
||||
rts ; Done
|
||||
iny ; Points to prev
|
||||
lda ptr4
|
||||
sta (ptr2),y
|
||||
iny
|
||||
lda ptr4+1
|
||||
sta (ptr2),y
|
||||
rts ; Done
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ FILE* __fastcall__ freopen (const char* name, const char* mode, FILE* f)
|
||||
{
|
||||
/* Check if the file is open, if so, close it */
|
||||
if ((f->f_flags & _FOPEN) == 0) {
|
||||
/* File is not open */
|
||||
/* File is not open */
|
||||
return (FILE*) _seterrno (EINVAL); /* File not input */
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ FILE* __fastcall__ freopen (const char* name, const char* mode, FILE* f)
|
||||
*/
|
||||
if (close (f->f_fd) < 0) {
|
||||
/* An error occured, errno is already set */
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Open the file and return the descriptor */
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; Ullrich von Bassewitz, 2004-11-28
|
||||
;
|
||||
|
||||
.export _fscanf
|
||||
.import addysp, decsp4, _vfscanf
|
||||
.importzp sp, ptr1
|
||||
.export _fscanf
|
||||
.import addysp, decsp4, _vfscanf
|
||||
.importzp sp, ptr1
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; int fscanf (FILE* f, const char* format, ...)
|
||||
@@ -36,7 +36,7 @@ ParamSize: .res 1 ; Number of parameter bytes
|
||||
.code
|
||||
|
||||
_fscanf:
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
|
||||
; We have to push f and format, both in the order they already have on stack.
|
||||
; To make this somewhat more efficient, we will create space on the stack and
|
||||
@@ -45,37 +45,37 @@ _fscanf:
|
||||
; of the fixed arguments, this will allow us to calculate the pointer to the
|
||||
; fixed size arguments easier (they're just ParamSize bytes away).
|
||||
|
||||
jsr decsp4
|
||||
jsr decsp4
|
||||
|
||||
; Calculate a pointer to the Format argument
|
||||
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
|
||||
; Now copy both, f and format
|
||||
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
|
||||
; Load va_list (last and __fastcall__ parameter to vfscanf)
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Call vfscanf
|
||||
|
||||
jsr _vfscanf
|
||||
jsr _vfscanf
|
||||
|
||||
; Cleanup the stack. We will return what we got from vfscanf
|
||||
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -24,30 +24,30 @@
|
||||
|
||||
; Save file and place it into ptr1
|
||||
|
||||
sta file
|
||||
sta ptr1
|
||||
stx file+1
|
||||
stx ptr1+1
|
||||
sta file
|
||||
sta ptr1
|
||||
stx file+1
|
||||
stx ptr1+1
|
||||
|
||||
; Check if the file is open
|
||||
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y
|
||||
and #_FOPEN ; Is the file open?
|
||||
bne @L2 ; Branch if yes
|
||||
ldy #_FILE::f_flags
|
||||
lda (ptr1),y
|
||||
and #_FOPEN ; Is the file open?
|
||||
bne @L2 ; Branch if yes
|
||||
|
||||
; File not open
|
||||
|
||||
@L1: lda #EBADF
|
||||
@L1: lda #EBADF
|
||||
jsr __seterrno ; Returns with A = 0
|
||||
tax ; A = X = 0
|
||||
jmp incsp6
|
||||
|
||||
; Check if the stream is in an error state
|
||||
|
||||
@L2: lda (ptr1),y ; get file->f_flags again
|
||||
and #_FERROR
|
||||
bne @L1
|
||||
@L2: lda (ptr1),y ; get file->f_flags again
|
||||
and #_FERROR
|
||||
bne @L1
|
||||
|
||||
; Build the stackframe for write()
|
||||
|
||||
@@ -122,5 +122,5 @@
|
||||
; Data
|
||||
|
||||
.bss
|
||||
file: .res 2
|
||||
file: .res 2
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#undef getchar /* This is usually declared as a macro */
|
||||
#undef getchar /* This is usually declared as a macro */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; unsigned char getcpu (void);
|
||||
;
|
||||
|
||||
.export _getcpu
|
||||
.export _getcpu
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Subroutine to detect an 816. Returns
|
||||
@@ -18,20 +18,20 @@
|
||||
; of the 6502, but all of them interpret unknown opcodes as NOP so this is
|
||||
; just what we want.
|
||||
|
||||
.p816 ; Enable 65816 instructions
|
||||
.p816 ; Enable 65816 instructions
|
||||
|
||||
_getcpu:
|
||||
lda #0
|
||||
inc a ; .byte $1A
|
||||
cmp #1
|
||||
bcc @L9
|
||||
lda #0
|
||||
inc a ; .byte $1A
|
||||
cmp #1
|
||||
bcc @L9
|
||||
|
||||
; This is at least a 65C02, check for a 65816
|
||||
|
||||
xba ; .byte $eb, put $01 in B accu
|
||||
dec a ; .byte $3a, A=$00 if 65C02
|
||||
xba ; .byte $eb, get $01 back if 65816
|
||||
inc a ; .byte $1a, make $01/$02
|
||||
@L9: ldx #0 ; Load high byte of word
|
||||
rts
|
||||
xba ; .byte $eb, put $01 in B accu
|
||||
dec a ; .byte $3a, A=$00 if 65C02
|
||||
xba ; .byte $eb, get $01 back if 65816
|
||||
inc a ; .byte $1a, make $01/$02
|
||||
@L9: ldx #0 ; Load high byte of word
|
||||
rts
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -25,24 +25,24 @@ char* __fastcall__ gets (char* s)
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Get next character */
|
||||
if ((c = fgetc (stdin)) == EOF) {
|
||||
/* Error or EOF */
|
||||
*p = '\0';
|
||||
if (stdin->f_flags & _FERROR) {
|
||||
/* ERROR */
|
||||
return 0;
|
||||
} else {
|
||||
/* EOF */
|
||||
if (i) {
|
||||
return s;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Get next character */
|
||||
if ((c = fgetc (stdin)) == EOF) {
|
||||
/* Error or EOF */
|
||||
*p = '\0';
|
||||
if (stdin->f_flags & _FERROR) {
|
||||
/* ERROR */
|
||||
return 0;
|
||||
} else {
|
||||
/* EOF */
|
||||
if (i) {
|
||||
return s;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* One char more. Newline ends the input */
|
||||
/* One char more. Newline ends the input */
|
||||
if ((char) c == '\n') {
|
||||
*p = '\0';
|
||||
break;
|
||||
|
||||
@@ -5,102 +5,102 @@
|
||||
; void reset_irq (void);
|
||||
;
|
||||
|
||||
.export _set_irq, _reset_irq
|
||||
.interruptor clevel_irq, 1 ; Export as low priority IRQ handler
|
||||
.import popax
|
||||
.export _set_irq, _reset_irq
|
||||
.interruptor clevel_irq, 1 ; Export as low priority IRQ handler
|
||||
.import popax
|
||||
.importzp __ZP_START__
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "zeropage.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
irqvec: jmp $00FF ; Patched at runtime
|
||||
irqvec: jmp $00FF ; Patched at runtime
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
.bss
|
||||
|
||||
irqsp: .res 2
|
||||
irqsp: .res 2
|
||||
|
||||
zpsave: .res zpsavespace
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
.proc _set_irq
|
||||
.proc _set_irq
|
||||
|
||||
; Keep clevel_irq from being called right now
|
||||
sei
|
||||
; Keep clevel_irq from being called right now
|
||||
sei
|
||||
|
||||
; Set irq stack pointer to stack_addr + stack_size
|
||||
sta irqsp
|
||||
stx irqsp+1
|
||||
jsr popax
|
||||
add irqsp
|
||||
sta irqsp
|
||||
txa
|
||||
adc irqsp+1
|
||||
sta irqsp+1
|
||||
; Set irq stack pointer to stack_addr + stack_size
|
||||
sta irqsp
|
||||
stx irqsp+1
|
||||
jsr popax
|
||||
add irqsp
|
||||
sta irqsp
|
||||
txa
|
||||
adc irqsp+1
|
||||
sta irqsp+1
|
||||
|
||||
; Set irq vector to irq_handler
|
||||
jsr popax
|
||||
sta irqvec+1
|
||||
stx irqvec+2 ; Set the user vector
|
||||
; Set irq vector to irq_handler
|
||||
jsr popax
|
||||
sta irqvec+1
|
||||
stx irqvec+2 ; Set the user vector
|
||||
|
||||
; Restore interrupt requests and return
|
||||
cli
|
||||
rts
|
||||
; Restore interrupt requests and return
|
||||
cli
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
.proc _reset_irq
|
||||
.proc _reset_irq
|
||||
|
||||
lda #$00
|
||||
sta irqvec+2 ; High byte is enough
|
||||
rts
|
||||
lda #$00
|
||||
sta irqvec+2 ; High byte is enough
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
.proc clevel_irq
|
||||
.proc clevel_irq
|
||||
|
||||
; Is C level interrupt request vector set?
|
||||
lda irqvec+2 ; High byte is enough
|
||||
bne @L1
|
||||
clc ; Interrupt not handled
|
||||
rts
|
||||
; Is C level interrupt request vector set?
|
||||
lda irqvec+2 ; High byte is enough
|
||||
bne @L1
|
||||
clc ; Interrupt not handled
|
||||
rts
|
||||
|
||||
; Save our zero page locations
|
||||
@L1: ldx #.sizeof(::zpsave)-1
|
||||
; Save our zero page locations
|
||||
@L1: ldx #.sizeof(::zpsave)-1
|
||||
@L2: lda __ZP_START__,x
|
||||
sta zpsave,x
|
||||
dex
|
||||
bpl @L2
|
||||
sta zpsave,x
|
||||
dex
|
||||
bpl @L2
|
||||
|
||||
; Set C level interrupt stack
|
||||
lda irqsp
|
||||
ldx irqsp+1
|
||||
sta sp
|
||||
stx sp+1
|
||||
; Set C level interrupt stack
|
||||
lda irqsp
|
||||
ldx irqsp+1
|
||||
sta sp
|
||||
stx sp+1
|
||||
|
||||
; Call C level interrupt request handler
|
||||
jsr irqvec
|
||||
; Call C level interrupt request handler
|
||||
jsr irqvec
|
||||
|
||||
; Copy back our zero page content
|
||||
ldx #.sizeof(::zpsave)-1
|
||||
; Copy back our zero page content
|
||||
ldx #.sizeof(::zpsave)-1
|
||||
@L3: ldy zpsave,x
|
||||
sty __ZP_START__,x
|
||||
dex
|
||||
bpl @L3
|
||||
sty __ZP_START__,x
|
||||
dex
|
||||
bpl @L3
|
||||
|
||||
; Mark interrupt handled / not handled and return
|
||||
lsr
|
||||
rts
|
||||
; Mark interrupt handled / not handled and return
|
||||
lsr
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int isalnum (int c);
|
||||
;
|
||||
|
||||
.export _isalnum
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int isalpha (int c);
|
||||
;
|
||||
|
||||
.export _isalpha
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
; cc65 (and GNU) extension.
|
||||
;
|
||||
|
||||
.export _isblank
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int iscntrl (int c);
|
||||
;
|
||||
|
||||
.export _iscntrl
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int isdigit (int c);
|
||||
;
|
||||
|
||||
.export _isdigit
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -5,21 +5,21 @@
|
||||
; int isgraph (int c);
|
||||
;
|
||||
|
||||
.export _isgraph
|
||||
.include "ctype.inc"
|
||||
.export _isgraph
|
||||
.include "ctype.inc"
|
||||
|
||||
_isgraph:
|
||||
cpx #>0 ; Char range OK?
|
||||
bne @L1 ; Jump if no
|
||||
tay
|
||||
lda __ctype,y ; Get character classification
|
||||
and #CT_CTRL_SPACE ; Mask character bits
|
||||
cmp #1 ; If false, then set "borrow" flag
|
||||
lda #0
|
||||
sbc #0 ; Invert logic
|
||||
rts ; Return NOT control and NOT space
|
||||
cpx #>0 ; Char range OK?
|
||||
bne @L1 ; Jump if no
|
||||
tay
|
||||
lda __ctype,y ; Get character classification
|
||||
and #CT_CTRL_SPACE ; Mask character bits
|
||||
cmp #1 ; If false, then set "borrow" flag
|
||||
lda #0
|
||||
sbc #0 ; Invert logic
|
||||
rts ; Return NOT control and NOT space
|
||||
|
||||
@L1: lda #<0 ; Return false
|
||||
tax
|
||||
rts
|
||||
@L1: lda #<0 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int islower (int c);
|
||||
;
|
||||
|
||||
.export _islower
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
; int isprint (int c);
|
||||
;
|
||||
|
||||
.export _isprint
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -5,21 +5,21 @@
|
||||
; int ispunct (int c);
|
||||
;
|
||||
|
||||
.export _ispunct
|
||||
.include "ctype.inc"
|
||||
.export _ispunct
|
||||
.include "ctype.inc"
|
||||
|
||||
_ispunct:
|
||||
cpx #>0 ; Char range OK?
|
||||
bne @L1 ; Jump if no
|
||||
tay
|
||||
lda __ctype,y ; Get character classification
|
||||
and #CT_NOT_PUNCT ; Mask relevant bits
|
||||
cmp #1 ; If false, then set "borrow" flag
|
||||
lda #0
|
||||
sbc #0 ; Invert logic
|
||||
rts ; Return NOT (space | control | digit | alpha)
|
||||
cpx #>0 ; Char range OK?
|
||||
bne @L1 ; Jump if no
|
||||
tay
|
||||
lda __ctype,y ; Get character classification
|
||||
and #CT_NOT_PUNCT ; Mask relevant bits
|
||||
cmp #1 ; If false, then set "borrow" flag
|
||||
lda #0
|
||||
sbc #0 ; Invert logic
|
||||
rts ; Return NOT (space | control | digit | alpha)
|
||||
|
||||
@L1: lda #<0 ; Return false
|
||||
tax
|
||||
rts
|
||||
@L1: lda #<0 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int isspace (int c);
|
||||
;
|
||||
|
||||
.export _isspace
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int isupper (int c);
|
||||
;
|
||||
|
||||
.export _isupper
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; int isxdigit (int c);
|
||||
;
|
||||
|
||||
.export _isxdigit
|
||||
.include "ctype.inc"
|
||||
.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
|
||||
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
|
||||
@L1: lda #$00 ; Return false
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -5,131 +5,131 @@
|
||||
; char* utoa (unsigned value, char* s, int radix);
|
||||
;
|
||||
|
||||
.export _itoa, _utoa
|
||||
.import addysp1
|
||||
.import __hextab
|
||||
.importzp sp, sreg, ptr2, ptr3, tmp1
|
||||
.export _itoa, _utoa
|
||||
.import addysp1
|
||||
.import __hextab
|
||||
.importzp sp, sreg, ptr2, ptr3, tmp1
|
||||
|
||||
.rodata
|
||||
specval:
|
||||
.byte '-', '3', '2', '7', '6', '8', 0
|
||||
.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
|
||||
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
|
||||
_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 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
|
||||
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
|
||||
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
|
||||
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
|
||||
_utoa: jsr dopop ; pop the arguments
|
||||
|
||||
; Convert to string by dividing and push the result onto the stack
|
||||
|
||||
utoa: lda #$00
|
||||
pha ; sentinel
|
||||
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
|
||||
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
|
||||
tay ; get remainder into y
|
||||
lda __hextab,y ; get hex character
|
||||
pha ; save char value on stack
|
||||
|
||||
lda sreg
|
||||
ora sreg+1
|
||||
bne L5
|
||||
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
|
||||
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
|
||||
L10: lda ptr3
|
||||
ldx ptr3+1
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
; intmax_t __fastcall imaxabs (intmax_t val);
|
||||
;
|
||||
|
||||
.export _labs, _imaxabs
|
||||
.import negeax
|
||||
.importzp sreg
|
||||
.export _labs, _imaxabs
|
||||
.import negeax
|
||||
.importzp sreg
|
||||
|
||||
|
||||
_labs:
|
||||
_imaxabs:
|
||||
ldy sreg+1 ; test hi byte
|
||||
bpl L1
|
||||
jmp negeax ; Negate if negative
|
||||
L1: rts
|
||||
ldy sreg+1 ; test hi byte
|
||||
bpl L1
|
||||
jmp negeax ; Negate if negative
|
||||
L1: rts
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -21,30 +21,30 @@
|
||||
static char EmptyString [] = "";
|
||||
|
||||
static struct lconv lc = {
|
||||
EmptyString, /* currency_symbol */
|
||||
".", /* decimal_point */
|
||||
EmptyString, /* grouping */
|
||||
EmptyString, /* int_curr_symbol */
|
||||
EmptyString, /* mon_decimal_point */
|
||||
EmptyString, /* mon_grouping */
|
||||
EmptyString, /* mon_thousands_sep */
|
||||
EmptyString, /* negative_sign */
|
||||
EmptyString, /* positive_sign */
|
||||
EmptyString, /* thousands_sep */
|
||||
CHAR_MAX, /* frac_digits */
|
||||
CHAR_MAX, /* int_frac_digits */
|
||||
CHAR_MAX, /* n_cs_precedes */
|
||||
CHAR_MAX, /* n_sep_by_space */
|
||||
CHAR_MAX, /* n_sign_posn */
|
||||
CHAR_MAX, /* p_cs_precedes */
|
||||
CHAR_MAX, /* p_sep_by_space */
|
||||
CHAR_MAX, /* p_sign_posn */
|
||||
EmptyString, /* currency_symbol */
|
||||
".", /* decimal_point */
|
||||
EmptyString, /* grouping */
|
||||
EmptyString, /* int_curr_symbol */
|
||||
EmptyString, /* mon_decimal_point */
|
||||
EmptyString, /* mon_grouping */
|
||||
EmptyString, /* mon_thousands_sep */
|
||||
EmptyString, /* negative_sign */
|
||||
EmptyString, /* positive_sign */
|
||||
EmptyString, /* thousands_sep */
|
||||
CHAR_MAX, /* frac_digits */
|
||||
CHAR_MAX, /* int_frac_digits */
|
||||
CHAR_MAX, /* n_cs_precedes */
|
||||
CHAR_MAX, /* n_sep_by_space */
|
||||
CHAR_MAX, /* n_sign_posn */
|
||||
CHAR_MAX, /* p_cs_precedes */
|
||||
CHAR_MAX, /* p_sep_by_space */
|
||||
CHAR_MAX, /* p_sign_posn */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -59,11 +59,11 @@ struct lconv* localeconv (void)
|
||||
char* __fastcall__ setlocale (int, const char* locale)
|
||||
{
|
||||
if (locale == 0 || (locale [0] == 'C' && locale [1] == '\0') || locale [0] == '\0') {
|
||||
/* No change, or value already set, our locale is the "C" locale */
|
||||
return "C";
|
||||
/* No change, or value already set, our locale is the "C" locale */
|
||||
return "C";
|
||||
} else {
|
||||
/* Cannot set this one */
|
||||
return 0;
|
||||
/* Cannot set this one */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,49 +4,49 @@
|
||||
; void longjmp (jmp_buf buf, int retval);
|
||||
;
|
||||
|
||||
.export _longjmp
|
||||
.import popax
|
||||
.importzp sp, ptr1, ptr2
|
||||
.export _longjmp
|
||||
.import popax
|
||||
.importzp sp, ptr1, ptr2
|
||||
|
||||
_longjmp:
|
||||
sta ptr2 ; Save retval
|
||||
stx ptr2+1
|
||||
ora ptr2+1 ; Check for 0
|
||||
bne @L1
|
||||
lda #1 ; 0 is illegal according to the standard...
|
||||
sta ptr2 ; ... and must be replaced by 1
|
||||
@L1: jsr popax ; get buf
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #0
|
||||
sta ptr2 ; Save retval
|
||||
stx ptr2+1
|
||||
ora ptr2+1 ; Check for 0
|
||||
bne @L1
|
||||
lda #1 ; 0 is illegal according to the standard...
|
||||
sta ptr2 ; ... and must be replaced by 1
|
||||
@L1: jsr popax ; get buf
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #0
|
||||
|
||||
; Get the old parameter stack
|
||||
|
||||
lda (ptr1),y
|
||||
iny
|
||||
sta sp
|
||||
lda (ptr1),y
|
||||
iny
|
||||
sta sp+1
|
||||
lda (ptr1),y
|
||||
iny
|
||||
sta sp
|
||||
lda (ptr1),y
|
||||
iny
|
||||
sta sp+1
|
||||
|
||||
; Get the old stack pointer
|
||||
|
||||
lda (ptr1),y
|
||||
iny
|
||||
tax
|
||||
txs
|
||||
lda (ptr1),y
|
||||
iny
|
||||
tax
|
||||
txs
|
||||
|
||||
; Get the return address and push it on the stack
|
||||
|
||||
lda (ptr1),y
|
||||
iny
|
||||
pha
|
||||
lda (ptr1),y
|
||||
pha
|
||||
lda (ptr1),y
|
||||
iny
|
||||
pha
|
||||
lda (ptr1),y
|
||||
pha
|
||||
|
||||
; Load the return value and return to the caller
|
||||
|
||||
lda ptr2
|
||||
ldx ptr2+1
|
||||
rts
|
||||
lda ptr2
|
||||
ldx ptr2+1
|
||||
rts
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
; char* ultoa (unsigned long value, char* s, int radix);
|
||||
;
|
||||
|
||||
.export _ltoa, _ultoa
|
||||
.import popax
|
||||
.import __hextab, __longminstr
|
||||
.importzp sreg, ptr1, ptr2, ptr3, tmp1
|
||||
.export _ltoa, _ultoa
|
||||
.import popax
|
||||
.import __hextab, __longminstr
|
||||
.importzp sreg, ptr1, ptr2, ptr3, tmp1
|
||||
|
||||
|
||||
|
||||
@@ -18,129 +18,129 @@
|
||||
; Common subroutine to pop the parameters and put them into core
|
||||
;
|
||||
|
||||
dopop: sta tmp1 ; will loose high byte
|
||||
jsr popax ; get s
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
sta sreg ; save for return
|
||||
stx sreg+1
|
||||
jsr popax ; get low word of value
|
||||
sta ptr2
|
||||
stx ptr2+1
|
||||
jsr popax ; get high word of value
|
||||
sta ptr3
|
||||
stx ptr3+1
|
||||
rts
|
||||
dopop: sta tmp1 ; will loose high byte
|
||||
jsr popax ; get s
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
sta sreg ; save for return
|
||||
stx sreg+1
|
||||
jsr popax ; get low word of value
|
||||
sta ptr2
|
||||
stx ptr2+1
|
||||
jsr popax ; get high word of value
|
||||
sta ptr3
|
||||
stx ptr3+1
|
||||
rts
|
||||
|
||||
;
|
||||
; ltoa
|
||||
;
|
||||
|
||||
_ltoa: jsr dopop ; pop the arguments
|
||||
_ltoa: jsr dopop ; pop the arguments
|
||||
|
||||
; We must handle $80000000 in a special way, since it is the only negative
|
||||
; number that has no positive 32-bit counterpart
|
||||
|
||||
ldx ptr3+1 ; get high byte
|
||||
ldy tmp1 ; get radix
|
||||
cpy #10
|
||||
bne ultoa
|
||||
lda ptr3
|
||||
ora ptr2+1
|
||||
ora ptr2
|
||||
bne L2
|
||||
cpx #$80
|
||||
bne L2
|
||||
ldx ptr3+1 ; get high byte
|
||||
ldy tmp1 ; get radix
|
||||
cpy #10
|
||||
bne ultoa
|
||||
lda ptr3
|
||||
ora ptr2+1
|
||||
ora ptr2
|
||||
bne L2
|
||||
cpx #$80
|
||||
bne L2
|
||||
|
||||
ldy #11
|
||||
L1: lda __longminstr,y ; copy -2147483648
|
||||
sta (ptr1),y
|
||||
dey
|
||||
bpl L1
|
||||
jmp L10
|
||||
ldy #11
|
||||
L1: lda __longminstr,y ; copy -2147483648
|
||||
sta (ptr1),y
|
||||
dey
|
||||
bpl L1
|
||||
jmp L10
|
||||
|
||||
; Check if the value is negative. If so, write a - sign and negate the
|
||||
; number.
|
||||
|
||||
L2: txa ; get high byte
|
||||
bpl ultoa
|
||||
lda #'-'
|
||||
ldy #0
|
||||
sta (ptr1),y ; store sign
|
||||
inc ptr1
|
||||
bne L3
|
||||
inc ptr1+1
|
||||
L2: txa ; get high byte
|
||||
bpl ultoa
|
||||
lda #'-'
|
||||
ldy #0
|
||||
sta (ptr1),y ; store sign
|
||||
inc ptr1
|
||||
bne L3
|
||||
inc ptr1+1
|
||||
|
||||
L3: lda ptr2 ; negate val
|
||||
eor #$FF
|
||||
clc
|
||||
adc #$01
|
||||
sta ptr2
|
||||
lda ptr2+1
|
||||
eor #$FF
|
||||
adc #$00
|
||||
sta ptr2+1
|
||||
lda ptr3
|
||||
eor #$FF
|
||||
adc #$00
|
||||
sta ptr3
|
||||
lda ptr3+1
|
||||
eor #$FF
|
||||
adc #$00
|
||||
sta ptr3+1
|
||||
jmp ultoa
|
||||
L3: lda ptr2 ; negate val
|
||||
eor #$FF
|
||||
clc
|
||||
adc #$01
|
||||
sta ptr2
|
||||
lda ptr2+1
|
||||
eor #$FF
|
||||
adc #$00
|
||||
sta ptr2+1
|
||||
lda ptr3
|
||||
eor #$FF
|
||||
adc #$00
|
||||
sta ptr3
|
||||
lda ptr3+1
|
||||
eor #$FF
|
||||
adc #$00
|
||||
sta ptr3+1
|
||||
jmp ultoa
|
||||
|
||||
;
|
||||
; utoa
|
||||
;
|
||||
|
||||
_ultoa: jsr dopop ; pop the arguments
|
||||
_ultoa: jsr dopop ; pop the arguments
|
||||
|
||||
; Convert to string by dividing and push the result onto the stack
|
||||
|
||||
ultoa: lda #$00
|
||||
pha ; sentinel
|
||||
ultoa: lda #$00
|
||||
pha ; sentinel
|
||||
|
||||
; Divide val/tmp1 -> val, remainder in a
|
||||
|
||||
L5: ldy #32 ; 32 bit
|
||||
lda #0 ; remainder
|
||||
L6: asl ptr2
|
||||
rol ptr2+1
|
||||
rol ptr3
|
||||
rol ptr3+1
|
||||
rol a
|
||||
cmp tmp1
|
||||
bcc L7
|
||||
sbc tmp1
|
||||
inc ptr2
|
||||
L7: dey
|
||||
bne L6
|
||||
L5: ldy #32 ; 32 bit
|
||||
lda #0 ; remainder
|
||||
L6: asl ptr2
|
||||
rol ptr2+1
|
||||
rol ptr3
|
||||
rol ptr3+1
|
||||
rol a
|
||||
cmp tmp1
|
||||
bcc L7
|
||||
sbc tmp1
|
||||
inc ptr2
|
||||
L7: dey
|
||||
bne L6
|
||||
|
||||
tay ; get remainder into y
|
||||
lda __hextab,y ; get hex character
|
||||
pha ; save char value on stack
|
||||
tay ; get remainder into y
|
||||
lda __hextab,y ; get hex character
|
||||
pha ; save char value on stack
|
||||
|
||||
lda ptr2
|
||||
ora ptr2+1
|
||||
ora ptr3
|
||||
ora ptr3+1
|
||||
bne L5
|
||||
lda ptr2
|
||||
ora ptr2+1
|
||||
ora ptr3
|
||||
ora ptr3+1
|
||||
bne L5
|
||||
|
||||
; Get the characters from the stack into the string
|
||||
|
||||
ldy #0
|
||||
L9: pla
|
||||
sta (ptr1),y
|
||||
beq L10 ; jump if sentinel
|
||||
iny
|
||||
bne L9 ; jump always
|
||||
ldy #0
|
||||
L9: pla
|
||||
sta (ptr1),y
|
||||
beq L10 ; jump if sentinel
|
||||
iny
|
||||
bne L9 ; jump always
|
||||
|
||||
; Done! Return the target string
|
||||
|
||||
L10: lda sreg
|
||||
ldx sreg+1
|
||||
rts
|
||||
L10: lda sreg
|
||||
ldx sreg+1
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
; * up the size if needed.
|
||||
; */
|
||||
; if (size == 0) {
|
||||
; return 0;
|
||||
; return 0;
|
||||
; }
|
||||
; size += HEAP_ADMIN_SPACE;
|
||||
; if (size < sizeof (struct freeblock)) {
|
||||
@@ -67,14 +67,14 @@
|
||||
; } else {
|
||||
;
|
||||
; /* We must slice the block found. Cut off space from the upper
|
||||
; * end, so we can leave the actual free block chain intact.
|
||||
; */
|
||||
; * end, so we can leave the actual free block chain intact.
|
||||
; */
|
||||
;
|
||||
; /* Decrement the size of the block */
|
||||
; f->size -= size;
|
||||
; /* Decrement the size of the block */
|
||||
; f->size -= size;
|
||||
;
|
||||
; /* Set f to the now unused space above the current block */
|
||||
; f = (struct freeblock*) (((unsigned) f) + f->size);
|
||||
; /* Set f to the now unused space above the current block */
|
||||
; f = (struct freeblock*) (((unsigned) f) + f->size);
|
||||
;
|
||||
; }
|
||||
;
|
||||
@@ -86,15 +86,15 @@
|
||||
; /* We did not find a block big enough. Try to use new space from the
|
||||
; * heap top.
|
||||
; */
|
||||
; if (((unsigned) _hend) - ((unsigned) _hptr) < size) {
|
||||
; if (((unsigned) _hend) - ((unsigned) _hptr) < size) {
|
||||
; /* Out of heap space */
|
||||
; return 0;
|
||||
; }
|
||||
; }
|
||||
;
|
||||
;
|
||||
; /* There is enough space left, take it from the heap top */
|
||||
; p = _hptr;
|
||||
; _hptr = (unsigned*) (((unsigned) _hptr) + size);
|
||||
; /* There is enough space left, take it from the heap top */
|
||||
; p = _hptr;
|
||||
; _hptr = (unsigned*) (((unsigned) _hptr) + size);
|
||||
;
|
||||
; }
|
||||
;
|
||||
@@ -105,105 +105,105 @@
|
||||
;
|
||||
|
||||
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.export _malloc
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.export _malloc
|
||||
|
||||
.include "_heap.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Code
|
||||
|
||||
_malloc:
|
||||
sta ptr1 ; Store size in ptr1
|
||||
stx ptr1+1
|
||||
sta ptr1 ; Store size in ptr1
|
||||
stx ptr1+1
|
||||
|
||||
; Check for a size of zero, if so, return NULL
|
||||
|
||||
ora ptr1+1
|
||||
beq Done ; a/x already contains zero
|
||||
ora ptr1+1
|
||||
beq Done ; a/x already contains zero
|
||||
|
||||
; Add the administration space and round up the size if needed
|
||||
|
||||
lda ptr1
|
||||
add #HEAP_ADMIN_SPACE
|
||||
sta ptr1
|
||||
bcc @L1
|
||||
inc ptr1+1
|
||||
@L1: ldx ptr1+1
|
||||
bne @L2
|
||||
cmp #HEAP_MIN_BLOCKSIZE+1
|
||||
bcs @L2
|
||||
lda #HEAP_MIN_BLOCKSIZE
|
||||
sta ptr1 ; High byte is already zero
|
||||
lda ptr1
|
||||
add #HEAP_ADMIN_SPACE
|
||||
sta ptr1
|
||||
bcc @L1
|
||||
inc ptr1+1
|
||||
@L1: ldx ptr1+1
|
||||
bne @L2
|
||||
cmp #HEAP_MIN_BLOCKSIZE+1
|
||||
bcs @L2
|
||||
lda #HEAP_MIN_BLOCKSIZE
|
||||
sta ptr1 ; High byte is already zero
|
||||
|
||||
; Load a pointer to the freelist into ptr2
|
||||
|
||||
@L2: lda __heapfirst
|
||||
sta ptr2
|
||||
lda __heapfirst+1
|
||||
sta ptr2+1
|
||||
@L2: lda __heapfirst
|
||||
sta ptr2
|
||||
lda __heapfirst+1
|
||||
sta ptr2+1
|
||||
|
||||
; Search the freelist for a block that is big enough. We will calculate
|
||||
; (f->size - size) here and keep it, since we need the value later.
|
||||
|
||||
jmp @L4
|
||||
jmp @L4
|
||||
|
||||
@L3: ldy #freeblock::size
|
||||
lda (ptr2),y
|
||||
sub ptr1
|
||||
tax ; Remember low byte for later
|
||||
iny ; Y points to freeblock::size+1
|
||||
lda (ptr2),y
|
||||
sbc ptr1+1
|
||||
bcs BlockFound ; Beware: Contents of a/x/y are known!
|
||||
@L3: ldy #freeblock::size
|
||||
lda (ptr2),y
|
||||
sub ptr1
|
||||
tax ; Remember low byte for later
|
||||
iny ; Y points to freeblock::size+1
|
||||
lda (ptr2),y
|
||||
sbc ptr1+1
|
||||
bcs BlockFound ; Beware: Contents of a/x/y are known!
|
||||
|
||||
; Next block in list
|
||||
|
||||
iny ; Points to freeblock::next
|
||||
lda (ptr2),y
|
||||
tax
|
||||
iny ; Points to freeblock::next+1
|
||||
lda (ptr2),y
|
||||
stx ptr2
|
||||
sta ptr2+1
|
||||
@L4: ora ptr2
|
||||
bne @L3
|
||||
iny ; Points to freeblock::next
|
||||
lda (ptr2),y
|
||||
tax
|
||||
iny ; Points to freeblock::next+1
|
||||
lda (ptr2),y
|
||||
stx ptr2
|
||||
sta ptr2+1
|
||||
@L4: ora ptr2
|
||||
bne @L3
|
||||
|
||||
; We did not find a block big enough. Try to use new space from the heap top.
|
||||
|
||||
lda __heapptr
|
||||
add ptr1 ; _heapptr + size
|
||||
tay
|
||||
lda __heapptr+1
|
||||
adc ptr1+1
|
||||
bcs OutOfHeapSpace ; On overflow, we're surely out of space
|
||||
lda __heapptr
|
||||
add ptr1 ; _heapptr + size
|
||||
tay
|
||||
lda __heapptr+1
|
||||
adc ptr1+1
|
||||
bcs OutOfHeapSpace ; On overflow, we're surely out of space
|
||||
|
||||
cmp __heapend+1
|
||||
bne @L5
|
||||
cpy __heapend
|
||||
@L5: bcc TakeFromTop
|
||||
beq TakeFromTop
|
||||
cmp __heapend+1
|
||||
bne @L5
|
||||
cpy __heapend
|
||||
@L5: bcc TakeFromTop
|
||||
beq TakeFromTop
|
||||
|
||||
; Out of heap space
|
||||
|
||||
OutOfHeapSpace:
|
||||
lda #0
|
||||
tax
|
||||
Done: rts
|
||||
lda #0
|
||||
tax
|
||||
Done: rts
|
||||
|
||||
; There is enough space left, take it from the heap top
|
||||
|
||||
TakeFromTop:
|
||||
ldx __heapptr ; p = _heapptr;
|
||||
stx ptr2
|
||||
ldx __heapptr+1
|
||||
stx ptr2+1
|
||||
ldx __heapptr ; p = _heapptr;
|
||||
stx ptr2
|
||||
ldx __heapptr+1
|
||||
stx ptr2+1
|
||||
|
||||
sty __heapptr ; _heapptr += size;
|
||||
sta __heapptr+1
|
||||
jmp FillSizeAndRet ; Done
|
||||
sty __heapptr ; _heapptr += size;
|
||||
sta __heapptr+1
|
||||
jmp FillSizeAndRet ; Done
|
||||
|
||||
; We found a block big enough. If the block can hold just the
|
||||
; requested size, use the block in full. Beware: When slicing blocks,
|
||||
@@ -213,73 +213,73 @@ TakeFromTop:
|
||||
; flag is set if the high byte of this remaining size is zero.
|
||||
|
||||
BlockFound:
|
||||
bne SliceBlock ; Block is large enough to slice
|
||||
cpx #HEAP_MIN_BLOCKSIZE ; Check low byte
|
||||
bcs SliceBlock ; Jump if block is large enough to slice
|
||||
bne SliceBlock ; Block is large enough to slice
|
||||
cpx #HEAP_MIN_BLOCKSIZE ; Check low byte
|
||||
bcs SliceBlock ; Jump if block is large enough to slice
|
||||
|
||||
; The block is too small to slice it. Use the block in full. The block
|
||||
; does already contain the correct size word, all we have to do is to
|
||||
; remove it from the free list.
|
||||
|
||||
ldy #freeblock::prev+1 ; Load f->prev
|
||||
lda (ptr2),y
|
||||
sta ptr3+1
|
||||
dey
|
||||
lda (ptr2),y
|
||||
sta ptr3
|
||||
dey ; Points to freeblock::next+1
|
||||
ora ptr3+1
|
||||
beq @L1 ; Jump if f->prev zero
|
||||
ldy #freeblock::prev+1 ; Load f->prev
|
||||
lda (ptr2),y
|
||||
sta ptr3+1
|
||||
dey
|
||||
lda (ptr2),y
|
||||
sta ptr3
|
||||
dey ; Points to freeblock::next+1
|
||||
ora ptr3+1
|
||||
beq @L1 ; Jump if f->prev zero
|
||||
|
||||
; We have a previous block, ptr3 contains its address.
|
||||
; Do f->prev->next = f->next
|
||||
|
||||
lda (ptr2),y ; Load high byte of f->next
|
||||
sta (ptr3),y ; Store high byte of f->prev->next
|
||||
dey ; Points to next
|
||||
lda (ptr2),y ; Load low byte of f->next
|
||||
sta (ptr3),y ; Store low byte of f->prev->next
|
||||
jmp @L2
|
||||
lda (ptr2),y ; Load high byte of f->next
|
||||
sta (ptr3),y ; Store high byte of f->prev->next
|
||||
dey ; Points to next
|
||||
lda (ptr2),y ; Load low byte of f->next
|
||||
sta (ptr3),y ; Store low byte of f->prev->next
|
||||
jmp @L2
|
||||
|
||||
; This is the first block, correct the freelist pointer
|
||||
; Do _hfirst = f->next
|
||||
|
||||
@L1: lda (ptr2),y ; Load high byte of f->next
|
||||
sta __heapfirst+1
|
||||
dey ; Points to next
|
||||
lda (ptr2),y ; Load low byte of f->next
|
||||
sta __heapfirst
|
||||
@L1: lda (ptr2),y ; Load high byte of f->next
|
||||
sta __heapfirst+1
|
||||
dey ; Points to next
|
||||
lda (ptr2),y ; Load low byte of f->next
|
||||
sta __heapfirst
|
||||
|
||||
; Check f->next. Y points always to next if we come here
|
||||
|
||||
@L2: lda (ptr2),y ; Load low byte of f->next
|
||||
sta ptr3
|
||||
iny ; Points to next+1
|
||||
lda (ptr2),y ; Load high byte of f->next
|
||||
sta ptr3+1
|
||||
iny ; Points to prev
|
||||
ora ptr3
|
||||
beq @L3 ; Jump if f->next zero
|
||||
@L2: lda (ptr2),y ; Load low byte of f->next
|
||||
sta ptr3
|
||||
iny ; Points to next+1
|
||||
lda (ptr2),y ; Load high byte of f->next
|
||||
sta ptr3+1
|
||||
iny ; Points to prev
|
||||
ora ptr3
|
||||
beq @L3 ; Jump if f->next zero
|
||||
|
||||
; We have a next block, ptr3 contains its address.
|
||||
; Do f->next->prev = f->prev
|
||||
|
||||
lda (ptr2),y ; Load low byte of f->prev
|
||||
sta (ptr3),y ; Store low byte of f->next->prev
|
||||
iny ; Points to prev+1
|
||||
lda (ptr2),y ; Load high byte of f->prev
|
||||
sta (ptr3),y ; Store high byte of f->prev->next
|
||||
jmp RetUserPtr ; Done
|
||||
lda (ptr2),y ; Load low byte of f->prev
|
||||
sta (ptr3),y ; Store low byte of f->next->prev
|
||||
iny ; Points to prev+1
|
||||
lda (ptr2),y ; Load high byte of f->prev
|
||||
sta (ptr3),y ; Store high byte of f->prev->next
|
||||
jmp RetUserPtr ; Done
|
||||
|
||||
; This is the last block, correct the freelist pointer.
|
||||
; Do _hlast = f->prev
|
||||
|
||||
@L3: lda (ptr2),y ; Load low byte of f->prev
|
||||
sta __heaplast
|
||||
iny ; Points to prev+1
|
||||
lda (ptr2),y ; Load high byte of f->prev
|
||||
sta __heaplast+1
|
||||
jmp RetUserPtr ; Done
|
||||
@L3: lda (ptr2),y ; Load low byte of f->prev
|
||||
sta __heaplast
|
||||
iny ; Points to prev+1
|
||||
lda (ptr2),y ; Load high byte of f->prev
|
||||
sta __heaplast+1
|
||||
jmp RetUserPtr ; Done
|
||||
|
||||
; We must slice the block found. Cut off space from the upper end, so we
|
||||
; can leave the actual free block chain intact.
|
||||
@@ -288,37 +288,37 @@ SliceBlock:
|
||||
|
||||
; Decrement the size of the block. Y points to size+1.
|
||||
|
||||
dey ; Points to size
|
||||
lda (ptr2),y ; Low byte of f->size
|
||||
sub ptr1
|
||||
sta (ptr2),y
|
||||
tax ; Save low byte of f->size in X
|
||||
iny ; Points to size+1
|
||||
lda (ptr2),y ; High byte of f->size
|
||||
sbc ptr1+1
|
||||
sta (ptr2),y
|
||||
dey ; Points to size
|
||||
lda (ptr2),y ; Low byte of f->size
|
||||
sub ptr1
|
||||
sta (ptr2),y
|
||||
tax ; Save low byte of f->size in X
|
||||
iny ; Points to size+1
|
||||
lda (ptr2),y ; High byte of f->size
|
||||
sbc ptr1+1
|
||||
sta (ptr2),y
|
||||
|
||||
; Set f to the space above the current block, which is the new block returned
|
||||
; to the caller.
|
||||
|
||||
txa ; Get low byte of f->size
|
||||
add ptr2
|
||||
tax
|
||||
lda (ptr2),y ; Get high byte of f->size
|
||||
adc ptr2+1
|
||||
stx ptr2
|
||||
sta ptr2+1
|
||||
txa ; Get low byte of f->size
|
||||
add ptr2
|
||||
tax
|
||||
lda (ptr2),y ; Get high byte of f->size
|
||||
adc ptr2+1
|
||||
stx ptr2
|
||||
sta ptr2+1
|
||||
|
||||
; Fill the size and start address into the admin space of the block
|
||||
; (struct usedblock) and return the user pointer
|
||||
|
||||
FillSizeAndRet:
|
||||
ldy #usedblock::size ; p->size = size;
|
||||
lda ptr1 ; Low byte of block size
|
||||
sta (ptr2),y
|
||||
iny ; Points to freeblock::size+1
|
||||
lda ptr1+1
|
||||
sta (ptr2),y
|
||||
ldy #usedblock::size ; p->size = size;
|
||||
lda ptr1 ; Low byte of block size
|
||||
sta (ptr2),y
|
||||
iny ; Points to freeblock::size+1
|
||||
lda ptr1+1
|
||||
sta (ptr2),y
|
||||
|
||||
RetUserPtr:
|
||||
ldy #usedblock::start ; p->start = p
|
||||
@@ -330,10 +330,10 @@ RetUserPtr:
|
||||
|
||||
; Return the user pointer, which points behind the struct usedblock
|
||||
|
||||
lda ptr2 ; return ++p;
|
||||
ldx ptr2+1
|
||||
add #HEAP_ADMIN_SPACE
|
||||
bcc @L9
|
||||
inx
|
||||
@L9: rts
|
||||
lda ptr2 ; return ++p;
|
||||
ldx ptr2+1
|
||||
add #HEAP_ADMIN_SPACE
|
||||
bcc @L9
|
||||
inx
|
||||
@L9: rts
|
||||
|
||||
|
||||
@@ -4,23 +4,23 @@
|
||||
; void* __fastcall__ memchr (const void* p, int c, size_t n);
|
||||
;
|
||||
|
||||
.export _memchr
|
||||
.import popax, return0
|
||||
.importzp ptr1, ptr2
|
||||
.export _memchr
|
||||
.import popax, return0
|
||||
.importzp ptr1, ptr2
|
||||
|
||||
|
||||
.proc _memchr
|
||||
|
||||
eor #$FF
|
||||
sta ptr2
|
||||
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
|
||||
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
|
||||
@@ -45,13 +45,13 @@ notfound:
|
||||
|
||||
; 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
|
||||
found: ldx ptr1+1 ; get high byte of pointer
|
||||
tya ; low byte offset
|
||||
clc
|
||||
adc ptr1
|
||||
bcc L9
|
||||
inx
|
||||
L9: rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
@@ -4,69 +4,69 @@
|
||||
; int memcmp (const void* p1, const void* p2, size_t count);
|
||||
;
|
||||
|
||||
.export _memcmp
|
||||
.import popax, return0
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
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
|
||||
bcs Greater
|
||||
ldx #$FF ; Make result negative
|
||||
rts
|
||||
|
||||
Greater:
|
||||
ldx #$01 ; Make result positive
|
||||
rts
|
||||
ldx #$01 ; Make result positive
|
||||
rts
|
||||
|
||||
|
||||
@@ -10,71 +10,71 @@
|
||||
; at memmove!
|
||||
;
|
||||
|
||||
.export _memcpy, memcpy_upwards, memcpy_getparams
|
||||
.import popax
|
||||
.importzp sp, ptr1, ptr2, ptr3
|
||||
.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
|
||||
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
|
||||
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
|
||||
; 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
|
||||
L3: lda (ptr1),Y ; copy a byte
|
||||
sta (ptr2),Y
|
||||
iny
|
||||
dex
|
||||
bne L3
|
||||
|
||||
; }
|
||||
; }
|
||||
|
||||
done: jmp popax ; Pop ptr and return as result
|
||||
done: jmp popax ; Pop ptr and return as result
|
||||
|
||||
; ----------------------------------------------------------------------
|
||||
; Get the parameters from stack as follows:
|
||||
;
|
||||
; size --> ptr3
|
||||
; size --> ptr3
|
||||
; src --> ptr1
|
||||
; dest --> ptr2
|
||||
; First argument (dest) will remain on stack and is returned in a/x!
|
||||
; 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
|
||||
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
|
||||
jsr popax
|
||||
sta ptr1
|
||||
stx ptr1+1 ; save src to ptr1
|
||||
|
||||
; save dest to ptr2
|
||||
ldy #1 ; (direct stack access is three cycles faster
|
||||
; 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
|
||||
tax
|
||||
stx ptr2+1 ; save high byte of ptr2
|
||||
dey ; Y = 0
|
||||
lda (sp),y ; Get ptr2 low
|
||||
sta ptr2
|
||||
rts
|
||||
sta ptr2
|
||||
rts
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
; NOTE: This function uses entry points from memcpy!
|
||||
;
|
||||
|
||||
.export _memmove
|
||||
.export _memmove
|
||||
.import memcpy_getparams, memcpy_upwards, popax
|
||||
.importzp ptr1, ptr2, ptr3, ptr4, tmp1
|
||||
.importzp ptr1, ptr2, ptr3, ptr4, tmp1
|
||||
|
||||
.macpack generic
|
||||
.macpack longbranch
|
||||
@@ -31,54 +31,54 @@ _memmove:
|
||||
|
||||
; Copy downwards. Adjust the pointers to the end of the memory regions.
|
||||
|
||||
lda ptr1+1
|
||||
add ptr3+1
|
||||
sta ptr1+1
|
||||
lda ptr1+1
|
||||
add ptr3+1
|
||||
sta ptr1+1
|
||||
|
||||
lda ptr2+1
|
||||
add ptr3+1
|
||||
sta ptr2+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...
|
||||
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
|
||||
@entry:
|
||||
dey
|
||||
bne @copyByte
|
||||
lda (ptr1),y ; copy remaining byte
|
||||
sta (ptr2),y
|
||||
dex ; one page to copy less
|
||||
bne @initBase ; still a page to copy?
|
||||
|
||||
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
|
||||
done: jmp popax ; Pop ptr and return as result
|
||||
|
||||
|
||||
@@ -15,79 +15,79 @@
|
||||
; in a/x is of any use.
|
||||
;
|
||||
|
||||
.export _memset, _bzero, __bzero
|
||||
.import popax
|
||||
.importzp sp, ptr1, ptr2, ptr3
|
||||
.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
|
||||
ldx #0 ; Fill with zeros
|
||||
beq common
|
||||
|
||||
_memset:
|
||||
sta ptr3 ; Save n
|
||||
stx ptr3+1
|
||||
jsr popax ; Get c
|
||||
tax
|
||||
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
|
||||
common: ; Fill value is in X!
|
||||
ldy #1
|
||||
lda (sp),y
|
||||
sta ptr1+1 ; save high byte of ptr
|
||||
dey ; Y = 0
|
||||
sta ptr1+1 ; save high byte of ptr
|
||||
dey ; Y = 0
|
||||
lda (sp),y ; Get ptr
|
||||
sta ptr1
|
||||
sta ptr1
|
||||
|
||||
lsr ptr3+1 ; divide number of
|
||||
ror ptr3 ; bytes by two to increase
|
||||
bcc evenCount ; speed (ptr3 = ptr3/2)
|
||||
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
|
||||
; 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
|
||||
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
|
||||
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
|
||||
; 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
|
||||
beq leave ; something to set? No -> leave
|
||||
L2: ldy ptr3 ; Get the low byte of n
|
||||
beq leave ; something to set? No -> leave
|
||||
|
||||
L3: dey
|
||||
sta (ptr1),y ; set bytes in low
|
||||
sta (ptr2),y ; and high section
|
||||
bne L3 ; flags still up to date from dey!
|
||||
leave:
|
||||
jmp popax ; Pop ptr and return as result
|
||||
L3: dey
|
||||
sta (ptr1),y ; set bytes in low
|
||||
sta (ptr2),y ; and high section
|
||||
bne L3 ; flags still up to date from dey!
|
||||
leave:
|
||||
jmp popax ; Pop ptr and return as result
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
;
|
||||
; Oliver Schmidt, 2005-08-30
|
||||
;
|
||||
; int mkdir (const char* name, ...); /* May take a mode argument */
|
||||
; int mkdir (const char* name, ...); /* May take a mode argument */
|
||||
;
|
||||
|
||||
.export _mkdir
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
;* */
|
||||
;* modfree.s */
|
||||
;* */
|
||||
;* Free loaded o65 modules */
|
||||
;* Free loaded o65 modules */
|
||||
;* */
|
||||
;* */
|
||||
;* */
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
|
||||
|
||||
|
||||
#include <stddef.h> /* define NULL */
|
||||
#include <stdlib.h> /* declare function's prototype */
|
||||
#include <stddef.h> /* define NULL */
|
||||
#include <stdlib.h> /* declare function's prototype */
|
||||
#include <_heap.h>
|
||||
|
||||
#include <errno.h>
|
||||
#define EOK 0 /* No errors (non-standard name) */
|
||||
#define EOK 0 /* No errors (non-standard name) */
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; Ullrich von Bassewitz, 1.12.2000
|
||||
;
|
||||
|
||||
.export _printf
|
||||
.import _stdout, pushax, addysp, _vfprintf
|
||||
.importzp sp, ptr1
|
||||
.export _printf
|
||||
.import _stdout, pushax, addysp, _vfprintf
|
||||
.importzp sp, ptr1
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Code
|
||||
@@ -24,10 +24,10 @@ ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
|
||||
_printf:
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
|
||||
; We are using a (hopefully) clever trick here to reduce code size. On entry,
|
||||
; the stack pointer points to the last pushed parameter of the variable
|
||||
; the stack pointer points to the last pushed parameter of the variable
|
||||
; parameter list. Adding the number of parameter bytes, would result in a
|
||||
; pointer that points *after* the Format parameter.
|
||||
; Since we have to push stdout anyway, we will do that here, so
|
||||
@@ -37,40 +37,40 @@ _printf:
|
||||
; be pushed next.
|
||||
;
|
||||
|
||||
lda _stdout
|
||||
ldx _stdout+1
|
||||
jsr pushax
|
||||
lda _stdout
|
||||
ldx _stdout+1
|
||||
jsr pushax
|
||||
|
||||
; Now calculate the va_list pointer, which does points to Format
|
||||
|
||||
lda sp
|
||||
ldx sp+1
|
||||
add ParamSize
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: sta ptr1
|
||||
stx ptr1+1
|
||||
lda sp
|
||||
ldx sp+1
|
||||
add ParamSize
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
; Push Format
|
||||
|
||||
ldy #1
|
||||
lda (ptr1),y
|
||||
tax
|
||||
dey
|
||||
lda (ptr1),y
|
||||
jsr pushax
|
||||
ldy #1
|
||||
lda (ptr1),y
|
||||
tax
|
||||
dey
|
||||
lda (ptr1),y
|
||||
jsr pushax
|
||||
|
||||
; Load va_list (last and __fastcall__ parameter to vfprintf)
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Call vfprintf
|
||||
|
||||
jsr _vfprintf
|
||||
jsr _vfprintf
|
||||
|
||||
; Cleanup the stack. We will return what we got from vfprintf
|
||||
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; int __fastcall__ putchar (int c);
|
||||
;
|
||||
|
||||
.export _putchar
|
||||
.export _putchar
|
||||
.import pushax
|
||||
.import _stdout
|
||||
.import _fputc
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
|
||||
; Since free() has destroyed ptr2, we need another copy ...
|
||||
|
||||
jsr copyenvptr ; Copy __environ to ptr2
|
||||
jsr copyenvptr ; Copy __environ to ptr2
|
||||
|
||||
; Bump the environment count and remember it in X. Add the final NULL entry.
|
||||
|
||||
@@ -169,10 +169,10 @@ addentry:
|
||||
; Error entries
|
||||
|
||||
nomem: lda #ENOMEM
|
||||
error: jsr __seterrno
|
||||
lda #$FF ; Return -1
|
||||
tax
|
||||
rts
|
||||
error: jsr __seterrno
|
||||
lda #$FF ; Return -1
|
||||
tax
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ int __fastcall__ puts (const char* s)
|
||||
|
||||
/* Assume stdout is always open */
|
||||
if (write (stdout->f_fd, s, strlen (s)) < 0 ||
|
||||
write (stdout->f_fd, &nl, 1) < 0) {
|
||||
stdout->f_flags |= _FERROR;
|
||||
return -1;
|
||||
write (stdout->f_fd, &nl, 1) < 0) {
|
||||
stdout->f_flags |= _FERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Done */
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
static void QuickSort (register unsigned char* Base, int Lo, int Hi,
|
||||
register size_t Size,
|
||||
int (*Compare)(const void*, const void*))
|
||||
int (*Compare)(const void*, const void*))
|
||||
/* Internal recursive function. Works with ints, but this shouldn't be
|
||||
* a problem.
|
||||
*/
|
||||
@@ -21,42 +21,42 @@ static void QuickSort (register unsigned char* Base, int Lo, int Hi,
|
||||
|
||||
/* Quicksort */
|
||||
while (Hi > Lo) {
|
||||
I = Lo + Size;
|
||||
J = Hi;
|
||||
while (I <= J) {
|
||||
while (I <= J && Compare (Base + Lo, Base + I) >= 0) {
|
||||
I += Size;
|
||||
}
|
||||
while (I <= J && Compare (Base + Lo, Base + J) < 0) {
|
||||
J -= Size;
|
||||
}
|
||||
if (I <= J) {
|
||||
_swap (Base + I, Base + J, Size);
|
||||
I += Size;
|
||||
J -= Size;
|
||||
}
|
||||
}
|
||||
if (J != Lo) {
|
||||
_swap (Base + J, Base + Lo, Size);
|
||||
}
|
||||
if (((unsigned) J) * 2 > (Hi + Lo)) {
|
||||
QuickSort (Base, J + Size, Hi, Size, Compare);
|
||||
Hi = J - Size;
|
||||
} else {
|
||||
QuickSort (Base, Lo, J - Size, Size, Compare);
|
||||
Lo = J + Size;
|
||||
}
|
||||
I = Lo + Size;
|
||||
J = Hi;
|
||||
while (I <= J) {
|
||||
while (I <= J && Compare (Base + Lo, Base + I) >= 0) {
|
||||
I += Size;
|
||||
}
|
||||
while (I <= J && Compare (Base + Lo, Base + J) < 0) {
|
||||
J -= Size;
|
||||
}
|
||||
if (I <= J) {
|
||||
_swap (Base + I, Base + J, Size);
|
||||
I += Size;
|
||||
J -= Size;
|
||||
}
|
||||
}
|
||||
if (J != Lo) {
|
||||
_swap (Base + J, Base + Lo, Size);
|
||||
}
|
||||
if (((unsigned) J) * 2 > (Hi + Lo)) {
|
||||
QuickSort (Base, J + Size, Hi, Size, Compare);
|
||||
Hi = J - Size;
|
||||
} else {
|
||||
QuickSort (Base, Lo, J - Size, Size, Compare);
|
||||
Lo = J + Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void __fastcall__ qsort (void* base, size_t nmemb, size_t size,
|
||||
int (*compare)(const void*, const void*))
|
||||
int (*compare)(const void*, const void*))
|
||||
/* Quicksort implementation */
|
||||
{
|
||||
if (nmemb > 1) {
|
||||
QuickSort (base, 0, (nmemb-1) * size, size, compare);
|
||||
QuickSort (base, 0, (nmemb-1) * size, size, compare);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,48 +19,48 @@
|
||||
; detectable patterns.
|
||||
;
|
||||
|
||||
.export _rand, _srand
|
||||
.export _rand, _srand
|
||||
|
||||
.data
|
||||
|
||||
; The seed. When srand() is not called, the C standard says that that rand()
|
||||
; should behave as if srand() was called with an argument of 1 before.
|
||||
rand: .dword 1
|
||||
rand: .dword 1
|
||||
|
||||
.code
|
||||
|
||||
_rand: clc
|
||||
lda rand+0 ; SEED *= $01010101
|
||||
adc rand+1
|
||||
sta rand+1
|
||||
adc rand+2
|
||||
sta rand+2
|
||||
adc rand+3
|
||||
sta rand+3
|
||||
clc
|
||||
lda rand+0 ; SEED += $31415927
|
||||
adc #$27
|
||||
sta rand+0
|
||||
lda rand+1
|
||||
adc #$59
|
||||
sta rand+1
|
||||
pha
|
||||
lda rand+2
|
||||
adc #$41
|
||||
sta rand+2
|
||||
and #$7f ; Suppress sign bit (make it positive)
|
||||
tax
|
||||
lda rand+3
|
||||
adc #$31
|
||||
sta rand+3
|
||||
pla ; return bit 8-22 in (X,A)
|
||||
rts
|
||||
_rand: clc
|
||||
lda rand+0 ; SEED *= $01010101
|
||||
adc rand+1
|
||||
sta rand+1
|
||||
adc rand+2
|
||||
sta rand+2
|
||||
adc rand+3
|
||||
sta rand+3
|
||||
clc
|
||||
lda rand+0 ; SEED += $31415927
|
||||
adc #$27
|
||||
sta rand+0
|
||||
lda rand+1
|
||||
adc #$59
|
||||
sta rand+1
|
||||
pha
|
||||
lda rand+2
|
||||
adc #$41
|
||||
sta rand+2
|
||||
and #$7f ; Suppress sign bit (make it positive)
|
||||
tax
|
||||
lda rand+3
|
||||
adc #$31
|
||||
sta rand+3
|
||||
pla ; return bit 8-22 in (X,A)
|
||||
rts
|
||||
|
||||
_srand: sta rand+0 ; Store the seed
|
||||
stx rand+1
|
||||
lda #0
|
||||
sta rand+2 ; Set MSW to zero
|
||||
sta rand+3
|
||||
rts
|
||||
_srand: sta rand+0 ; Store the seed
|
||||
stx rand+1
|
||||
lda #0
|
||||
sta rand+2 ; Set MSW to zero
|
||||
sta rand+3
|
||||
rts
|
||||
|
||||
|
||||
|
||||
@@ -48,15 +48,15 @@ void* __fastcall__ realloc (void* block, register size_t size)
|
||||
|
||||
/* Check the block parameter */
|
||||
if (!block) {
|
||||
/* Block is NULL, same as malloc */
|
||||
return malloc (size);
|
||||
/* Block is NULL, same as malloc */
|
||||
return malloc (size);
|
||||
}
|
||||
|
||||
/* Check the size parameter */
|
||||
if (size == 0) {
|
||||
/* Block is not NULL, but size is: free the block */
|
||||
free (block);
|
||||
return 0;
|
||||
/* Block is not NULL, but size is: free the block */
|
||||
free (block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make the internal used size from the given size */
|
||||
@@ -75,15 +75,15 @@ void* __fastcall__ realloc (void* block, register size_t size)
|
||||
|
||||
/* Is the block at the current heap top? */
|
||||
if (((unsigned) b) + oldsize == ((unsigned) _heapptr)) {
|
||||
/* Check if we've enough memory at the heap top */
|
||||
newhptr = ((unsigned) _heapptr) - oldsize + size;
|
||||
if (newhptr <= ((unsigned) _heapend)) {
|
||||
/* Ok, there's space enough */
|
||||
_heapptr = (unsigned*) newhptr;
|
||||
/* Check if we've enough memory at the heap top */
|
||||
newhptr = ((unsigned) _heapptr) - oldsize + size;
|
||||
if (newhptr <= ((unsigned) _heapend)) {
|
||||
/* Ok, there's space enough */
|
||||
_heapptr = (unsigned*) newhptr;
|
||||
b->size = size;
|
||||
b->start = b;
|
||||
return block;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
/* The given block was not located on top of the heap, or there's no
|
||||
@@ -91,19 +91,19 @@ void* __fastcall__ realloc (void* block, register size_t size)
|
||||
*/
|
||||
if (newblock = malloc (size)) {
|
||||
|
||||
/* Adjust the old size to the user visible portion */
|
||||
oldsize -= HEAP_ADMIN_SPACE;
|
||||
/* Adjust the old size to the user visible portion */
|
||||
oldsize -= HEAP_ADMIN_SPACE;
|
||||
|
||||
/* If the new block is larger than the old one, copy the old
|
||||
* data only
|
||||
*/
|
||||
if (size > oldsize) {
|
||||
size = oldsize;
|
||||
}
|
||||
/* If the new block is larger than the old one, copy the old
|
||||
* data only
|
||||
*/
|
||||
if (size > oldsize) {
|
||||
size = oldsize;
|
||||
}
|
||||
|
||||
/* Copy the block data */
|
||||
memcpy (newblock, block, size);
|
||||
free (block);
|
||||
/* Copy the block data */
|
||||
memcpy (newblock, block, size);
|
||||
free (block);
|
||||
}
|
||||
return newblock;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -22,4 +22,4 @@ void __fastcall__ rewind (FILE* f)
|
||||
clearerr(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
; 2004-12-31, Greg King
|
||||
;
|
||||
|
||||
.export _scanf
|
||||
.export _scanf
|
||||
|
||||
.import _stdin, pushax, addysp, _vfscanf
|
||||
.import sp:zp, ptr1:zp
|
||||
.import _stdin, pushax, addysp, _vfscanf
|
||||
.import sp:zp, ptr1:zp
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Code
|
||||
;
|
||||
_scanf:
|
||||
sty ArgSize ; Number of argument bytes passed in .Y
|
||||
sty ArgSize ; Number of argument bytes passed in .Y
|
||||
|
||||
; We are using a (hopefully) clever trick here to reduce code size. On entry,
|
||||
; the stack pointer points to the last pushed argument of the variable
|
||||
@@ -28,47 +28,47 @@ _scanf:
|
||||
; * we will have the address of the Format argument which needs to
|
||||
; be pushed next.
|
||||
|
||||
lda _stdin
|
||||
ldx _stdin+1
|
||||
jsr pushax
|
||||
lda _stdin
|
||||
ldx _stdin+1
|
||||
jsr pushax
|
||||
|
||||
; Now, calculate the va_list pointer, which does point to Format.
|
||||
|
||||
lda sp
|
||||
ldx sp+1
|
||||
add ArgSize
|
||||
bcc @L1
|
||||
lda sp
|
||||
ldx sp+1
|
||||
add ArgSize
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: sta ptr1
|
||||
stx ptr1+1
|
||||
@L1: sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
; Push a copy of Format.
|
||||
|
||||
ldy #1
|
||||
lda (ptr1),y
|
||||
ldy #1
|
||||
lda (ptr1),y
|
||||
tax
|
||||
dey
|
||||
lda (ptr1),y
|
||||
jsr pushax
|
||||
lda (ptr1),y
|
||||
jsr pushax
|
||||
|
||||
; Load va_list [last and __fastcall__ argument to vfscanf()].
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Call vfscanf().
|
||||
|
||||
jsr _vfscanf
|
||||
jsr _vfscanf
|
||||
|
||||
; Clean up the stack. We will return what we got from vfscanf().
|
||||
|
||||
ldy ArgSize
|
||||
jmp addysp
|
||||
ldy ArgSize
|
||||
jmp addysp
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
;
|
||||
.bss
|
||||
ArgSize:
|
||||
.res 1 ; Number of argument bytes
|
||||
.res 1 ; Number of argument bytes
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
; Copy the pointer to the environment to the zero page
|
||||
|
||||
jsr copyenvptr
|
||||
jsr copyenvptr
|
||||
|
||||
; Loop over all environment entries trying to find the requested one.
|
||||
|
||||
@@ -71,13 +71,13 @@
|
||||
; copyenvptr: Copy _environ to ptr2
|
||||
;
|
||||
|
||||
.proc copyenvptr
|
||||
.proc copyenvptr
|
||||
|
||||
lda __environ
|
||||
sta ptr2
|
||||
lda __environ+1
|
||||
sta ptr2+1
|
||||
rts
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
@@ -4,49 +4,49 @@
|
||||
; int setjmp (jmp_buf buf);
|
||||
;
|
||||
|
||||
.export __setjmp
|
||||
.importzp sp, ptr1
|
||||
.export __setjmp
|
||||
.importzp sp, ptr1
|
||||
|
||||
__setjmp:
|
||||
sta ptr1 ; Save buf
|
||||
stx ptr1+1
|
||||
ldy #0
|
||||
sta ptr1 ; Save buf
|
||||
stx ptr1+1
|
||||
ldy #0
|
||||
|
||||
; The parameter stack is now empty, put it into buf
|
||||
|
||||
lda sp
|
||||
sta (ptr1),y
|
||||
iny
|
||||
lda sp+1
|
||||
sta (ptr1),y
|
||||
iny
|
||||
lda sp
|
||||
sta (ptr1),y
|
||||
iny
|
||||
lda sp+1
|
||||
sta (ptr1),y
|
||||
iny
|
||||
|
||||
; Put the return stack pointer next
|
||||
|
||||
tsx
|
||||
inx
|
||||
inx ; drop return address
|
||||
txa
|
||||
sta (ptr1),y
|
||||
iny
|
||||
tsx
|
||||
inx
|
||||
inx ; drop return address
|
||||
txa
|
||||
sta (ptr1),y
|
||||
iny
|
||||
|
||||
; Last thing is the return address.
|
||||
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
sta (ptr1),y ; high byte first
|
||||
iny
|
||||
pha
|
||||
txa
|
||||
sta (ptr1),y
|
||||
pha
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
sta (ptr1),y ; high byte first
|
||||
iny
|
||||
pha
|
||||
txa
|
||||
sta (ptr1),y
|
||||
pha
|
||||
|
||||
; Return zero
|
||||
|
||||
lda #0
|
||||
tax
|
||||
rts
|
||||
lda #0
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
; __sigfunc __fastcall__ signal (int sig, __sigfunc func);
|
||||
;
|
||||
|
||||
.import popax
|
||||
.importzp ptr1
|
||||
.import popax
|
||||
.importzp ptr1
|
||||
|
||||
.include "signal.inc"
|
||||
.include "errno.inc"
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; Ullrich von Bassewitz, 2009-09-26
|
||||
;
|
||||
|
||||
.export _snprintf
|
||||
.import pushax, addysp, decsp6, _vsnprintf
|
||||
.importzp sp, ptr1
|
||||
.export _snprintf
|
||||
.import pushax, addysp, decsp6, _vsnprintf
|
||||
.importzp sp, ptr1
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Code
|
||||
@@ -24,7 +24,7 @@ ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
|
||||
_snprintf:
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
|
||||
; We have to push buf/size/format, both in the order they already have on stack.
|
||||
; To make this somewhat more efficient, we will create space on the stack and
|
||||
@@ -33,37 +33,37 @@ _snprintf:
|
||||
; of the fixed arguments, this will allow us to calculate the pointer to the
|
||||
; fixed size arguments easier (they're just ParamSize bytes away).
|
||||
|
||||
jsr decsp6
|
||||
jsr decsp6
|
||||
|
||||
; Calculate a pointer to the Format argument
|
||||
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
|
||||
; Now copy buf/size/format
|
||||
|
||||
ldy #6-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
ldy #6-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
|
||||
; Load va_list (last and __fastcall__ parameter to vsprintf)
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Call vsnprintf
|
||||
|
||||
jsr _vsnprintf
|
||||
jsr _vsnprintf
|
||||
|
||||
; Cleanup the stack. We will return what we got from vsprintf
|
||||
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; Ullrich von Bassewitz, 1.12.2000
|
||||
;
|
||||
|
||||
.export _sprintf
|
||||
.import pushax, addysp, decsp4, _vsprintf
|
||||
.importzp sp, ptr1
|
||||
.export _sprintf
|
||||
.import pushax, addysp, decsp4, _vsprintf
|
||||
.importzp sp, ptr1
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Code
|
||||
@@ -24,7 +24,7 @@ ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
|
||||
_sprintf:
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
|
||||
; We have to push buf and format, both in the order they already have on stack.
|
||||
; To make this somewhat more efficient, we will create space on the stack and
|
||||
@@ -33,37 +33,37 @@ _sprintf:
|
||||
; of the fixed arguments, this will allow us to calculate the pointer to the
|
||||
; fixed size arguments easier (they're just ParamSize bytes away).
|
||||
|
||||
jsr decsp4
|
||||
jsr decsp4
|
||||
|
||||
; Calculate a pointer to the Format argument
|
||||
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
|
||||
; Now copy both, buf and format
|
||||
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
|
||||
; Load va_list (last and __fastcall__ parameter to vsprintf)
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Call vsprintf
|
||||
|
||||
jsr _vsprintf
|
||||
jsr _vsprintf
|
||||
|
||||
; Cleanup the stack. We will return what we got from vsprintf
|
||||
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
; Ullrich von Bassewitz, 2004-11-28
|
||||
;
|
||||
|
||||
.export _sscanf
|
||||
.import addysp, decsp4, _vsscanf
|
||||
.importzp sp, ptr1
|
||||
.export _sscanf
|
||||
.import addysp, decsp4, _vsscanf
|
||||
.importzp sp, ptr1
|
||||
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
ParamSize: .res 1 ; Number of parameter bytes
|
||||
|
||||
; ----------------------------------------------------------------------------
|
||||
; Code
|
||||
@@ -37,7 +37,7 @@ ParamSize: .res 1 ; Number of parameter bytes
|
||||
.code
|
||||
|
||||
_sscanf:
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
sty ParamSize ; Number of param bytes passed in Y
|
||||
|
||||
; We have to push buf and format, both in the order they already have on stack.
|
||||
; To make this somewhat more efficient, we will create space on the stack and
|
||||
@@ -46,37 +46,37 @@ _sscanf:
|
||||
; of the fixed arguments, this will allow us to calculate the pointer to the
|
||||
; fixed size arguments easier (they're just ParamSize bytes away).
|
||||
|
||||
jsr decsp4
|
||||
jsr decsp4
|
||||
|
||||
; Calculate a pointer to the fixed parameters
|
||||
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
lda ParamSize
|
||||
add sp
|
||||
sta ptr1
|
||||
ldx sp+1
|
||||
bcc @L1
|
||||
inx
|
||||
@L1: stx ptr1+1
|
||||
|
||||
; Now copy both, str and format
|
||||
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
ldy #4-1
|
||||
@L2: lda (ptr1),y
|
||||
sta (sp),y
|
||||
dey
|
||||
bpl @L2
|
||||
|
||||
; Load va_list (last and __fastcall__ parameter to vsscanf)
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
|
||||
; Call vsscanf
|
||||
|
||||
jsr _vsscanf
|
||||
jsr _vsscanf
|
||||
|
||||
; Cleanup the stack. We will return what we got from vsscanf
|
||||
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
ldy ParamSize
|
||||
jmp addysp
|
||||
|
||||
|
||||
@@ -4,52 +4,52 @@
|
||||
; char* strcat (char* dest, const char* src);
|
||||
;
|
||||
|
||||
.export _strcat
|
||||
.import popax
|
||||
.importzp ptr1, ptr2, tmp3
|
||||
.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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
sc5: lda tmp3 ; X does still contain high byte
|
||||
rts
|
||||
|
||||
|
||||
|
||||
@@ -4,45 +4,45 @@
|
||||
; const char* strchr (const char* s, int c);
|
||||
;
|
||||
|
||||
.export _strchr
|
||||
.import popax
|
||||
.importzp ptr1, tmp1
|
||||
.export _strchr
|
||||
.import popax
|
||||
.importzp ptr1, tmp1
|
||||
|
||||
_strchr:
|
||||
sta tmp1 ; Save c
|
||||
jsr popax ; get s
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #0
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
lda #0
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,32 +4,32 @@
|
||||
; int strcmp (const char* s1, const char* s2);
|
||||
;
|
||||
|
||||
.export _strcmp
|
||||
.import popax
|
||||
.importzp ptr1, ptr2
|
||||
.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
|
||||
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
|
||||
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
|
||||
L1: bcs L2
|
||||
ldx #$FF
|
||||
rts
|
||||
|
||||
L2: ldx #$01
|
||||
L3: rts
|
||||
L2: ldx #$01
|
||||
L3: rts
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
; Since we don't have locales, this function is equivalent to strcmp.
|
||||
;
|
||||
|
||||
.export _strcoll
|
||||
.import _strcmp
|
||||
.export _strcoll
|
||||
.import _strcmp
|
||||
|
||||
_strcoll = _strcmp
|
||||
_strcoll = _strcmp
|
||||
|
||||
|
||||
@@ -4,27 +4,27 @@
|
||||
; char* strcpy (char* dest, const char* src);
|
||||
;
|
||||
|
||||
.export _strcpy
|
||||
.import popax
|
||||
.importzp ptr1, ptr2
|
||||
.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
|
||||
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
|
||||
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
|
||||
L9: lda ptr2 ; X still contains high byte
|
||||
rts
|
||||
|
||||
|
||||
@@ -4,50 +4,50 @@
|
||||
; size_t strcspn (const char* s1, const char* s2);
|
||||
;
|
||||
|
||||
.export _strcspn
|
||||
.import popax
|
||||
.importzp ptr1, ptr2, tmp1, tmp2, tmp3
|
||||
.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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
L6: txa ; get low counter byte
|
||||
ldx tmp1 ; get high counter byte
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
; 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
|
||||
.importzp sp, tmp1, ptr4
|
||||
.import pushax, decsp4, incsp4
|
||||
.import _strlen, _malloc, _memcpy
|
||||
.export _strdup
|
||||
|
||||
.macpack cpu
|
||||
.macpack generic
|
||||
.macpack generic
|
||||
|
||||
_strdup:
|
||||
|
||||
@@ -20,66 +20,66 @@ _strdup:
|
||||
; 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
|
||||
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
|
||||
ldy #1
|
||||
txa
|
||||
sta (sp),y
|
||||
pla
|
||||
.if (.cpu .bitand CPU_ISET_65SC02)
|
||||
sta (sp)
|
||||
sta (sp)
|
||||
.else
|
||||
dey
|
||||
sta (sp),y
|
||||
dey
|
||||
sta (sp),y
|
||||
.endif
|
||||
|
||||
; Get length of S (which is still in a/x)
|
||||
|
||||
jsr _strlen
|
||||
jsr _strlen
|
||||
|
||||
; Calculate strlen(S)+1 (the space needed)
|
||||
|
||||
add #1
|
||||
bcc @L1
|
||||
inx
|
||||
add #1
|
||||
bcc @L1
|
||||
inx
|
||||
|
||||
; Save the space we're about to allocate in ptr4
|
||||
|
||||
@L1: sta ptr4
|
||||
stx ptr4+1
|
||||
@L1: sta ptr4
|
||||
stx ptr4+1
|
||||
|
||||
; Allocate memory. _malloc will not use ptr4
|
||||
|
||||
jsr _malloc
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
tax
|
||||
jmp incsp4 ; Drop stack frame
|
||||
|
||||
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
; /* Map an error number to an error message */
|
||||
;
|
||||
|
||||
.export _strerror
|
||||
.import __sys_errlist
|
||||
.export _strerror
|
||||
.import __sys_errlist
|
||||
|
||||
.include "errno.inc"
|
||||
.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
|
||||
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
|
||||
|
||||
@@ -22,14 +22,14 @@ _strerror:
|
||||
sta __errno
|
||||
lda #>EINVAL ; = 0
|
||||
sta __errno+1
|
||||
; lda #$00 ; A contains zero: "Unknown error"
|
||||
; 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
|
||||
@L2: asl a ; * 2
|
||||
tay
|
||||
ldx __sys_errlist+1,y
|
||||
lda __sys_errlist,y
|
||||
rts
|
||||
|
||||
|
||||
|
||||
@@ -162,9 +162,9 @@ size_t __fastcall__ strftime (char* buf, size_t bufsize, const char* format,
|
||||
|
||||
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);
|
||||
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':
|
||||
|
||||
@@ -1,60 +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 */
|
||||
; 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
|
||||
.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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
L3: bcs L4
|
||||
ldx #$FF
|
||||
rts
|
||||
|
||||
L4: ldx #$01
|
||||
L5: rts
|
||||
L4: ldx #$01
|
||||
L5: rts
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user