Commit Graph

19 Commits

Author SHA1 Message Date
Stephen Heumann d9e26d4467 Small optimizations related to 8/16-bit register switching. 2024-03-22 21:10:33 -05:00
Stephen Heumann 0e519e1e58 Small optimizations in memset and memcpy. 2024-02-29 17:16:47 -06:00
Stephen Heumann 49ffb1065b Unroll the core loop of strlen one time.
This makes the core loop about 10% faster at the cost of 5 extra code bytes, which seems like a reasonable tradeoff.
2024-02-26 22:14:59 -06:00
Stephen Heumann 9d42552756 strncmp: Fix issues related to very large n values.
This fixes the following issues:
*If n was 0x80000000 or greater, strncmp would return 0 without performing a comparison.
*If n was 0x1000000 or greater, strncmp might compare fewer characters than it should because the high byte of n was effectively ignored, causing it to return 0 when it should not.

Here is an example demonstrating these issues:

#pragma memorymodel 1
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define LEN 100000
int main(void) {
        char *s1 = malloc(LEN+1);
        char *s2 = malloc(LEN+1);
        if (!s1 || !s2)
                return 0;
        for (unsigned long i = 0; i < LEN; i++) {
                s2[i] = s1[i] = '0' + (i & 0x07);
        }
        s1[LEN] = 'x';
        return strncmp(s1,s2,0xFFFFFFFF);
}
2024-02-19 22:12:26 -06:00
Stephen Heumann bbfad1e299 strncat: fix more issues related to large n values.
This addresses the following issues:
*If the low-order 16 bits of n were 0x0000, no concatenation would be performed.
*If n was 0x1000000 or greater, the output could be cut off prematurely because the high byte of n was effectively ignored.

The following test program demonstrates these issues:

#pragma memorymodel 1
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define LEN2 100000
int main(void) {
        char *s1 = malloc(LEN2+2);
        char *s2 = malloc(LEN2+1);
        if (!s1 || !s2)
                return 0;
        for (unsigned long i = 0; i < LEN2; i++)
                s2[i] = '0' + (i & 0x07);
        strcpy(s1,"a");
        strncat(s1, s2, 0x1000000);
        puts(s1);
        printf("len = %zu\n", strlen(s1));
}
2024-02-19 22:01:53 -06:00
Stephen Heumann f1582be5a2 Fix handling of large strings in strncat.
There were two issues:
*If bit 15 of the n value was set, the second string would not be copied.
*If the length of the second string was 64K or more, it would not be copied properly because the pointers were not updated.

This test program demonstrates both issues:

#pragma memorymodel 1
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define LEN2 100000
int main(void) {
        char *s1 = malloc(LEN2+2);
        char *s2 = malloc(LEN2+1);
        if (!s1 || !s2)
                return 0;
        for (unsigned long i = 0; i < LEN2; i++)
                s2[i] = '0' + (i & 0x07);
        strcpy(s1,"a");
        strncat(s1, s2, LEN2);
        puts(s1);
        printf("len = %zu\n", strlen(s1));
}
2024-02-18 21:53:03 -06:00
Stephen Heumann b60c307ee6 Make strcat and strncat work properly when first string crosses a bank boundary.
Previously, the pointer was not properly updated to account for the bank crossing, so the characters from the second string would be written to the wrong bank.

Here is an example that illustrates this:

#include <memory.h>
#include <string.h>
#include <orca.h>
#include <stdio.h>
int main(void) {
        Handle hndl = NewHandle(0x1000f, userid(), 0xC000, 0);
        if (toolerror())
                return 0;
        char *s = *hndl;
        s = (void*)((unsigned long)s | 0xffff);
        strcpy(s, "foo");
        strcat(s, "bar");
        strncat(s, "baz", 5);
        puts(s);
}
2024-02-18 21:01:01 -06:00
Stephen Heumann bf3a4d7ceb Small optimizations in library code.
There should be no functional differences.
2024-02-18 17:35:21 -06:00
Stephen Heumann 84f471474a Use newer, more efficient ph2/ph4 macros throughout ORCALib.
These push DP values with pei, rather than lda+pha as in the old versions of the macros.
2022-06-30 19:01:47 -05:00
Stephen Heumann 3581d20a7c Standardize indentation using spaces.
Most files already used spaces, but three used tabs for indentation. These have been converted to use spaces. This allows the files to be displayed with proper formatting in modern editors and on GitHub. It also removes any dependency on SysTabs settings when assembling them.

The spacing in fpextra.asm was also modified to use standard column positions.

There are no non-whitespace changes in this commit.
2022-06-25 18:27:20 -05:00
Stephen Heumann ae504c6e4f Add support for EILSEQ errno value.
EILSEQ is required by C95 and later.
2021-10-02 14:34:35 -05:00
Stephen Heumann 3a847d245e Add strcoll and strxfrm functions.
This is currently a minimalistic implementation in which strcoll always sorts strings the same way as strcmp.
2021-09-30 18:37:54 -05:00
Stephen Heumann 79201198a1 Fix a bug in memset.
If the upper byte of the int argument was nonzero, it could write the wrong value (the OR of the upper and lower bytes). It should convert the value to unsigned char, i.e. just use the lower byte.
2021-03-10 20:08:36 -06:00
Stephen Heumann e5360c9605 Spellcheck comments. 2020-02-16 13:29:53 -06:00
Stephen Heumann 573bc6efa9 Use consistent indentation within files.
Tabs have been expanded to spaces in several files that use mainly spaces for indentation.

The files ctype.asm, stdio.asm, and string.asm consistently use tabs for indentation. The tabs in these files have been left alone, except that a few tabs between sentences in comments were changed to spaces.  One space-indented line in stdio.asm was changed to use a tab.
2020-02-16 13:28:18 -06:00
Stephen Heumann d89096236e Ensure that strtok returns NULL after reaching the end of the string.
It had been doing a null pointer dereference and effectively treating memory locations starting from 0 as the continuation of the string, potentially producing inappropriate results depending on what they contained.
2020-01-21 17:12:54 -06:00
Stephen Heumann 2be73c4e5d Make strerror() return a valid error string for unknown errno values.
This is required by C99 and later.
2018-09-09 21:26:21 -05:00
Kelvin Sherlock 578bda8439 CR -> LF 2017-10-31 13:14:07 -04:00
mikew50 954c3a02b5 ORCA libraries, from the Opus ][ CD 2017-10-01 18:00:58 -06:00