summaryrefslogtreecommitdiff
path: root/userspace
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-10-05 14:36:42 +0200
committerMiguel <m.i@gmx.at>2018-10-05 14:36:42 +0200
commit4dbe6a264d7a3bd38ca1ac0921248654a50f1b5e (patch)
tree5ab6b10a281eec07d46dc678805a9a4eb59e6341 /userspace
parent7e56d9ac1e6888faed2109e2eefe124650aa4a72 (diff)
user space xterm continued
Diffstat (limited to 'userspace')
-rw-r--r--userspace/Makefile5
-rw-r--r--userspace/init.c1
-rw-r--r--userspace/xterm/Makefile13
-rw-r--r--userspace/xterm/crt0.s39
-rw-r--r--userspace/xterm/terminal.c572
-rw-r--r--userspace/xterm/vesa.c (renamed from userspace/vesa.c)4
-rw-r--r--userspace/xterm/xterm.c2
7 files changed, 632 insertions, 4 deletions
diff --git a/userspace/Makefile b/userspace/Makefile
index 3b7a6b9..b1b077d 100644
--- a/userspace/Makefile
+++ b/userspace/Makefile
@@ -7,6 +7,7 @@ GIT_REVISION=$(shell git rev-parse HEAD)
CC=i686-foolos-gcc
CC=i686-elf-gcc
AS=i686-elf-as
+
CC = @echo "Compiling (i686-elf-gcc) $<..."; i686-elf-gcc
AS = @echo "Assembling (i686-elf-as) $<..."; i686-elf-as
@@ -29,9 +30,9 @@ include ../Makefile.common
all: crt0.o ext2.img
-
ext2.img: $(PROGS)
make -C fonts
+ make -C xterm
@echo "----------------------"
@echo "Creating ext2.img ...."
@dd if=/dev/zero of=ext2.img bs=1024 count=$(IMAGESIZE)
@@ -48,6 +49,7 @@ ext2.img: $(PROGS)
@mkdir -p mnt/pipes # mountpoint for pipes
@cp $(PROGS) mnt/bin
@cp fonts/binfont.bin mnt/doc/fonts
+ @cp xterm/xterm mnt/bin
# cp ~/temp/fool-os-stuff/binutils-build-host-foolos/binutils/readelf mnt/bin
# cp ../font/binfont.bin mnt/
@@ -69,6 +71,7 @@ ext2.img: $(PROGS)
clean:
make -C fonts clean
+ make -C xterm clean
@echo "Cleaning userspace ..."; rm -f *.o $(PROGS) ext2.img *.d
new: clean all
diff --git a/userspace/init.c b/userspace/init.c
index 0e0fd66..d07942b 100644
--- a/userspace/init.c
+++ b/userspace/init.c
@@ -6,6 +6,7 @@ int main(int argc, char **argv)
{
// loop forever and spawn shells if the top-shell exits
+ _execve("/bin/xterm",NULL,NULL);
_execve("/bin/vesa",NULL,NULL);
diff --git a/userspace/xterm/Makefile b/userspace/xterm/Makefile
new file mode 100644
index 0000000..3056094
--- /dev/null
+++ b/userspace/xterm/Makefile
@@ -0,0 +1,13 @@
+CC=i686-foolos-gcc
+AS=i686-foolos-as
+
+CFLAGS=-I/home/miguel/temp/foolos/usr/i686-foolos/include
+
+LDFLAGS=-L/home/miguel/temp/foolos/usr/i686-foolos/lib/
+
+all: crt0.o xterm
+
+xterm: vesa.o terminal.o
+
+clean:
+ rm -f *.o xterm
diff --git a/userspace/xterm/crt0.s b/userspace/xterm/crt0.s
new file mode 100644
index 0000000..dedc86c
--- /dev/null
+++ b/userspace/xterm/crt0.s
@@ -0,0 +1,39 @@
+.global _start
+
+_start:
+
+# copy reent to this page
+push %ebx
+push %ecx
+
+mov _impure_ptr,%eax
+mov $0xf5000000,%ebx
+copy:
+mov (%eax),%ecx
+mov %ecx,(%ebx)
+add $4, %ebx
+add $4, %eax
+cmp $0xf5001000,%ebx
+jne copy
+
+pop %ecx
+pop %ebx
+
+movl $0xf5000000, _impure_ptr
+
+# environment adress was passed on stack
+
+pop %eax
+mov %eax, environ
+
+# call main (argc and argv are on the stack)
+call main
+
+# push exit code and pass to _exit syscall
+push %eax
+call exit
+
+# this should never be reached!
+.wait:
+ hlt
+jmp .wait
diff --git a/userspace/xterm/terminal.c b/userspace/xterm/terminal.c
new file mode 100644
index 0000000..4f321dd
--- /dev/null
+++ b/userspace/xterm/terminal.c
@@ -0,0 +1,572 @@
+// http://en.wikipedia.org/wiki/VT52
+// http://vt100.net/docs/vt520-rm/
+// man 4 console_codes
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#define NPAR_START 1000
+#define TERM_WIDTH 80
+#define TERM_HEIGHT 24
+
+// COLORS
+#define SCR_BLACK 0x0
+#define SCR_BLUE 0x1
+#define SCR_GREEN 0x2
+#define SCR_CYAN 0x3
+#define SCR_RED 0x4
+#define SCR_MAGENTA 0x5
+#define SCR_BROWN 0x6
+#define SCR_GRAY_LIGHT 0x7
+#define SCR_GRAY_DARK 0x8
+#define SCR_BLUE_LIGHT 0x9
+#define SCR_GREEN_LIGHT 0xa
+#define SCR_CYAN_LIGHT 0xb
+#define SCR_RED_LIGHT 0xc
+#define SCR_MAGENTA_LIGHT 0xd
+#define SCR_YELLOW 0xe
+#define SCR_WHITE 0xf
+//
+
+typedef enum{
+
+ ecma48_reset,
+ ecma48_bold,
+ ecma48_halfbright,
+ ecma48_underscore,
+ ecma48_blink,
+ ecma48_reverse_video,
+ ecma48_reset_mapping,
+ ecma48_null_mapping_1,
+ ecma48_null_mapping_2,
+ ecma48_normalbright_1,
+ ecma48_normalbright_2,
+ ecma48_nounderline,
+ ecma48_blinkoff,
+ ecma48_reverse_video_off,
+
+ ecma48_fg_black =30,
+ ecma48_fg_red,
+ ecma48_fg_green,
+ ecma48_fg_brown,
+ ecma48_fg_blue,
+ ecma48_fg_magenta,
+ ecma48_fg_cyan,
+ ecma48_fg_white,
+ ecma48_underscore_on, // set def color
+ ecma48_underscore_off, // set def color
+
+ ecma48_bg_black, //40
+ ecma48_bg_red,
+ ecma48_bg_green,
+ ecma48_bg_brown,
+ ecma48_bg_blue,
+ ecma48_bg_magenta,
+ ecma48_bg_cyan,
+ ecma48_bg_white,
+
+ ecma48_bg_default =49,
+
+}terminal_settings;
+
+typedef struct term_out_struct
+{
+ void (*put_char)(uint8_t c,uint8_t color_fg, uint8_t color_bg, uint32_t x, uint32_t y);
+ void (*update_cursor)(uint32_t col,uint32_t row);
+}term_out;
+
+typedef struct term_in_struct
+{
+ void (*put_char)(uint8_t c);
+}term_in;
+
+typedef struct terminal_tty_struct
+{
+ uint8_t fg;
+ uint8_t bg;
+
+ bool set_buff;
+ bool set_lfnl;
+ bool set_echo;
+
+ uint32_t width;
+ uint32_t height;
+ uint32_t x;
+ uint32_t y;
+ uint32_t *data; // screen data
+ uint8_t *command; // command line / also holds npar for escape sequences somewhere
+ int32_t command_l; // command line length
+
+ uint8_t escaping; // escaping mode?
+ uint8_t npar; // npar pos
+
+ term_out *screen;
+ term_in *input;
+
+ bool reverse_video;
+
+}terminal_tty;
+
+static uint32_t index(terminal_tty *tty, uint32_t x, uint32_t y)
+{
+ return tty->width*y+x;
+}
+
+static void set_char(terminal_tty *tty, uint32_t x, uint32_t y, uint8_t c, uint8_t fg, uint8_t bg)
+{
+ tty->data[index(tty,x,y)]=c;
+ tty->data[index(tty,x,y)]|=fg<<8;
+ tty->data[index(tty,x,y)]|=bg<<16;
+ tty->screen->put_char(c,fg,bg,x,y);
+}
+
+static void process_graphic_npar(terminal_tty *tty, terminal_settings s)
+{
+ uint8_t buf;
+
+ switch(s)
+ {
+ case ecma48_null_mapping_2:
+ break;
+ case ecma48_null_mapping_1:
+ break;
+ case ecma48_reset_mapping:
+ break;
+ case ecma48_blinkoff:
+ break;
+ case ecma48_blink:
+ break;
+ case ecma48_nounderline:
+ break;
+ case ecma48_underscore_on:
+ break;
+ case ecma48_underscore_off:
+ break;
+ case ecma48_underscore:
+ break;
+ case ecma48_halfbright:
+ break;
+ case ecma48_normalbright_1:
+ break;
+ case ecma48_normalbright_2:
+ break;
+ case ecma48_bold:
+ break;
+ case ecma48_reset:
+ tty->fg=SCR_WHITE;
+ tty->bg=SCR_BLACK;
+ break;
+
+ case ecma48_reverse_video:
+
+ if(tty->reverse_video)break;
+ buf=tty->fg;
+ tty->fg=tty->bg;
+ tty->bg=buf;
+ break;
+
+ case ecma48_reverse_video_off:
+
+ if(!tty->reverse_video)break;
+ buf=tty->fg;
+ tty->fg=tty->bg;
+ tty->bg=buf;
+ break;
+
+ //fg
+
+ case ecma48_fg_black:
+ tty->fg=SCR_BLACK;
+ break;
+
+ case ecma48_fg_red:
+ tty->fg=SCR_RED;
+ break;
+
+ case ecma48_fg_green:
+ tty->fg=SCR_GREEN;
+ break;
+
+ case ecma48_fg_brown:
+ tty->fg=SCR_BROWN;
+ break;
+
+ case ecma48_fg_blue:
+ tty->fg=SCR_BLUE;
+ break;
+
+ case ecma48_fg_magenta:
+ tty->fg=SCR_MAGENTA;
+ break;
+
+ case ecma48_fg_cyan:
+ tty->fg=SCR_CYAN;
+ break;
+
+ case ecma48_fg_white:
+ tty->fg=SCR_WHITE;
+ break;
+ // bg
+
+ case ecma48_bg_black:
+ tty->bg=SCR_BLACK;
+ break;
+
+ case ecma48_bg_red:
+ tty->bg=SCR_RED;
+ break;
+
+ case ecma48_bg_green:
+ tty->bg=SCR_GREEN;
+ break;
+
+ case ecma48_bg_brown:
+ tty->bg=SCR_BROWN;
+ break;
+
+ case ecma48_bg_blue:
+ tty->bg=SCR_BLUE;
+ break;
+
+ case ecma48_bg_magenta:
+ tty->bg=SCR_MAGENTA;
+ break;
+
+ case ecma48_bg_cyan:
+ tty->bg=SCR_CYAN;
+ break;
+
+ case ecma48_bg_white:
+ tty->bg=SCR_WHITE;
+ break;
+
+ case ecma48_bg_default:
+ tty->bg=SCR_BLACK;
+ break;
+
+ }
+}
+
+static void process_graphic_npars(terminal_tty *tty)
+{
+
+ char buf[4];
+ int b=0;
+
+ tty->escaping=0;
+
+ for(int i=0;i<tty->npar+1;i++)
+ {
+ char c=tty->command[NPAR_START+i];
+ buf[b++]=c;
+
+ if(i==tty->npar||c==';')
+ {
+ if(b==2)process_graphic_npar(tty,buf[0]-'0');
+ if(b==3)process_graphic_npar(tty,(buf[0]-'0')*10+(buf[1]-'0'));
+ b=0;
+ }
+ //terminal_put(tty,tty->command[NPAR_START+i]);
+ }
+
+ tty->npar=0;
+
+}
+
+static void reset(terminal_tty *tty)
+{
+ tty->bg=SCR_BLACK;
+ tty->fg=SCR_WHITE;
+
+ for(int x=0;x<tty->width;x++)
+ for(int y=0;y<tty->height;y++)
+ {
+ set_char(tty,x,y,' ',tty->fg,tty->bg);
+ }
+
+ tty->x=0;
+ tty->y=0;
+ tty->command_l=0;
+}
+
+terminal_tty terminal_init(term_out *screen,term_in *input)
+{
+ terminal_tty tty;
+
+ tty.data=malloc(2*4096);
+
+ tty.set_buff=true;
+// tty.set_buff=false;
+
+ tty.set_lfnl=true;
+// tty.set_lfnl=false;
+
+
+ tty.set_echo=true;
+ tty.set_echo=false;
+
+ tty.command=malloc(1*4096);
+ tty.command_l=0;
+
+ tty.escaping=0;
+
+ tty.screen=screen;
+ tty.input=input;
+
+ tty.x=0;
+ tty.y=0;
+
+ tty.width=TERM_WIDTH;
+ tty.height=TERM_HEIGHT;
+
+ tty.reverse_video=false;
+
+ reset(&tty);
+
+ return tty;
+}
+
+// send one ASCII character to the terminal
+void terminal_put(terminal_tty *tty, uint8_t c)
+{
+
+ // CONTROL CHARACTERS
+ if(c==0x07){return;} // BEL (ignore)
+ if(c==0x7F){return;} // nothing
+
+ if(c==0x09) // TAB
+ {
+ if(tty->x==tty->width-1)return;
+ set_char(tty,tty->x,tty->y,' ',tty->fg,tty->bg);
+ tty->x++;
+
+ while(tty->x<tty->width-1&&tty->x%8!=0)
+ {
+ set_char(tty,tty->x,tty->y,' ',tty->fg,tty->bg);
+ tty->x++;
+ }
+ tty->x--;
+ c=' ';
+ }
+
+ if(c==0x0E){return;} // G1 set (ignore)
+ if(c==0x0F){return;} // G0 set (ignore)
+
+ if(c==0x18||c==0x1A){tty->escaping=0;return;} // cancel escaping
+ if(c==0x1B){tty->escaping=1;return;} // ESC
+ if(c==0x9B){tty->escaping=2;tty->npar=0;return;} // CSI = ESC [
+
+ if(c==0x08) //BACKSPACE
+ {
+ if((tty->x>0&&tty->command_l>0)||!tty->set_echo)
+ {
+ set_char(tty,tty->x-1,tty->y,' ',tty->fg,tty->bg);
+ tty->x--;
+ }
+ }
+
+ else if(c==0x0D) // CR
+ {
+ tty->x=0;
+ return;
+ }
+
+ else if(c==0x0A||c==0x0B||c==0x0C) // \n NEXTLINE
+ {
+ for(uint32_t x=tty->x;x<tty->width;x++)
+ {
+ set_char(tty,x,tty->y,' ',tty->fg,tty->bg);
+ }
+ tty->y++;
+ if(tty->set_lfnl)tty->x=0;
+ }
+ else //
+ {
+ // ESC- but not CSI-sequences
+ if(tty->escaping==1)
+ {
+ // FOOL-TERM: delchar
+ if(c=='x')
+ {
+ set_char(tty, tty->x, tty->y, ' ', tty->fg, tty->bg);
+ }
+ // FOOL-TERM: clear to end of line
+ if(c=='K')
+ {
+ for(uint32_t x=tty->x;x<tty->width;x++)
+ {
+ set_char(tty, x, tty->y, ' ', tty->fg, tty->bg);
+ }
+ }
+ // FOOL-TERM: clear to end of screen
+ if(c=='J')
+ {
+ for(uint32_t x=tty->x;x<tty->width;x++)
+ {
+ set_char(tty, x, tty->y, ' ', tty->fg, tty->bg);
+ }
+ for(uint32_t y=tty->y+1;y<tty->height;y++)
+ {
+ for(uint32_t x=0;x<tty->width;x++)
+ {
+ set_char(tty,x, y, ' ', tty->fg, tty->bg);
+ }
+ }
+ }
+
+ // FOOL-TERM: home
+ if(c=='H')
+ {
+ tty->x=0;
+ tty->y=0;
+ }
+ // FOOL-TERM: movement
+ if(c=='u')
+ {
+ if(tty->y>0)
+ tty->y--;
+ }
+
+ if(c=='d')
+ {
+ if(tty->y+1<tty->height)
+ tty->y++;
+ }
+
+ if(c=='f')
+ {
+ if(tty->x+1<tty->width)
+ tty->x++;
+ }
+
+ if(c=='b')
+ {
+ if(tty->x>0)
+ tty->x--;
+ }
+
+ ///
+
+ if(c=='c'){reset(tty);} // RESET
+
+ if(c=='D'){tty->y++;} // LINEFEED
+ if(c=='E'){tty->y++;tty->x=0;} //NEWLINE
+
+ //if(c=='H'){} // SET TABSTOP: TODO
+ if(c=='M'){ // REVERSE LINEFEED
+
+ if(tty->y==0)
+ {
+ for(int32_t y=tty->height-1;y>=0;y--)
+ {
+ for(uint32_t x=0;x<tty->width;x++)
+ {
+ uint32_t c=' '|tty->fg<<8|tty->bg<<16;
+ if(y!=0) c=tty->data[index(tty,x,y-1)];
+ tty->data[index(tty,x,y)] = c;
+
+ tty->screen->put_char(c&0xff,(c>>8)&0xff,c>>16,x,y);
+ }
+ }
+ }
+ else
+ tty->y--;
+
+ }
+
+ if(c=='Z'){// IDENTIFY: claim we are vt102
+
+ if(tty->input!=NULL)
+ {
+ tty->input->put_char(0x1B); //ESC
+ tty->input->put_char('[');
+ tty->input->put_char('?');
+ tty->input->put_char('6');
+ tty->input->put_char('c');
+ }
+
+ return;}
+
+ if(c=='7'){}// SAVE STATE (coord,attributes,G0/G1?)
+ if(c=='8'){}// RESTORE STATE
+ if(c=='['){tty->escaping=2;tty->npar=0;return;} // CONTROL SEQ INTRODUCER
+
+
+ // TODO
+ // %, %@, %G, %8, #8, (, (B, (O, (U, (K
+ // ), >, =, ] (???)
+ //
+ //
+
+ tty->escaping=0; // DONE
+ }
+ // CSI SEQEUENCES (AFTER ESC [..)
+ else if(tty->escaping==2)
+ {
+ //ECMA-48: TODO
+
+
+
+
+ //ECMA-48 GRAPHIC RENDITION: OK
+ if(c!='m')
+ {
+ tty->command[NPAR_START+(tty->npar++)]=c;
+ }
+ else
+ {
+ process_graphic_npars(tty);
+ }
+
+ //ECMA-48 MODE SWITCHES: TODO
+ //ECMA-48 STATUS REPORT: TODO
+ //DEC PRIVATE MODE: TODO
+ //LINUX CONSOLE PRIVATE CSI: TODO
+ //
+ // ESC [ 1 ; n ] Set color n as the underline color
+ // ESC [ 2 ; n ] Set color n as the dim color
+ // ESC [ 8 ] Make the current color pair the default attributes.
+ // ESC [ 9 ; n ] Set screen blank timeout to n minutes.
+ // ESC [ 10 ; n ] Set bell frequency in Hz.
+ // ESC [ 11 ; n ] Set bell duration in msec.
+ // ESC [ 12 ; n ] Bring specified console to the front.
+ // ESC [ 13 ] Unblank the screen.
+ // ESC [ 14 ; n ] Set the VESA powerdown interval in minutes.
+
+ }
+ else //PROBABLY (AND HOPEFULLY) JUST A NORMAL CHAR
+ {
+ set_char(tty,tty->x,tty->y,c,tty->fg,tty->bg);
+ tty->x++;
+ }
+
+ }
+
+ //autobreak
+ if(tty->x>=tty->width)
+ {
+ tty->x=0;
+ tty->y++;
+ }
+
+ //autoscroll
+ if(tty->y>=tty->height)
+ {
+ tty->y--;
+ for(uint32_t y=0;y<tty->height;y++)
+ {
+ for(uint32_t x=0;x<tty->width;x++)
+ {
+ uint32_t c=tty->data[index(tty,x,y+1)];
+ if(y==tty->height-1)c=' '|tty->fg<<8|tty->bg<<16;
+ tty->data[index(tty,x,y)] = c;
+ tty->screen->put_char(c&0xff,(c>>8)&0xff,c>>16,x,y);
+ }
+ }
+ }
+
+ //cusor pos
+ tty->screen->update_cursor(tty->x,tty->y);
+ return;
+}
diff --git a/userspace/vesa.c b/userspace/xterm/vesa.c
index 7901b1f..d38f3f2 100644
--- a/userspace/vesa.c
+++ b/userspace/xterm/vesa.c
@@ -1,7 +1,7 @@
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
-#include "newcalls.h"
+#include "../newcalls.h"
#define VMEM_USER_FRAMEBUFFER 0xfa000000
@@ -352,8 +352,6 @@ void vesa_init_doublebuff()
}
*/
-
-
int main()
{
FILE *f=fopen("/doc/fonts/binfont.bin","r");
diff --git a/userspace/xterm/xterm.c b/userspace/xterm/xterm.c
new file mode 100644
index 0000000..10b222c
--- /dev/null
+++ b/userspace/xterm/xterm.c
@@ -0,0 +1,2 @@
+#include <stdio.h>
+