Refactored the C files out into libraries, started work on the BASIC repl (it can sorta do math!)
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
src/*o
|
||||||
153
src/basic.c
Normal file
153
src/basic.c
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
#include "basic.h"
|
||||||
|
#include "screen.h"
|
||||||
|
#include "conio.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
struct basic_math_expr math_expressions[8];
|
||||||
|
int basic_errno;
|
||||||
|
|
||||||
|
char _tokenizer_value[BASIC_TOKENIZER_MAX_LENGTH];
|
||||||
|
char *_tokenizer_prev;
|
||||||
|
char *_tokenizer_prev_next;
|
||||||
|
|
||||||
|
void _tokenizer_init(void)
|
||||||
|
{
|
||||||
|
_tokenizer_prev = NULL;
|
||||||
|
_tokenizer_prev_next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *_tokenize(char *ptr, char token)
|
||||||
|
{
|
||||||
|
char *orig = NULL;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if ( ptr == NULL ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ( _tokenizer_prev == ptr ) {
|
||||||
|
ptr = _tokenizer_prev_next;
|
||||||
|
}
|
||||||
|
orig = ptr;
|
||||||
|
|
||||||
|
memset(&_tokenizer_value, 0x00, BASIC_TOKENIZER_MAX_LENGTH);
|
||||||
|
while ( *ptr != token ) {
|
||||||
|
if ( *ptr == '\0' ) {
|
||||||
|
ptr -= sizeof(char);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr += sizeof(char);
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
if ( len > BASIC_TOKENIZER_MAX_LENGTH ) {
|
||||||
|
basic_errno = BASIC_ERR_SYNTAX_TOKEN_LENGTH;
|
||||||
|
return NULL;
|
||||||
|
} else if ( len == 0 ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy((void *)&_tokenizer_value, (void *)orig, len);
|
||||||
|
_tokenizer_prev_next = (ptr + 1);
|
||||||
|
return &_tokenizer_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct basic_math_expr *basic_parse_expr(char *expbuf)
|
||||||
|
{
|
||||||
|
struct basic_math_expr *ret = &math_expressions[0];
|
||||||
|
char flags = 0;
|
||||||
|
char *subptr = 0;
|
||||||
|
|
||||||
|
_tokenizer_init();
|
||||||
|
memset(ret, 0x0, sizeof(struct basic_math_expr));
|
||||||
|
|
||||||
|
while ( *expbuf != '\0' ) {
|
||||||
|
if ( *expbuf == ' ' ) {
|
||||||
|
expbuf += sizeof(char);
|
||||||
|
continue;
|
||||||
|
} else if ( isdigit(*expbuf) == 1 ) {
|
||||||
|
if ( (ret->type == 0) && (flags & BASIC_FOUND_LVAL) == BASIC_FOUND_LVAL ) {
|
||||||
|
basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_LVALUES;
|
||||||
|
return NULL;
|
||||||
|
} else if ( ret->type == 0x0 ) {
|
||||||
|
ret->lval = atoi(_tokenize(expbuf, ' '));
|
||||||
|
flags = (flags + BASIC_FOUND_LVAL);
|
||||||
|
} else if ( ret->type != 0x0 && ((flags & BASIC_FOUND_RVAL) == BASIC_FOUND_RVAL)) {
|
||||||
|
basic_errno = BASIC_ERR_SYNTAX_MULTIPLE_RVALUES;
|
||||||
|
return NULL;
|
||||||
|
} else if ( ret->type != 0x0 ) {
|
||||||
|
ret->rval = atoi(_tokenize(expbuf, ' '));
|
||||||
|
}
|
||||||
|
} else if ( ret->type == 0x0 ) {
|
||||||
|
if ( *expbuf == '+' ) {
|
||||||
|
ret->type = BASIC_MATH_ADD;
|
||||||
|
} else if ( *expbuf == '*' ) {
|
||||||
|
ret->type = BASIC_MATH_MUL;
|
||||||
|
} else if ( *expbuf == '-' ) {
|
||||||
|
ret->type = BASIC_MATH_SUB;
|
||||||
|
} else if ( *expbuf == '/' ) {
|
||||||
|
ret->type = BASIC_MATH_DIV;
|
||||||
|
} else if ( *expbuf == '%' ) {
|
||||||
|
ret->type = BASIC_MATH_MOD;
|
||||||
|
} else {
|
||||||
|
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
basic_errno = BASIC_ERR_SYNTAX_GENERAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
expbuf += sizeof(char);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void basic_run(void)
|
||||||
|
{
|
||||||
|
char keybuff[512];
|
||||||
|
char outbuff[128];
|
||||||
|
char decimal;
|
||||||
|
|
||||||
|
struct basic_math_expr *expr;
|
||||||
|
|
||||||
|
blankScreen();
|
||||||
|
setCursorPosition(0, 0);
|
||||||
|
_cputs("Piquant Basic v0.1\n\n");
|
||||||
|
|
||||||
|
while ( 1 ) {
|
||||||
|
_cputs("> ");
|
||||||
|
memset((void *)&keybuff, 0x00, 512);
|
||||||
|
memset((void *)&outbuff, 0x00, 128);
|
||||||
|
if ( _cgets((char *)&keybuff) != NULL ) {
|
||||||
|
_cputs("\n");
|
||||||
|
_cputs("Analyzing ");
|
||||||
|
_cputs((char *)&keybuff);
|
||||||
|
_cputs("\n");
|
||||||
|
|
||||||
|
expr = basic_parse_expr((char *)&keybuff);
|
||||||
|
if ( expr == NULL ) {
|
||||||
|
_cputs("Syntax Error: ");
|
||||||
|
decimal = dtoa(basic_errno);
|
||||||
|
_cputs(&decimal);
|
||||||
|
_cputs("\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
decimal = dtoa(expr->type);
|
||||||
|
memcpy(&outbuff, "Expression type: \0", strlen("Expression type: \0"));
|
||||||
|
strncat(&outbuff, &decimal, 1);
|
||||||
|
_cputs(&outbuff);
|
||||||
|
_cputs("\n");
|
||||||
|
|
||||||
|
decimal = dtoa(expr->lval);
|
||||||
|
memcpy(&outbuff, "Expression lval: \0", strlen("Expression lval: \0"));
|
||||||
|
strncat(&outbuff, &decimal, 1);
|
||||||
|
_cputs(&outbuff);
|
||||||
|
_cputs("\n");
|
||||||
|
|
||||||
|
decimal = dtoa(expr->rval);
|
||||||
|
memcpy(&outbuff, "Expression rval: \0", strlen("Expression rval: \0"));
|
||||||
|
strncat(&outbuff, &decimal, 1);
|
||||||
|
_cputs(&outbuff);
|
||||||
|
_cputs("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/basic.h
Normal file
39
src/basic.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _BASIC_H_
|
||||||
|
#define _BASIC_H_
|
||||||
|
|
||||||
|
#define BASIC_MATH_ADD 1
|
||||||
|
#define BASIC_MATH_SUB 2
|
||||||
|
#define BASIC_MATH_MUL 3
|
||||||
|
#define BASIC_MATH_DIV 4
|
||||||
|
#define BASIC_MATH_MOD 5
|
||||||
|
|
||||||
|
#define BASIC_LVAL_EXPR 0
|
||||||
|
#define BASIC_LVAL_VAR 1
|
||||||
|
#define BASIC_RVAL_EXPR 2
|
||||||
|
#define BASIC_RVAL_VAR 3
|
||||||
|
#define BASIC_RVAL_CONST 4
|
||||||
|
|
||||||
|
#define BASIC_FOUND_LVAL 0x0001
|
||||||
|
#define BASIC_FOUND_RVAL 0x0002
|
||||||
|
|
||||||
|
#define BASIC_ERR_SYNTAX_MULTIPLE_LVALUES 1
|
||||||
|
#define BASIC_ERR_SYNTAX_TOKEN_LENGTH 2
|
||||||
|
#define BASIC_ERR_SYNTAX_GENERAL 3
|
||||||
|
#define BASIC_ERR_SYNTAX_MULTIPLE_RVALUES 4
|
||||||
|
|
||||||
|
#define BASIC_TOKENIZER_MAX_LENGTH 512
|
||||||
|
|
||||||
|
struct basic_math_expr {
|
||||||
|
char type;
|
||||||
|
char lval_type;
|
||||||
|
char rval_type;
|
||||||
|
char pad;
|
||||||
|
void *lval;
|
||||||
|
void *rval;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int basic_errno;
|
||||||
|
|
||||||
|
void run_basic(void);
|
||||||
|
|
||||||
|
#endif /* _BASIC_H_ */
|
||||||
90
src/conio.c
Normal file
90
src/conio.c
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "conio.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
void _putch(char c)
|
||||||
|
{
|
||||||
|
#asm
|
||||||
|
push bx;
|
||||||
|
push ax;
|
||||||
|
mov bx, sp;
|
||||||
|
mov al, [bx+6];
|
||||||
|
mov ah, #0x0e;
|
||||||
|
mov bh, #0x00;
|
||||||
|
mov bl, #0x07;
|
||||||
|
int 0x10;
|
||||||
|
pop ax;
|
||||||
|
pop bx;
|
||||||
|
#endasm
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cputs(char *ptr)
|
||||||
|
{
|
||||||
|
if ( ptr == NULL ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while ((char)*ptr != 0x0) {
|
||||||
|
_putch((char)*ptr);
|
||||||
|
if (*ptr == '\n') {
|
||||||
|
_cursor_y += 1;
|
||||||
|
_cursor_x = 0;
|
||||||
|
setCursorPosition(_cursor_x, _cursor_y);
|
||||||
|
} else {
|
||||||
|
advanceCursor();
|
||||||
|
}
|
||||||
|
ptr += 1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char _getkey(char *dest)
|
||||||
|
{
|
||||||
|
char echo;
|
||||||
|
char scancode;
|
||||||
|
#asm
|
||||||
|
push ax;
|
||||||
|
mov ah, #0x10;
|
||||||
|
int 0x16;
|
||||||
|
mov [bp-6], ah;
|
||||||
|
mov [bp-5], al;
|
||||||
|
pop ax;
|
||||||
|
#endasm
|
||||||
|
*dest = echo;
|
||||||
|
return scancode;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *_cgets(char *d)
|
||||||
|
{
|
||||||
|
char *orig = d;
|
||||||
|
char scancode;
|
||||||
|
char printable;
|
||||||
|
|
||||||
|
if ( d == NULL ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
scancode = _getkey(&printable);
|
||||||
|
|
||||||
|
while ( scancode != NULL ) {
|
||||||
|
if ( scancode == 0x0e ) {
|
||||||
|
if ( d > orig ) {
|
||||||
|
backupCursor();
|
||||||
|
setCursorPosition(_cursor_x, _cursor_y);
|
||||||
|
d -= 1;
|
||||||
|
_putch(0x0);
|
||||||
|
}
|
||||||
|
} else if ( scancode == 0x1c ) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
*(d++) = printable;
|
||||||
|
_putch(printable);
|
||||||
|
advanceCursor();
|
||||||
|
}
|
||||||
|
scancode = _getkey(&printable);
|
||||||
|
}
|
||||||
|
|
||||||
|
__cgets_finish_loop:
|
||||||
|
*d = NULL;
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
8
src/conio.h
Normal file
8
src/conio.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _CONIO_H_
|
||||||
|
#define _CONIO_H_
|
||||||
|
|
||||||
|
void _putch(char _c);
|
||||||
|
char *_cgets(void);
|
||||||
|
char _getkey(char *dest);
|
||||||
|
|
||||||
|
#endif /* _CONIO_H_ */
|
||||||
238
src/kernel.c
238
src/kernel.c
@@ -1,238 +1,8 @@
|
|||||||
char _cursor_x = 0;
|
#include "screen.h"
|
||||||
char _cursor_y = 0;
|
#include "string.h"
|
||||||
|
#include "conio.h"
|
||||||
#define NULL 0x0
|
|
||||||
typedef int size_t;
|
|
||||||
|
|
||||||
void setCursorPosition(char x, char y)
|
|
||||||
{
|
|
||||||
#asm
|
|
||||||
push bx;
|
|
||||||
mov bx, sp;
|
|
||||||
mov dl, [bx+4];
|
|
||||||
mov dh, [bx+6];
|
|
||||||
pop bx;
|
|
||||||
push ax;
|
|
||||||
push bx;
|
|
||||||
mov ah, #0x02;
|
|
||||||
mov bx, #0x0;
|
|
||||||
int 0x10;
|
|
||||||
pop bx;
|
|
||||||
pop ax;
|
|
||||||
#endasm
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void backupCursor()
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( _cursor_x == 0 && _cursor_y > 0 ) {
|
|
||||||
_cursor_x = 80;
|
|
||||||
_cursor_y -= 1;
|
|
||||||
} else if ( _cursor_x > 0 ) {
|
|
||||||
_cursor_x -= 1;
|
|
||||||
}
|
|
||||||
setCursorPosition(_cursor_x, _cursor_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void advanceCursor()
|
|
||||||
{
|
|
||||||
_cursor_x += 1;
|
|
||||||
if ( _cursor_x > 79 ) {
|
|
||||||
_cursor_x = 0;
|
|
||||||
_cursor_y += 1;
|
|
||||||
}
|
|
||||||
setCursorPosition(_cursor_x, _cursor_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putc(char c)
|
|
||||||
{
|
|
||||||
#asm
|
|
||||||
push bx;
|
|
||||||
push ax;
|
|
||||||
mov bx, sp;
|
|
||||||
mov al, [bx+6];
|
|
||||||
mov ah, #0x0e;
|
|
||||||
mov bh, #0x00;
|
|
||||||
mov bl, #0x07;
|
|
||||||
int 0x10;
|
|
||||||
pop ax;
|
|
||||||
pop bx;
|
|
||||||
#endasm
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int strlen(char *ptr)
|
|
||||||
{
|
|
||||||
char *ptr2 = ptr;
|
|
||||||
if ( ptr == NULL ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*ptr2 != 0x0 ) {
|
|
||||||
ptr2 += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr2 - ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void puts(char *ptr, char x, char y)
|
|
||||||
{
|
|
||||||
if ( ptr == NULL ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while ((char)*ptr != 0x0) {
|
|
||||||
putc((char)*ptr);
|
|
||||||
if (*ptr == '\n') {
|
|
||||||
_cursor_y += 1;
|
|
||||||
_cursor_x = 0;
|
|
||||||
setCursorPosition(_cursor_x, _cursor_y);
|
|
||||||
} else {
|
|
||||||
advanceCursor();
|
|
||||||
}
|
|
||||||
ptr += 1;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char getkey(char *dest)
|
|
||||||
{
|
|
||||||
char echo;
|
|
||||||
char scancode;
|
|
||||||
#asm
|
|
||||||
push ax;
|
|
||||||
mov ah, 0x10;
|
|
||||||
int 0x16;
|
|
||||||
mov [bp-6], ah;
|
|
||||||
mov [bp-5], al;
|
|
||||||
pop ax;
|
|
||||||
#endasm
|
|
||||||
*dest = echo;
|
|
||||||
return scancode;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *gets(char *d)
|
|
||||||
{
|
|
||||||
char *orig = d;
|
|
||||||
char scancode;
|
|
||||||
char printable;
|
|
||||||
|
|
||||||
if ( d == NULL ) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
scancode = getkey(&printable);
|
|
||||||
|
|
||||||
while ( scancode != NULL ) {
|
|
||||||
if ( scancode == 0x0e ) {
|
|
||||||
if ( d > orig ) {
|
|
||||||
backupCursor();
|
|
||||||
setCursorPosition(_cursor_x, _cursor_y);
|
|
||||||
d -= 1;
|
|
||||||
putc(0x0);
|
|
||||||
}
|
|
||||||
} else if ( scancode == 0x1c ) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
*(d++) = printable;
|
|
||||||
putc(printable);
|
|
||||||
advanceCursor();
|
|
||||||
}
|
|
||||||
scancode = getkey(&printable);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gets_finish_loop:
|
|
||||||
*d = NULL;
|
|
||||||
return orig;
|
|
||||||
}
|
|
||||||
|
|
||||||
void memset(void *s, int c, size_t n)
|
|
||||||
{
|
|
||||||
int *d = (int *)s;
|
|
||||||
if ( s == NULL ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while ( ((int)d - (int)s) <= n ) {
|
|
||||||
*d = c;
|
|
||||||
d += sizeof(int);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
signed int strcmp(char *s1, char *s2)
|
|
||||||
{
|
|
||||||
int d = 0;
|
|
||||||
int s1len = 0;
|
|
||||||
|
|
||||||
if ( s1 == NULL || s2 == NULL ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
s1len = strlen(s1);
|
|
||||||
if ( s1len != strlen(s2) ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ( *s1 != '\0' ) {
|
|
||||||
if ( *s1 != *s2 ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
s1 += sizeof(char);
|
|
||||||
s2 += sizeof(char);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void repl(void)
|
|
||||||
{
|
|
||||||
char keybuff[512];
|
|
||||||
|
|
||||||
while ( 1 ) {
|
|
||||||
puts("> ");
|
|
||||||
memset((void *)&keybuff, 0x00, 512);
|
|
||||||
if ( gets((char *)&keybuff) != NULL ) {
|
|
||||||
puts("\n");
|
|
||||||
if ( strcmp(&keybuff, "quit") == 0 ) {
|
|
||||||
puts("You asked for it\n");
|
|
||||||
#asm
|
|
||||||
hlt;
|
|
||||||
#endasm
|
|
||||||
|
|
||||||
} else if ( strcmp(&keybuff, "reset") == 0 ) {
|
|
||||||
puts("Resetting PC ... ");
|
|
||||||
#asm
|
|
||||||
jmp 0xf000:0xfff0;
|
|
||||||
#endasm
|
|
||||||
|
|
||||||
} else if ( strcmp(&keybuff, "help") == 0 ) {
|
|
||||||
puts("help : Show this help message\n");
|
|
||||||
puts("quit : Halt the computer\n");
|
|
||||||
puts("reset : Reset the PC\n");
|
|
||||||
puts("\n");
|
|
||||||
} else {
|
|
||||||
puts("Wat?\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void blankScreen(void)
|
|
||||||
{
|
|
||||||
char i = 0;
|
|
||||||
char j = 0;
|
|
||||||
for ( i = 0 ; i < 26 ; i++ ) {
|
|
||||||
for ( j = 0; j < 81 ; j++ ) {
|
|
||||||
setCursorPosition(j, i);
|
|
||||||
putc(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
blankScreen();
|
basic_run();
|
||||||
setCursorPosition(0, 0);
|
|
||||||
puts("Piquant Kernel v0.1\n");
|
|
||||||
puts("\n");
|
|
||||||
repl();
|
|
||||||
}
|
}
|
||||||
|
|||||||
58
src/screen.c
Normal file
58
src/screen.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
char _cursor_x = 0;
|
||||||
|
char _cursor_y = 0;
|
||||||
|
|
||||||
|
void blankScreen(void)
|
||||||
|
{
|
||||||
|
char i = 0;
|
||||||
|
char j = 0;
|
||||||
|
for ( i = 0 ; i < 26 ; i++ ) {
|
||||||
|
for ( j = 0; j < 81 ; j++ ) {
|
||||||
|
setCursorPosition(j, i);
|
||||||
|
_putch(0x0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCursorPosition(char x, char y)
|
||||||
|
{
|
||||||
|
#asm
|
||||||
|
push bx;
|
||||||
|
mov bx, sp;
|
||||||
|
mov dl, [bx+4];
|
||||||
|
mov dh, [bx+6];
|
||||||
|
pop bx;
|
||||||
|
push ax;
|
||||||
|
push bx;
|
||||||
|
mov ah, #0x02;
|
||||||
|
mov bx, #0x0;
|
||||||
|
int 0x10;
|
||||||
|
pop bx;
|
||||||
|
pop ax;
|
||||||
|
#endasm
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void backupCursor()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( _cursor_x == 0 && _cursor_y > 0 ) {
|
||||||
|
_cursor_x = 80;
|
||||||
|
_cursor_y -= 1;
|
||||||
|
} else if ( _cursor_x > 0 ) {
|
||||||
|
_cursor_x -= 1;
|
||||||
|
}
|
||||||
|
setCursorPosition(_cursor_x, _cursor_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void advanceCursor()
|
||||||
|
{
|
||||||
|
_cursor_x += 1;
|
||||||
|
if ( _cursor_x > 79 ) {
|
||||||
|
_cursor_x = 0;
|
||||||
|
_cursor_y += 1;
|
||||||
|
}
|
||||||
|
setCursorPosition(_cursor_x, _cursor_y);
|
||||||
|
}
|
||||||
12
src/screen.h
Normal file
12
src/screen.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _SCREEN_H_
|
||||||
|
#define _SCREEN_H_
|
||||||
|
|
||||||
|
extern char _cursor_x;
|
||||||
|
extern char _cursor_y;
|
||||||
|
|
||||||
|
void setCursorPosition(char x, char y);
|
||||||
|
void backupCursor();
|
||||||
|
void advanceCursor();
|
||||||
|
void blankScreen();
|
||||||
|
|
||||||
|
#endif /* _SCREEN_H_ */
|
||||||
81
src/stdlib.c
Normal file
81
src/stdlib.c
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
char dtoa(int d)
|
||||||
|
{
|
||||||
|
switch (d) {
|
||||||
|
case 0: return '0'; break;
|
||||||
|
case 1: return '1'; break;
|
||||||
|
case 2: return '2'; break;
|
||||||
|
case 3: return '3'; break;
|
||||||
|
case 4: return '4'; break;
|
||||||
|
case 5: return '5'; break;
|
||||||
|
case 6: return '6'; break;
|
||||||
|
case 7: return '7'; break;
|
||||||
|
case 8: return '8'; break;
|
||||||
|
case 9: return '9'; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int atoi(char *nptr)
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
char *ptr = nptr;
|
||||||
|
int multiplier = 1;
|
||||||
|
|
||||||
|
if ( nptr == NULL ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while ( isdigit(*ptr) == 1 ) {
|
||||||
|
ptr += 1;
|
||||||
|
}
|
||||||
|
ptr -= 1;
|
||||||
|
while ( ptr >= nptr) {
|
||||||
|
value += (((int)(*ptr--) - 0x30) * multiplier);
|
||||||
|
multiplier *= 10;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isdigit(int c)
|
||||||
|
{
|
||||||
|
if (c >= 0x30 && c <= 0x39) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isupper(int c)
|
||||||
|
{
|
||||||
|
if (c >= 0x41 && c <= 0x5A) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int islower(int c)
|
||||||
|
{
|
||||||
|
if (c >= 0x61 && c <= 0x7A) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isalnum(int c)
|
||||||
|
{
|
||||||
|
if ( isupper(c) || islower(c) || isdigit(c) ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isxdigit(int c)
|
||||||
|
{
|
||||||
|
if ( isdigit(c) ||
|
||||||
|
(c >= 0x41 && c <= 0x46) ||
|
||||||
|
(c >= 0x61 && c <= 0x66)
|
||||||
|
) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
12
src/stdlib.h
Normal file
12
src/stdlib.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _STDLIB_H_
|
||||||
|
#define _STDLIB_H_
|
||||||
|
|
||||||
|
char dtoa(int d);
|
||||||
|
int atoi(char *nptr);
|
||||||
|
int isdigit(int c);
|
||||||
|
int isupper(int c);
|
||||||
|
int islower(int c);
|
||||||
|
int isalnum(int c);
|
||||||
|
int isxdigit(int c);
|
||||||
|
|
||||||
|
#endif /* _STDLIB_H_ */
|
||||||
83
src/string.c
Normal file
83
src/string.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
size_t strlen(char *ptr)
|
||||||
|
{
|
||||||
|
char *ptr2 = ptr;
|
||||||
|
if ( ptr == NULL ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*ptr2 != 0x0 ) {
|
||||||
|
ptr2 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr2 - ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memset(void *s, int c, size_t n)
|
||||||
|
{
|
||||||
|
int *d = (int *)s;
|
||||||
|
if ( s == NULL ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while ( ((int)d - (int)s) <= n ) {
|
||||||
|
*d = c;
|
||||||
|
d += sizeof(int);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memcpy(void *dest, void *src, size_t n)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
char *d = dest;
|
||||||
|
char *s = src;
|
||||||
|
|
||||||
|
if ( d == NULL || s == NULL ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for ( i = 0 ; i < n ; i++ ) {
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
*d = '\0';
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strncat(char *dest, char *src, size_t n)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
if ( dest == NULL || src == NULL ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dest = (dest + strlen(dest));
|
||||||
|
while ( c++ < n ) {
|
||||||
|
*dest++ = *src++;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strcmp(char *s1, char *s2)
|
||||||
|
{
|
||||||
|
int d = 0;
|
||||||
|
int s1len = 0;
|
||||||
|
|
||||||
|
if ( s1 == NULL || s2 == NULL ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s1len = strlen(s1);
|
||||||
|
if ( s1len != strlen(s2) ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( *s1 != '\0' ) {
|
||||||
|
if ( *s1 != *s2 ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
s1 += sizeof(char);
|
||||||
|
s2 += sizeof(char);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
12
src/string.h
Normal file
12
src/string.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _STRING_H_
|
||||||
|
#define _STRING_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
size_t strlen(char *ptr);
|
||||||
|
int strncat(char *dest, char *src, size_t n);
|
||||||
|
void *memset(void *s, int c, size_t n);
|
||||||
|
void *memcpy(void *dest, void *src, size_t n);
|
||||||
|
int strcmp(const char *s1, const char *s2);
|
||||||
|
|
||||||
|
#endif /* _STRING_H_ */
|
||||||
7
src/types.h
Normal file
7
src/types.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _TYPES_H_
|
||||||
|
#define _TYPES_H_
|
||||||
|
|
||||||
|
#define NULL 0x0
|
||||||
|
typedef int size_t;
|
||||||
|
|
||||||
|
#endif /* _TYPES_H_ */
|
||||||
Reference in New Issue
Block a user