Commit 9adfe80d authored by Oxynux's avatar Oxynux

cursor, enter, vga nav

parent 1a3b4675
......@@ -9,6 +9,7 @@
*/
#define VID_MEMORY 0x0b8000
#define VGA_WIDTH 80
/*
* Max Columns and Lines
......@@ -40,4 +41,5 @@
char getchar();
#endif
......@@ -5,10 +5,10 @@ unsigned char kbdus[128] = {
0, // esc
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'-', '=',
0, // backspace
253, // backspace
0, // tab
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
0, // enter
255, // enter
0, // left ctrl
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
0, // left shift
......@@ -23,15 +23,15 @@ unsigned char kbdus[128] = {
0, // numlock
0, // scroll lock
0, // home
0, // up
150, // up
0, // page up
'-',
0, // left
151, // left
0, // keypad 5
0, // right
152, // right
'+',
0, // end
0, // down
153, // down
0, // page down
0, // insert
0, // del
......@@ -60,12 +60,12 @@ unsigned char kbdus[128] = {
*
*/
// static inline void outb(uint16_t port, uint8_t val)
// {
// asm volatile ( "outb %0, %1"
// :
// : "a"(val), "Nd"(port) );
// }
static inline void outb(uint16_t port, uint8_t val)
{
asm volatile ( "outb %0, %1"
:
: "a"(val), "Nd"(port) );
}
/*
......
......@@ -4,6 +4,79 @@
#include "include/kernel.h"
/*
*
* outb: output byte in AL (here it's val and 0x0 in get_scancode())
* to I/O port address in DX (here it's port and 0x60 in get_scancode())
*
* a: constraint mean use the A register (in this case AL)
* Nd: constraint mean:
* N: force 8-bit integer constant
* d: use the D register (in this case DX)
*
* x86 OUT (Output to Port) :
* Copies the value from the second operand (source operand)
* to the I/O port specified with the destination operand (first operand).
*
*/
static inline void outb(uint16_t port, uint8_t val)
{
asm volatile ( "outb %0, %1"
:
: "a"(val), "Nd"(port) );
}
/*
*
* inb: take I/O port address in DX (here it's port and 0x60 in get_scancode())
* and return the I/O port value in AL (here ret and c= in get_scancode())
*
* =a: constraint mean use the A register (in this case AL) and copy it to
* ret as output
*
* Nd: constraint mean:
* N: force 8-bit integer constant
* d: use the D register (in this case DX)
*
* x86 IN (Input from Port) :
* Copies the value from the I/O port
* specified with the second operand (source operand)
* to the destination operand (first operand).
*
*/
static inline uint8_t inb(uint16_t port)
{
uint8_t ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(port) );
return ret;
}
void enable_cursor(uint8_t cursor_start, uint8_t cursor_end)
{
outb(0x3D4, 0x0A);
outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start);
outb(0x3D4, 0x0B);
outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end);
}
void update_cursor(int x, int y)
{
uint16_t pos = y * VGA_WIDTH + x;
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t) (pos & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF));
}
static void ft_write_on_screen(const char *str, char *vidptr)
{
unsigned int i, j = 0;
......@@ -41,15 +114,86 @@ static void ft_clear_screen()
}
}
int column(char *video)
{
return (((video - (char *)VID_MEMORY) / 2) % 80);
}
int line(char *video)
{
return (((video - (char *)VID_MEMORY) / 2) / 80);
}
void enter(char **video)
{
// if (line(*video) == 25)
// *video = (char *)VID_MEMORY;
// else
*video = (char *)VID_MEMORY + 80 * 2 * (line(*video) + 1);
// update_cursor(((*video-(char *)VID_MEMORY)/2)%80, ((*video-(char *)VID_MEMORY)/2)/80);
}
static inline void del(char **video)
{
if ((int)*video - 2 < (int)VID_MEMORY)
*video = *video - 2 + (80 * 25 * 2);
else
*video -= 2;
**video = ' ';
}
static inline void arrow_up(char **video)
{
if ((int)*video - MAX_COLUMNS * 2 < (int)VID_MEMORY)
*video = *video - MAX_COLUMNS * 2 + (80 * 25 * 2);
else
*video -= MAX_COLUMNS * 2;
}
static inline void arrow_down(char **video)
{
if ((int)*video + MAX_COLUMNS * 2 > (int)VID_MEMORY + (80 * 25 * 2))
*video = *video + MAX_COLUMNS * 2 - (80 * 25 * 2);
else
*video += MAX_COLUMNS * 2;
}
static inline void arrow_right(char **video)
{
if ((int)*video + 2 > (int)VID_MEMORY + (80 * 25 * 2))
*video = *video + 2 - (80 * 25 * 2);
else
*video += 2;
}
static inline void arrow_left(char **video)
{
if ((int)*video - 2 < (int)VID_MEMORY)
*video = *video - 2 + (80 * 25 * 2);
else
*video -= 2;
}
static void kputchar(char c) {
static char *video = (char*)VID_MEMORY;
static char color = WHITE;
if (video == (char*)(VID_MEMORY + MAX_COLUMNS * MAX_LINES * 2))
video = (char*)VID_MEMORY;
switch ((unsigned char)c)
{
case 200:
case 150:
arrow_up(&video);
break;
case 151:
arrow_left(&video);
break;
case 152:
arrow_right(&video);
break;
case 153:
arrow_down(&video);
break;
case 200:
color = BLUE;
break;
case 201:
......@@ -79,11 +223,20 @@ static void kputchar(char c) {
case 209:
color = WHITE;
break;
case 253:
del(&video);
break;
case 255:
enter(&video);
break;
default:
*video++ = c;
*video++ = color;
break;
}
if (video == (char*)(VID_MEMORY + MAX_COLUMNS * MAX_LINES * 2))
video = (char *) VID_MEMORY;
update_cursor(column(video), line(video));
}
static void basic_kbd() {
......@@ -103,6 +256,7 @@ void kmain(void)
char c;
ft_clear_screen();
enable_cursor(0, 15);
ft_write_on_screen(str, vidptr);
while (1) {
c = getchar();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment