Compare commits

..

No commits in common. "86cd9b98d47314bea170693fc40c3e80d835bfc9" and "fc7aab6ebab012616e51fc56bef689a3ca032e06" have entirely different histories.

6 changed files with 34 additions and 77 deletions

5
TODO
View File

@ -13,12 +13,13 @@ Complementary elements on existing code.
* topti: support unicode fonts
* gray: find good values for more models than the Graph 35+E II
* render: get rid of GINT_NEED_VRAM and #define vram gint_vram if you need
* dma: dma_memcpy() and dma_memset(), possibly requiring alignment
* dma: maybe relax the 4-byte size constraint for dma_memset()
* core: try to leave add-in without reset in case of panic
* core: try to leave add-in without reset in case of fatal exception
* topti: support Unicode fonts
* hardware: fill in the HWMEM_FITTLB flag
* keyboard: think of extended functions
* keyboard: implement keydown() in an event-compliant way
* keyboard: add an intermediate-level API with some sort of IsKeyDown()
* cpg: spread spectrum on fxcg50
* bopti: blending modes for monochrome bitmaps (use topti assembler)
* display: use more of topti's assembler in drect()

View File

@ -9,21 +9,9 @@
#include <stdarg.h>
/* Formatted printing functions
These functions implement most of printf()'s features, including:
* Signed and unsigned integer formats (%d, %i, %o, %u, %x, %X)
* Character, string and pointer formats (%c, %s, %p)
* Format options (0, #, -, (space), length, precision)
* Parameter size (hh, h, l, ll)
* Limiting the size of the output and still returning the whole length
They do not support:
* Floating-point (%e, %E, %f, %F, %g, %G, %a, %A)
* Exotic integer types (intmax_t) or features (thousands separators)
A new fixed-point format %j has been added; it behaves like %d but includes
a decimal point. The number of decimal places is specified by the precision
field. */
These functions implement most of printf()'s features, except:
* Large parameters (ll)
* Floating-point (%e, %E, %f, %F, %g, %G, %a, %A) */
/* Print to string from var args */
int sprintf(char *str, char const *format, ...);

View File

@ -16,13 +16,10 @@ void *memset(void *dest, int byte, size_t n);
/* strlen(): Length of a NUL-terminated string */
size_t strlen(char const *str);
/* strncpy(): Copy a string with a size limit */
/* strncpy(): Copy a string with a size limit*/
char *strncpy(char *dst, char const *src, size_t n);
/* strcat(): Concatenation a string to a pre-allocated space */
/* strcat(): Concatenation of src in dest*/
char *strcat(char *dest, const char *src);
/* strcmp(): Compare NUL-terminated strings */
int strcmp(char const *s1, char const *s2);
#endif /* GINT_STD_STRING */

View File

@ -10,7 +10,7 @@
#include <gint/mpu/intc.h>
/* VBR address, from the linker script */
extern char gint_vbr[];
extern char gint_vbr;
/* System's VBR address */
GBSS static uint32_t system_vbr;
/* Size of exception and TLB handler */

View File

@ -54,12 +54,12 @@ struct kprint_options
/* How much significant characters of data, meaning varies */
uint16_t precision;
/* Size specifier for integers (%o, %x, %i, %d, %u), may be one of:
(0) char (8-bit)
(1) short (16-bit)
(2) int (32-bit)
(3) long (32-bit)
(4) long long (64-bit) */
/* Size specifier, may be one of:
(b) 8-bit data (%o, %x)
(w) 16-bit data (%o, %x)
(l) 32-bit data (%o, %x) or long int type (%i, %d, %u)
(q) 64-bit data (%o, %x) or long long int type (%i, %d, %u)
(h) short int type (%i, %d, %u) */
uint8_t size;
/* (#) Alternative form: base prefixes, decimal point */
@ -146,9 +146,8 @@ GINLINE static void kprint_outn(int byte, size_t n)
/* kprint_opt(): Parse option strings */
struct kprint_options kprint_opt(char const **options_ptr)
{
/* No options enabled by default, set the size to int */
struct kprint_options opt = { .size = 2 };
/* No options enabled by default */
struct kprint_options opt = { 0 };
/* This function acts as a deterministic finite automaton */
enum {
basic, /* Reading option characters */
@ -160,8 +159,8 @@ struct kprint_options kprint_opt(char const **options_ptr)
for(int c; (c = *options); options++)
{
int c_low = c | 0x20;
if(c_low >= 'a' && c_low <= 'z' && c != 'h' && c != 'l') break;
int c_lower = c | 0x20;
if(!c || (c_lower >= 'a' && c_lower < 'z')) break;
if(c == '.')
{
@ -193,8 +192,8 @@ struct kprint_options kprint_opt(char const **options_ptr)
}
/* Data size */
if(c == 'h') opt.size--;
if(c == 'l') opt.size++;
if(c == 'h') opt.size--;
if(c >= '1' && c <= '9') state = length, options--;
}
@ -337,7 +336,7 @@ static void kformat_geometry(int spec, struct kprint_options *opt,
Fills up the provided digit string from least significant to most
significant digit, not adding zeros except if argument is zero. Returns the
number of digits. No NUL terminator is added. */
static int digits_10(char *str, uint64_t n)
static int digits_10(char *str, uint n)
{
int digits = 0;
@ -351,7 +350,7 @@ static int digits_10(char *str, uint64_t n)
}
/* digits_16(): Generate digits in base 16 */
static int digits_16(char *str, int uppercase, uint64_t n)
static int digits_16(char *str, int uppercase, uint32_t n)
{
char *hex = uppercase ? "0123456789ABCDEF" : "0123456789abcdef";
int digits = 0;
@ -365,7 +364,7 @@ static int digits_16(char *str, int uppercase, uint64_t n)
}
/* digits_8(): Generate digits in base 8 */
static int digits_8(char *str, uint64_t n)
static int digits_8(char *str, uint32_t n)
{
int digits = 0;
@ -377,28 +376,6 @@ static int digits_8(char *str, uint64_t n)
return digits;
}
//---
// Loading helpers
//---
static int64_t load_i(int size, va_list *args)
{
/* All smaller types are promoeted to int so we can't read the
explicitly. They have been converted and sign-extended we don't need
to care what their size is, the result will remain the same */
if(size == 3) return va_arg(*args, long);
if(size == 4) return va_arg(*args, long long);
return va_arg(*args, int);
}
static uint64_t load_u(int size, va_list *args)
{
/* Again, no need to care about small types */
if(size == 3) return va_arg(*args, unsigned long);
if(size == 4) return va_arg(*args, unsigned long long);
return va_arg(*args, unsigned int);
}
//---
// Individual formatters
//---
@ -453,7 +430,7 @@ static void kformat_str(KFORMAT_ARGS)
{pre} Forces a minimal number of digits, creating 0s (overrides '0') */
static void kformat_int(KFORMAT_ARGS)
{
int64_t n = load_i(opt->size, args);
int n = va_arg(*args, int);
/* Compute the sign and the absolute value */
struct geometry g = {
@ -491,9 +468,9 @@ static void kformat_int(KFORMAT_ARGS)
{pre} Forces a minimal number of digits, creating 0s (overrides '0') */
static void kformat_uint(KFORMAT_ARGS)
{
uint64_t n = load_u(opt->size, args);
uint n = va_arg(*args, uint);
char digits[48];
char digits[32];
int pure = 0, total;
int specl = spec | 0x20;
@ -548,7 +525,7 @@ static void kformat_ptr(KFORMAT_ARGS)
{pre} Number of digits after the decimal dot */
static void kformat_fixed(KFORMAT_ARGS)
{
int64_t n = load_i(opt->size, args);
int n = va_arg(*args, int);
/* Compute the sign and the absolute value */
struct geometry g = {

View File

@ -6,30 +6,24 @@
#include <gint/defs/attributes.h>
#include <stdarg.h>
GWEAK size_t strlen(char const *str)
GWEAK size_t strlen(const char *str)
{
int len = 0;
while(str[len]) len++;
return len;
}
GWEAK char *strncpy(char *dst, char const *src, size_t n)
GWEAK char *strncpy(char *dst, const char *src, size_t n)
{
size_t i = 0;
while(i < n && (dst[i] = src[i])) i++;
return dst;
}
GWEAK char *strcat(char *dest, char const *src)
GWEAK char *strcat(char *dest, const char *src)
{
unsigned long fin_dest = strlen(dest);
unsigned int i;
for (i = 0 ; i <= strlen(src) ; i++) dest[fin_dest + i] = src[i];
return dest;
}
GWEAK int strcmp(char const *s1, char const *s2)
{
while(*s1 && *s1 == *s2) s1++, s2++;
return *s1 - *s2;
unsigned long fin_dest = strlen(dest);
unsigned int i;
for (i = 0 ; i <= strlen(src) ; i++) dest[fin_dest + i] = src[i];
return dest;
}