Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 178 additions & 78 deletions libb/6502-posix.b
Original file line number Diff line number Diff line change
@@ -1,13 +1,53 @@
exit(code) {
0(code);
(*0xFFFC)(code);
}

abort() {
exit(69);
}
assert(cond, msg) {
if (cond == 0) {
printf("Assertion failed: %s\n", msg);
abort();
}
}

/* not correct at all */
usleep(n) {
auto i, j;
if (n < 0) n = 32767;
i = 0; while (i < n>>2) {
__asm__("nop");
i++;
}
}

/* IO functions */
putchar(c) {
0xFFEF(c);
extrn lchar;
lchar(0xD012, 0, c);
}

getchar() {
extrn char;
return (char(0xD010, 0));
}

read(fd, buf, n) {
extrn lchar;
auto i, c;

assert(fd == 0, "only fd==0 supported for read");
i = 0; while (i < n) {
c = getchar();
lchar(buf, i, c);
if (c == '\n') {
return (n); /* simulate terminal behaviour */
}
if (c == 0xFF) return (i);
i++;
}

return (n);
}

char __asm__(
Expand Down Expand Up @@ -43,76 +83,7 @@ lchar __asm__(
fputc(c, fd) {
putchar(c);
}

/* TODO: actually allocate something */
__heap_ptr 0x0200;
malloc(size) {
extrn printf;
auto ptr;
ptr = __heap_ptr;
__heap_ptr += size;
if (__heap_ptr >= 0x1000) {
printf("Allocation reached end: %p\nTODO: allow allocating more, implement free\n", __heap_ptr);
abort();
}
return (ptr);
}
/* TODO: free someting? */
realloc(ptr, size) {
return (malloc(size));
}

/* TODO: Try to implement this function with assembly
Problem with this implementation is that it is not
mapped to the operator
We cannot call this function `div` as it conflicts
with the `divmod` test
*/
_div(a, b) {
auto d, sign;
sign = 0;
if (a < 0) {
sign = !sign;
a = -a;
}
if (b < 0) {
sign = !sign;
b = -a;
}

d = 0; while(a >= b) {
a = a - b;
d++;
}
if (sign) d = -d;
return (d);
}
_udiv(a, b) {
auto d;
d = 0; while(a >= b | a < 0) {
a = a - b;
d++;
}
return (d);
}

/* TODO: Try to implement this function with assembly
Problem with this implementation is that it is not
mapped to the operator */
_rem (a, b) {
auto d;
while(a >= b) {
a = a - b;
}
return (a);
}
_urem(a, b) {
auto d;
while(a >= b | a < 0) {
a = a - b;
}
return (a);
}
fflush(); /* nop */

printn(n, b, sign) {
auto a, c, d, __div, __rem;
Expand All @@ -133,7 +104,17 @@ printn(n, b, sign) {
putchar(c);
}

stdin 0;
stdout 1;
stderr 1;

fprintf(fd, str, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) {
assert((fd == 1) | (fd == 2), "only fd in [1,2] supported for fprintf");
return (printf(str, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15));
}

printf(str, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) {
extrn char;
auto i, j, arg, c;
i = 0;
j = 0;
Expand All @@ -143,7 +124,7 @@ printf(str, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) {
c = char(str, i);
while (c != 0) {
if (c == '\n') {
putchar(0xD); // \r
putchar(0xD); /* \r */
}

if(c == '%') {
Expand All @@ -164,9 +145,9 @@ printf(str, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) {
while (c = char(*arg, j++)) {
putchar(c);
}
} else if (c == 'z' | c == 'l') { /* hack for %zu %lu, % */
} else if ((c == 'z') | (c == 'l')) { /* hack for %zu %lu, % */
c = '%';
goto while_end;
goto continue;
} else {
putchar('%');
arg += 2; /* word size */
Expand All @@ -177,10 +158,91 @@ printf(str, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) {
}
i++;
c = char(str, i);
while_end:;
continue:;
}
}

/* Math functions */
_rand_seed 123456789;
rand() {
_rand_seed = 20077 * _rand_seed + 12345;
return (_rand_seed);
}

atoi(str) {
extrn char;

auto i, c, n, neg;
neg = 0;
n = 0;

if (char(str, 0) == '-') {
neg = 1;
str++;
}

i = 0; while (1) {
c = char(str, i);
if ((c == 0) | (c < '0') | (c > '9')) goto end;
n = n * 10 + (c - '0');
i++;
}

end:;
if (neg) n = -n;

return (n);
}

/* TODO: Try to implement this function with assembly
Problem with this implementation is that it is not
mapped to the operator
We cannot call this function `div` as it conflicts
with the `divmod` test
*/
_div(a, b) {
auto d, sign;
sign = 0;
if (a < 0) {
sign = !sign;
a = -a;
}
if (b < 0) {
sign = !sign;
b = -a;
}

d = 0; while(a >= b) {
a = a - b;
d++;
}
if (sign) d = -d;
return (d);
}
_udiv(a, b) {
auto d;
d = 0; while(a >= b | a < 0) {
a = a - b;
d++;
}
return (d);
}

/* TODO: Try to implement this function with assembly
Problem with this implementation is that it is not
mapped to the operator */
_rem (a, b) {
return (a - a / b * b);
}
_urem(a, b) {
auto d;
while(a >= b | a < 0) {
a = a - b;
}
return (a);
}

/* memory related functions */
strlen(s) {
auto n;
n = 0;
Expand All @@ -194,7 +256,6 @@ toupper(c) {
}


/* memory related functions */
memset(addr, val, size) {
extrn lchar;
auto i;
Expand All @@ -204,3 +265,42 @@ memset(addr, val, size) {
i += 1;
}
}

memcpy(dest, src, n) {
extrn char, lchar;
auto i, rn;
rn = n;
if (n & 1) n--;

i = 0; while (i < n) {
dest[i] = src[i];
i++;
}

if (rn & 1) lchar(dest, n-1, char(src, n-1));
return (dest);
}

/* TODO: actually allocate something */
__heap_ptr 0x0E000;
malloc(size) {
extrn printf;
auto ptr;
ptr = __heap_ptr;
__heap_ptr += size;
if (__heap_ptr >= 0xFF00) {
printf("Allocation reached end: %p\nTODO: allow allocating more, implement free\n", __heap_ptr);
abort();
}
return (ptr);
}
free() {
/* TODO: free someting */
}
realloc(ptr, size) {
auto nptr;
nptr = malloc(size);
memcpy(nptr, ptr, size);
free(ptr);
return (nptr);
}
Loading
Loading