From b66e67e3a5f2680ee0e44228fce0fcaeff87206b Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Thu, 19 Dec 2019 04:48:56 +0100
Subject: eve textbox added; eve cmd result function added

---
 code/fe310/eos/Makefile   |   2 +-
 code/fe310/eos/eve.c      |  36 ++++++++++++-----
 code/fe310/eos/eve.h      |   6 ++-
 code/fe310/eos/eve_text.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 code/fe310/eos/eve_text.h |  20 ++++++++++
 5 files changed, 150 insertions(+), 14 deletions(-)
 create mode 100644 code/fe310/eos/eve_text.c
 create mode 100644 code/fe310/eos/eve_text.h

diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile
index 36eefd7..133a36a 100644
--- a/code/fe310/eos/Makefile
+++ b/code/fe310/eos/Makefile
@@ -2,7 +2,7 @@ include ../common.mk
 
 CFLAGS += -I../include -I../drivers
 
-obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o uart.o spi.o net.o wifi.o cell.o sock.o eve.o
+obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o uart.o spi.o net.o wifi.o cell.o sock.o eve.o eve_text.o
 
 
 %.o: %.c %.h
diff --git a/code/fe310/eos/eve.c b/code/fe310/eos/eve.c
index 8c0a477..9d902b2 100644
--- a/code/fe310/eos/eve.c
+++ b/code/fe310/eos/eve.c
@@ -96,8 +96,8 @@ static void _dl_inc(uint16_t i) {
 	dl_offset += i;
 }
 
-void eos_eve_dl_start(void) {
-    dl_offset = 0;
+void eos_eve_dl_start(uint16_t offset) {
+    dl_offset = offset;
 }
 
 void eos_eve_dl_write(uint32_t dl) {
@@ -106,10 +106,14 @@ void eos_eve_dl_write(uint32_t dl) {
     _dl_inc(4);
 }
 
-void eos_eve_dl_end(void) {
+void eos_eve_dl_swap(void) {
     eos_eve_write8(REG_DLSWAP, EVE_DLSWAP_FRAME);
 }
 
+uint16_t eos_eve_dl_offset(void) {
+    return dl_offset;
+}
+
 static void _cmd_inc(uint16_t i) {
 	cmd_offset += i;
 	cmd_offset &= 0x0fff;
@@ -145,8 +149,7 @@ static void _cmd_string(const char *s, uint8_t flags) {
 	p = 4 - p;  /* 4, 3, 2 or 1 */
 	i += p;
 
-	while(p > 0)
-	{
+	while(p > 0) {
         eos_spi_xchg8(0, EOS_SPI_FLAG_BSWAP | flags);
 		p--;
 	}
@@ -156,7 +159,8 @@ static void _cmd_string(const char *s, uint8_t flags) {
 void eos_eve_cmd(uint32_t cmd, const char *fmt, ...) {
     uint8_t flags = cmd_burst ? EOS_SPI_FLAG_TX : 0;
     va_list argv;
-    int i;
+    uint16_t *p;
+    int i = 0;
 
     va_start(argv, fmt);
     _cmd_begin(cmd);
@@ -174,6 +178,12 @@ void eos_eve_cmd(uint32_t cmd, const char *fmt, ...) {
                 eos_spi_xchg32(va_arg(argv, int), EOS_SPI_FLAG_BSWAP | flags);
                 _cmd_inc(4);
                 break;
+            case 'W':
+                p = va_arg(argv, uint16_t *);
+                *p = cmd_offset;
+                eos_spi_xchg32(0, EOS_SPI_FLAG_BSWAP | flags);
+                _cmd_inc(4);
+                break;
             case 's':
                 _cmd_string(va_arg(argv, const char *), flags);
                 break;
@@ -184,6 +194,10 @@ void eos_eve_cmd(uint32_t cmd, const char *fmt, ...) {
 	va_end(argv);
 }
 
+uint32_t eos_eve_cmd_result(uint16_t offset) {
+    return eos_eve_read32(EVE_RAM_CMD + offset);
+}
+
 void eos_eve_cmd_dl(uint32_t dl) {
     _cmd_begin(dl);
     _cmd_end();
@@ -271,11 +285,11 @@ int eos_eve_init(void) {
 	eos_eve_write16(REG_SOUND, 0x6000);     /* set synthesizer to mute */
 
 	/* write a basic display-list to get things started */
-    eos_eve_dl_start();
-    eos_eve_dl_write(DL_CLEAR_RGB);
-	eos_eve_dl_write(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG);
-    eos_eve_dl_write(DL_DISPLAY);
-    eos_eve_dl_end();
+    eos_eve_dl_start(0);
+    eos_eve_dl_write(CLEAR_COLOR_RGB(0,0,0));
+	eos_eve_dl_write(CLEAR(1,1,1));
+    eos_eve_dl_write(DISPLAY());
+    eos_eve_dl_swap();
 
 	/* nothing is being displayed yet... the pixel clock is still 0x00 */
 	eos_eve_write8(REG_GPIO, 0x80);         /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIO_DIR by default */
diff --git a/code/fe310/eos/eve.h b/code/fe310/eos/eve.h
index b3c7ec2..1c837f5 100644
--- a/code/fe310/eos/eve.h
+++ b/code/fe310/eos/eve.h
@@ -17,11 +17,13 @@ void eos_eve_sleep(void);
 void eos_eve_reset(void);
 void eos_eve_brightness(uint8_t b);
 
-void eos_eve_dl_start(void);
+void eos_eve_dl_start(uint16_t offset);
 void eos_eve_dl_write(uint32_t dl);
-void eos_eve_dl_end(void);
+void eos_eve_dl_swap(void);
+uint16_t eos_eve_dl_offset(void);
 
 void eos_eve_cmd(uint32_t cmd, const char *fmt, ...);
+uint32_t eos_eve_cmd_result(uint16_t offset);
 void eos_eve_cmd_dl(uint32_t dl);
 int eos_eve_cmd_done(void);
 int eos_eve_cmd_exec(int w);
diff --git a/code/fe310/eos/eve_text.c b/code/fe310/eos/eve_text.c
new file mode 100644
index 0000000..73fcb65
--- /dev/null
+++ b/code/fe310/eos/eve_text.c
@@ -0,0 +1,100 @@
+#include "eve.h"
+#include "eve_text.h"
+
+static int _line_diff(EVETextBox *box, int line) {
+    if (line > box->line_idx) {
+        return line - box->line_idx;
+    } else {
+        return box->buf_line_h - box->line_idx + line;
+    }
+}
+
+static void _line_scroll(EVETextBox *box) {
+    box->line_idx = (box->line_idx + 1) % box->buf_line_h;
+    eos_eve_cmd(CMD_MEMSET, "www", EVE_RAM_G + box->buf_addr + box->buf_idx, 0x0, box->w * 2);
+    eos_eve_cmd_exec(1);
+    eos_eve_dl_start(box->dl_offset);
+    eos_eve_text_update(box);
+    eos_eve_dl_swap();
+}
+
+void eos_eve_text_init(EVETextBox *box, uint16_t buf_addr, int buf_line_h, int w, int h, int x, int y, uint8_t bitmap_handle) {
+    box->buf_addr = buf_addr;
+    box->buf_line_h = buf_line_h;
+    box->w = w;
+    box->h = h;
+    box->x = x;
+    box->y = y;
+    box->buf_idx = 0;
+    box->line_idx = 0;
+    box->dl_offset = 0;
+    box->bitmap_handle = bitmap_handle;
+
+    eos_eve_cmd(CMD_MEMSET, "www", EVE_RAM_G + buf_addr, 0x0, w * 2 * buf_line_h);
+    eos_eve_cmd_exec(1);
+}
+
+void eos_eve_text_update(EVETextBox *box) {
+    int text_h1;
+    int text_h2;
+
+    eos_eve_dl_write(BITMAP_HANDLE(box->bitmap_handle));
+    eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr + box->line_idx * box->w * 2));
+    if (box->line_idx + box->h > box->buf_line_h) {
+        text_h1 = box->buf_line_h - box->line_idx;
+        text_h2 = box->h - text_h1;
+    } else {
+        text_h1 = box->h;
+        text_h2 = 0;
+    }
+    eos_eve_dl_write(BITMAP_LAYOUT(EVE_TEXTVGA, box->w * 2, text_h1));
+    eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * 8, text_h1 * 16));
+
+    if (text_h2) {
+        eos_eve_dl_write(BITMAP_HANDLE(box->bitmap_handle+1));
+        eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr));
+        eos_eve_dl_write(BITMAP_LAYOUT(EVE_TEXTVGA, box->w * 2, text_h2));
+        eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * 8, text_h2 * 16));
+    } else {
+        eos_eve_dl_write(NOP());
+        eos_eve_dl_write(NOP());
+        eos_eve_dl_write(NOP());
+        eos_eve_dl_write(NOP());
+    }
+
+    eos_eve_dl_write(BEGIN(EVE_BITMAPS));
+    eos_eve_dl_write(VERTEX2II(box->x, box->y, 0, 0));
+    if (text_h2) {
+        eos_eve_dl_write(VERTEX2II(box->x, box->y + text_h1 * 16, 1, 0));
+    } else {
+        eos_eve_dl_write(NOP());
+    }
+    eos_eve_dl_write(END());
+}
+
+void eos_eve_text_draw(EVETextBox *box) {
+    box->dl_offset = eos_eve_dl_offset();
+    eos_eve_text_update(box);
+}
+
+void eos_eve_text_putc(EVETextBox *box, int c) {
+    int line_c, line_n;
+
+    line_c = box->buf_idx / 2 / box->w;
+
+    eos_eve_write16(EVE_RAM_G + box->buf_addr + box->buf_idx, 0x0A00 | (c & 0xff));
+    box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2);
+
+    line_n = box->buf_idx / 2 / box->w;
+    if ((line_c != line_n) && (_line_diff(box, line_n) == box->h)) {
+        _line_scroll(box);
+    }
+}
+
+void eos_eve_text_newline(EVETextBox *box) {
+    int line = (box->buf_idx / 2 / box->w + 1) % box->buf_line_h;
+    box->buf_idx = line * box->w * 2;
+    if (_line_diff(box, line) == box->h) {
+        _line_scroll(box);
+    }
+}
\ No newline at end of file
diff --git a/code/fe310/eos/eve_text.h b/code/fe310/eos/eve_text.h
new file mode 100644
index 0000000..e882195
--- /dev/null
+++ b/code/fe310/eos/eve_text.h
@@ -0,0 +1,20 @@
+#include <stdint.h>
+
+typedef struct EVETextBox {
+    uint16_t buf_addr;
+    int buf_line_h;
+    int w;
+    int h;
+    int x;
+    int y;
+    int buf_idx;
+    int line_idx;
+    uint16_t dl_offset;
+    uint8_t bitmap_handle;
+} EVETextBox;
+
+void eos_eve_text_init(EVETextBox *box, uint16_t buf_addr, int buf_line_h, int w, int h, int x, int y, uint8_t bitmap_handle);
+void eos_eve_text_update(EVETextBox *box);
+void eos_eve_text_draw(EVETextBox *box);
+void eos_eve_text_putc(EVETextBox *box, int c);
+void eos_eve_text_newline(EVETextBox *box);
\ No newline at end of file
-- 
cgit v1.2.3