aboutsummaryrefslogtreecommitdiffstats
path: root/com32/lib/sys/ansicon_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/lib/sys/ansicon_write.c')
-rw-r--r--com32/lib/sys/ansicon_write.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/com32/lib/sys/ansicon_write.c b/com32/lib/sys/ansicon_write.c
index dbcf7412..2b7cff00 100644
--- a/com32/lib/sys/ansicon_write.c
+++ b/com32/lib/sys/ansicon_write.c
@@ -40,14 +40,6 @@
#include <klibc/compiler.h>
#include "file.h"
-static void __constructor ansicon_init(void)
-{
- static com32sys_t ireg; /* Auto-initalized to all zero */
-
- ireg.eax.w[0] = 0x0005; /* Force text mode */
- __intcall(0x22, &ireg, NULL);
-}
-
struct curxy {
uint8_t x, y;
} __attribute__((packed));
@@ -74,7 +66,9 @@ static struct {
int bg;
int autocr;
struct curxy saved_xy;
+ uint16_t cursor_type;
enum ansi_state state;
+ int pvt; /* Private code? */
int nparms; /* Number of parameters seen */
int parms[MAX_PARMS];
} st = {
@@ -87,10 +81,28 @@ static struct {
.bg = 0,
.autocr = 0,
.saved_xy = { 0, 0 },
+ .cursor_type = 0x0607,
.state = st_init,
+ .pvt = 0,
.nparms = 0,
};
+/* Common setup */
+static void __constructor ansicon_init(void)
+{
+ static com32sys_t ireg; /* Auto-initalized to all zero */
+
+ /* Force text mode */
+ ireg.eax.w[0] = 0x0005;
+ __intcall(0x22, &ireg, NULL);
+
+ /* Get cursor shape */
+ ireg.eax.b[1] = 0x03;
+ ireg.ebx.b[1] = BIOS_PAGE;
+ __intcall(0x10, &ireg, &ireg);
+ st.cursor_type = ireg.ecx.w[0];
+}
+
/* Erase a region of the screen */
static void ansicon_erase(int x0, int y0, int x1, int y1)
{
@@ -105,6 +117,16 @@ static void ansicon_erase(int x0, int y0, int x1, int y1)
__intcall(0x10, &ireg, NULL);
}
+/* Show or hide the cursor */
+static void showcursor(int yes)
+{
+ static com32sys_t ireg;
+
+ ireg.eax.b[1] = 0x01;
+ ireg.ecx.w[0] = yes ? st.cursor_type : 0x2020;
+ __intcall(0x10, &ireg, NULL);
+}
+
static void ansicon_putchar(int ch)
{
static com32sys_t ireg;
@@ -168,7 +190,7 @@ static void ansicon_putchar(int ch)
break;
case '[':
st.state = st_csi;
- st.nparms = 0;
+ st.nparms = st.pvt = 0;
memset(st.parms, 0, sizeof st.parms);
break;
default:
@@ -189,6 +211,8 @@ static void ansicon_putchar(int ch)
if ( st.nparms >= MAX_PARMS )
st.nparms = MAX_PARMS-1;
break;
+ } else if ( ch == '?' ) {
+ st.pvt = 1;
} else {
switch ( ch ) {
case 'A':
@@ -229,6 +253,13 @@ static void ansicon_putchar(int ch)
xy.x = 0;
}
break;
+ case 'G':
+ case '\'':
+ {
+ int x = st.parms[0] - 1;
+ xy.x = (x >= cols) ? cols-1 : (x < 0) ? 0 : x;
+ }
+ break;
case 'H':
case 'f':
{
@@ -295,6 +326,9 @@ static void ansicon_putchar(int ch)
case 20:
st.autocr = set;
break;
+ case 25:
+ showcursor(set);
+ break;
default:
/* Ignore */
break;