added various (bad) example programs

master
Anton Lydike 3 years ago
parent 3b93b864ac
commit 314da51aaf

@ -0,0 +1,12 @@
CC = riscv32-unknown-elf-gcc
CFLAGS = -nostdlib -mcmodel=medany -Wall -Wextra -pedantic-errors -T ../linker.ld
simple:
$(CC) $(CFLAGS) -o simple simple.c
spawn:
$(CC) $(CFLAGS) -o spawn spawn.c
all: simple spawn

@ -0,0 +1,15 @@
# EMBARK example programs
Note that these programs are of poor quality.
* `simple.c` does some arithmetic in a loop, occasionally prints something rather random (the sequence goes `90,90,90,2386,2386,ae86,520c,1cbde,...`)
* `spawn.c` this thing spawn a new thread and exits when the thread overwrites a value.
## Compiling
The important thing when compiling user binaries are the following:
* `-mcmodel=medany` makes all address loads pc-relative. This allows for relocating binaries without much effort. This only works, if the addresses are larger than signed 12 bit number, so make sure you programs are located far enough into memory. (the default linker script takes care of that)
* `-T ../linker.ld` use the kernel linker script. This packs everything nice and close and sets the `__global_pointer$` etc up.
If you don't want to worry, use the makefile `make all`.

@ -0,0 +1,104 @@
#define TEXT_IO_ADDR 0xff0000
#define TEXT_IO_BUFLEN 64
void dbgln(char*, int);
char* itoa (int value, char* str, int base);
char text[48] = "the number is ";
int main() {
dbgln("main", 4);
int a = 144;
while (1) {
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
a ^= (((a<<16) ^ a) & i) << 4;
a ^= ((a & (j << 4)) >> 3) ^ (i*j);
}
itoa(a, &text[14], 16);
dbgln(text, 32);
}
__asm__("ebreak");
}
return a;
}
void dbgln(char* text, int len)
{
while (len > TEXT_IO_BUFLEN) {
dbgln(text, TEXT_IO_BUFLEN);
text += TEXT_IO_BUFLEN;
len -= TEXT_IO_BUFLEN;
}
char* ioaddr = (char*) TEXT_IO_ADDR + 4;
for (int i = 0; i < len; i++) {
if (*text == 0)
break;
*ioaddr++ = *text++;
}
if (len < TEXT_IO_BUFLEN)
*ioaddr = '\n';
// write a 1 to the start of the textIO to signal a buffer flush
*((char*) TEXT_IO_ADDR) = 1;
}
char alpha[16] = "0123456789abcdef";
char* itoa (int value, char* str, int base)
{
if (base > 16 || base < 2) {
*str++ = '?';
return str;
}
if (value < 0) {
*str++ = '-';
value *= -1;
}
int digits = 0;
int num = 0;
// reverse number
do {
num = num * base;
num += value % base;
value = value / base;
digits++;
} while (value > 0);
value = num;
do {
num = value % base;
value = value / base;
*str++ = alpha[num];
digits--;
}
while (digits > 0);
return str;
}
void _start() {
__asm__(
".option push\n"
".option norelax\n"
" la gp, _gp\n"
".option pop\n"
);
dbgln("start", 5);
int exit_code = main();
dbgln("end", 3);
__asm__(
"mv a0, %0\n"
"li a7, 5\n"
"ecall" :: "r"(exit_code)
);
}

@ -0,0 +1,115 @@
#define TEXT_IO_ADDR 0xff0000
#define TEXT_IO_BUFLEN 64
void dbgln(char*, int);
char* itoa (int value, char* str, int base);
int thread(void* args);
int main() {
dbgln("main", 4);
int arg = 144;
__asm__(
"mv a0, %0\n"
"mv a1, %1\n"
"li a7, 1\n"
"ecall" :: "r"(thread), "r"(&arg)
);
while (arg == 144) {}
__asm__("ebreak");
return 0;
}
int thread(void* args)
{
int arg = *((int*) args);
char buff[32] = "the magic number is: ";
char* end = itoa(arg, &buff[21], 10);
dbgln(buff, (int)(end - buff));
// *((int*) args) = 0;
return arg;
}
void dbgln(char* text, int len)
{
while (len > TEXT_IO_BUFLEN) {
dbgln(text, TEXT_IO_BUFLEN);
text += TEXT_IO_BUFLEN;
len -= TEXT_IO_BUFLEN;
}
char* ioaddr = (char*) TEXT_IO_ADDR + 4;
for (int i = 0; i < len; i++) {
if (*text == 0)
break;
*ioaddr++ = *text++;
}
if (len < TEXT_IO_BUFLEN)
*ioaddr = '\n';
// write a 1 to the start of the textIO to signal a buffer flush
*((char*) TEXT_IO_ADDR) = 1;
}
char alpha[16] = "0123456789abcdef";
char* itoa (int value, char* str, int base)
{
if (base > 16 || base < 2) {
*str++ = '?';
return str;
}
if (value < 0) {
*str++ = '-';
value *= -1;
}
int digits = 0;
int num = 0;
// reverse number
do {
num = num * base;
num += value % base;
value = value / base;
digits++;
} while (value > 0);
value = num;
do {
num = value % base;
value = value / base;
*str++ = alpha[num];
digits--;
}
while (digits > 0);
return str;
}
void _start() {
__asm__(
".option push\n"
".option norelax\n"
" la gp, _gp\n"
".option pop\n"
);
dbgln("start", 5);
int exit_code = main();
dbgln("end", 3);
__asm__(
"mv a0, %0\n"
"li a7, 5\n"
"ecall" :: "r"(exit_code)
);
}
Loading…
Cancel
Save