MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
AFLAGS = $(MCUFLAGS)
-CFLAGS = $(MCUFLAGS) -ggdb \
+CFLAGS = $(MCUFLAGS) -O2 \
-Iinclude -Iinclude/cmsis \
-fno-builtin -fsigned-char -ffreestanding \
-Wall -Werror -Wextra -pedantic \
#include <stdint.h>
+#define C_WIDTH 12
+#define C_HEIGHT 16
+
/**
* Starts the task for a blinking text cursor.
*/
*/
void dsp_rect(int x, int y, int w, int h, uint16_t color);
-/**
- * Sets the text cursor's position, in characters NOT pixels.
- * @param x text column to move to
- * @param y text row to move to
- */
-void dsp_cpos(int x, int y);
-
-/*
- * Shifts the cursor the given amount of characters.
- */
-void dsp_spos(int x, int y);
-
-/**
- * Sets the pixel offset of the text cursor.
- * @param x x-pixel offset from (0, 0)
- * @param y y-pixel offset from (0, 0)
- */
-void dsp_coff(int x, int y);
-
-/**
- * Puts a string to the screen. Text position if kept track of internally, so
- * multiple calls will print the strings in one line.
- * @param s the string to print
- */
-void dsp_puts(const char *s);
+void dsp_putchar(int c, unsigned int xpos, unsigned int ypos);
#endif // DISPLAY_DRAW_H_
--- /dev/null
+#ifndef DISPLAY_TEXT_H_
+#define DISPLAY_TEXT_H_
+
+void text_init(void);
+void text_switch(unsigned int i);
+void text_puts(const char *s);
+
+void text_clear(void);
+
+void text_setpos(uint8_t x, uint8_t y);
+void text_relpos(int8_t x, int8_t y);
+
+#endif // DISPLAY_TEXT_H_
while (1) {
- rect(0, 0, 480, 300, 0)
- ppos(0, 0)
-
print("Free mem: ")
print(freemem())
print("\n")
choice = filemenu()
program(choice)
+ clear()
}
#include <task.h>
#include <clock.h>
-#define C_WIDTH 12
-#define C_HEIGHT 16
-#define S_WIDTH 40
-#define S_HEIGHT 18
-
volatile uint8_t lock = 0;
#define LOCK while (lock) { delay(5); } task_hold(1); lock = 1
#define UNLOCK task_hold(0); lock = 0
-static unsigned int curx = 0;
-static unsigned int cury = 0;
-static unsigned int curxo = 0;
-static unsigned int curyo = 0;
static unsigned char *font;
-void task_cursor(void)
-{
- while (1) {
- int x = curxo + curx * C_WIDTH;
- int y = curyo + cury * C_HEIGHT;
- dsp_rect(x, y + C_HEIGHT, C_WIDTH, 1, 0xFFFF);
- delay(300);
- dsp_rect(x, y + C_HEIGHT, C_WIDTH, 1, 0);
- delay(300);
- }
-}
-
void dsp_cursoron(void)
{
font = malloc(32 * 256);
flash_read((char *)font, 0, 32 * 256);
- task_start(task_cursor, 512);
}
-void dsp_putchar(int c)
+void dsp_putchar(int c, unsigned int xpos, unsigned int ypos)
{
LOCK;
- if (c == '\n') {
+ /*if (c == '\n') {
curx = 0;
if (++cury == S_HEIGHT) {
UNLOCK;
dsp_rect(curxo + curx * C_WIDTH, curyo + cury * C_HEIGHT,
C_WIDTH, C_HEIGHT, 0);
return;
- }
+ }*/
- unsigned int x = curxo + curx * C_WIDTH;
- unsigned int y = curyo + cury * C_HEIGHT;
+ unsigned int x = xpos * C_WIDTH;
+ unsigned int y = ypos * C_HEIGHT;
dsp_set_addr(x, y, x + C_WIDTH - 1, y + C_HEIGHT - 1);
uint32_t base = c * 32;
}
}
- if (++curx == S_WIDTH) {
+ /*if (++curx == S_WIDTH) {
curx = 0;
if (++cury == S_HEIGHT) {
UNLOCK;
LOCK;
cury = 0;
}
- }
+ }*/
UNLOCK;
}
-void dsp_puts(const char *s)
-{
- unsigned int i = 0;
- while (s[i])
- dsp_putchar(s[i++]);
-}
-
-void dsp_cpos(int x, int y)
-{
- curx = x;
- cury = y;
-}
-
-void dsp_spos(int x, int y)
-{
- if ((int)curx + x >= 0)
- curx += x;
- if ((int)cury + y >= 0)
- cury += y;
-}
-
-void dsp_coff(int x, int y)
-{
- curxo = x;
- curyo = y;
-}
+//
+// Drawing functions
+//
void dsp_rect(int x, int y, int w, int h, uint16_t color)
{
--- /dev/null
+
+#include <clock.h>
+#include <task.h>
+#include <display_draw.h>
+#include <heap.h>
+#include <string.h>
+
+#define WIDTH 40
+#define HEIGHT 18
+
+#define TTY_COUNT 2
+
+typedef struct {
+ char *buf;
+ uint8_t x;
+ uint8_t y;
+} tty_t;
+
+static tty_t text_tty[TTY_COUNT];
+static tty_t *text_current;
+static uint8_t text_cursor;
+
+void task_cursor(void)
+{
+ while (1) {
+ delay(300);
+ if (text_cursor == 0)
+ continue;
+
+ int x = text_current->x * C_WIDTH;
+ int y = text_current->y * C_HEIGHT;
+ dsp_rect(x, y + C_HEIGHT - 1, C_WIDTH, 1, 0xFFFF);
+ delay(300);
+ dsp_rect(x, y + C_HEIGHT - 1, C_WIDTH, 1, 0);
+ }
+}
+
+void text_init(void)
+{
+ for (int i = 0; i < TTY_COUNT; i++) {
+ text_tty[i].buf = calloc(WIDTH * HEIGHT, sizeof(char));
+ text_tty[i].x = 0;
+ text_tty[i].y = 0;
+ }
+
+ text_current = &text_tty[0];
+
+ text_cursor = 1;
+ task_start(task_cursor, 512);
+}
+
+void text_redraw(void)
+{
+ for (unsigned int i = 0; i < WIDTH; i++) {
+ //unsigned int zc = 0;
+ for (unsigned int j = 0; j < HEIGHT; j++) {
+ int c = text_current->buf[i + j * WIDTH];
+ /*if (c == '\0') {
+ if (++zc == 3)
+ break;
+ } else if (zc > 0) {
+ zc = 0;
+ }*/
+
+ dsp_putchar(c, i, j);
+ }
+ }
+}
+
+void text_switch(unsigned int i)
+{
+ if (i >= TTY_COUNT)
+ return;
+
+ text_current = &text_tty[i];
+ text_redraw();
+}
+
+void text_clear(void)
+{
+ for (unsigned int i = 0; i < WIDTH; i++) {
+ for (unsigned int j = 0; j < HEIGHT; j++) {
+ text_current->buf[i + j * WIDTH] = 0;
+ dsp_putchar(' ', i, j);
+ }
+ }
+ text_current->x = 0;
+ text_current->y = 0;
+}
+
+void text_putchar(int c)
+{
+ uint8_t x = text_current->x;
+ uint8_t y = text_current->y;
+
+ switch (c) {
+ case '\n':
+ y++;
+ // fall_through
+ case '\r':
+ x = 0;
+ break;
+ case '\t':
+ for (unsigned int i = 0; i < 4; i++)
+ dsp_putchar(' ', x++, y);
+ break;
+ case '\b':
+ x--;
+ dsp_putchar(' ', x, y);
+ break;
+ default:
+ dsp_putchar(c, x, y);
+ text_current->buf[x + y * WIDTH] = c;
+ x++;
+ break;
+ }
+
+ if (x >= WIDTH) {
+ x = 0;
+ y++;
+ }
+
+ if (y >= HEIGHT) {
+ // clear
+ for (int i = 1; i < HEIGHT; i++) {
+ memcpy(text_current->buf + (i - 1) * WIDTH,
+ text_current->buf + i * WIDTH, WIDTH);
+ }
+ x = 0;
+ y = HEIGHT - 1;
+ for (int i = 0; i < WIDTH; i++)
+ text_current->buf[i + y * WIDTH] = 0;
+
+ text_redraw();
+ }
+
+ text_current->x = x;
+ text_current->y = y;
+}
+
+void text_puts(const char *s)
+{
+ unsigned int i = 0;
+ while (s[i])
+ text_putchar(s[i++]);
+}
+
+void text_setpos(uint8_t x, uint8_t y)
+{
+ if (x >= WIDTH)
+ x = WIDTH - 1;
+ if (y >= HEIGHT)
+ y = HEIGHT - 1;
+ text_current->x = x;
+ text_current->y = y;
+}
+
+void text_relpos(int8_t x, int8_t y)
+{
+ if ((int)(text_current->x + x) < 0)
+ text_current->x = 0;
+ else
+ text_current->x += x;
+ if ((int)(text_current->y + y) < 0)
+ text_current->y = 0;
+ else
+ text_current->y += y;
+}
static uint32_t ClustersLBA;
static uint32_t FATStartLBA;
+static uint8_t *RootDir = 0;
+
int fat_find(void)
{
uint8_t *block = malloc(512);
file_t *fat_findfile(const char *name)
{
- uint8_t *block = malloc(512 * SectorsPerCluster);
- sd_read(block, fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ if (RootDir == 0) {
+ RootDir = sd_read(malloc(512 * SectorsPerCluster),
+ fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ }
+ uint8_t *block = RootDir;
for (unsigned int i = 0; block[i * 32] != 0; i++) {
if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F)
continue;
file_t *file = malloc(sizeof(file_t));
file->size = size;
file->start = start;
- free(block);
return file;
}
}
- free(block);
return 0;
}
char *fat_getname(uint32_t index)
{
- uint8_t *block = malloc(512 * SectorsPerCluster);
- sd_read(block, fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ if (RootDir == 0) {
+ RootDir = sd_read(malloc(512 * SectorsPerCluster),
+ fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ }
uint32_t idx = 0;
+ uint8_t *block = RootDir;
for (unsigned int i = 0; block[i * 32] != 0; i++) {
if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F)
continue;
if (idx == index) {
- char *name = strncpy(malloc(11), (char *)(block + i * 32), 11);
- free(block);
+ char *name = strncpy(malloc(12), (char *)(block + i * 32), 11);
+ name[11] = '\0';
return name;
}
idx++;
}
- free(block);
return 0;
}
#include <clock.h>\r
#include <display.h>\r
#include <display_draw.h>\r
+#include <display_text.h>\r
#include <fat32.h>\r
#include <flash.h>\r
#include <gpio.h>\r
void kmain(void)\r
{\r
dsp_init();\r
+ dsp_cursoron();\r
+ text_init();\r
+\r
sd_init();\r
fat_find();\r
- dsp_cursoron();\r
keypad_start();\r
\r
task_start(task_interpreter, 4096);\r
// load file\r
file_t *file = fat_findfile(name);\r
if (file == 0) {\r
- dsp_puts("can't find ");\r
- dsp_puts(name);\r
+ text_puts("can't find ");\r
+ text_puts(name);\r
goto fail;\r
}\r
\r
\r
void task_interpreter(void)\r
{\r
+ dsp_rect(0, 0, 480, 300, 0);\r
instance *it = load_program("init");\r
\r
// run the script\r
#include <ctype.h>
#include <display.h>
#include <display_draw.h>
+#include <display_text.h>
#include <heap.h>
#include <initrd.h>
#include <it/string.h>
int script_filemenu(instance *it);
int script_program(instance *it);
int script_free(instance *it);
+int script_clear(instance *it);
int math_sin(instance *it);
int math_cos(instance *it);
inew_cfunc(it, "line", script_line);
inew_cfunc(it, "rect", script_rect);
inew_cfunc(it, "color", script_color);
+ inew_cfunc(it, "clear", script_clear);
inew_cfunc(it, "rand", script_rand);
inew_cfunc(it, "delay", script_delay);
int nargs = igetarg_integer(it, 0);
float *resps = (float *)calloc(nargs, sizeof(float));
strncpy(listbuf, " : \0", 4);
+
+ text_switch(1);
+ text_clear();
+
for (int i = 0; i < nargs; i++) {
listbuf[0] = i + '0';
- dsp_puts(listbuf);
- dsp_puts((char *)igetarg(it, 1 + i * 2)->value.p);
- dsp_puts("\n");
+ text_puts(listbuf);
+ text_puts((char *)igetarg(it, 1 + i * 2)->value.p);
+ text_puts("\n");
resps[i] = igetarg(it, 2 + i * 2)->value.f;
}
variable *v = make_varf(0, isdigit(c) ? c - '0' : -1.0f);
ipush(it, (uint32_t)v);
+ text_switch(0);
free(resps);
return 0;
}
char listbuf[4];
char *fname;
strncpy(listbuf, " : \0", 4);
- dsp_puts("Choose a file: \n");
+ text_puts("Choose a file: \n");
for (unsigned int i = 0; (fname = /*initrd*/fat_getname(i)) != 0; i++) {
listbuf[0] = i + '0';
- dsp_puts(listbuf);
- dsp_puts(fname);
+ text_puts(listbuf);
+ text_puts(fname);
free(fname);
- dsp_puts("\n");
+ text_puts("\n");
}
int c;
char buf[33];
//snprintf(buf, 33, "%d", (int)v->value.f); // TODO
ftostr(buf, v->value.f);
- dsp_puts(buf);
+ text_puts(buf);
} else if (v->type == STRING) {
- dsp_puts((const char *)v->value.p);
+ text_puts((const char *)v->value.p);
}
return 0;
}
buf[0] = (int)v->value.f;
buf[1] = '\0';
- dsp_puts(buf);
+ text_puts(buf);
return 0;
}
break;
} else if (c[0] == K_LEFT) {
if (index > 0) {
- dsp_spos(-1, 0);
+ text_relpos(-1, 0);
index--;
}
continue;
} else if (c[0] == K_RIGHT) {
if (index < furthest) {
- dsp_spos(1, 0);
+ text_relpos(1, 0);
index++;
}
continue;
if (c[0] == '\b' || c[0] == 127) {
index--;
if (index > -1) {
- dsp_puts("\b");
+ text_puts("\b");
index--;
}
} else if (keypad_insert != 0) {
- dsp_spos(-index, 0);
+ text_relpos(-index, 0);
s[furthest + 1] = '\0';
- dsp_puts(s);
- dsp_spos(-(furthest - index), 0);
+ text_puts(s);
+ text_relpos(-(furthest - index), 0);
furthest++;
} else if (c[0] != '\n'/*'\r'*/) {
- dsp_puts(c);
+ text_puts(c);
}
if (++index > furthest)
int script_ppos(instance *it)
{
- dsp_coff(0, 0);
- dsp_cpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
+ text_setpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
return 0;
}
int script_rpos(instance *it)
{
- dsp_spos(igetarg_integer(it, 0), igetarg_integer(it, 1));
+ text_relpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
return 0;
}
int initrdOffset = (int)igetarg(it, 0)->value.f;
char *name = fat_getname(initrdOffset);
- dsp_rect(0, 0, 480, 300, 0);
- dsp_cpos(0, 0);
- dsp_coff(0, 0);
-
+ text_clear();
instance *it2 = load_program(name);
free(name);
ipush(it, (uint32_t)make_varf(0, 98303 - heap_used));
return 0;
}
+
+int script_clear(instance *it)
+{
+ (void)it;
+ text_clear();
+ return 0;
+}