Began work on proper terminal I/O

- Chenged Puts() syscall to Write()
- Improved syscalls.h
- added a new header in terminal/terminal.h
- moved gfxMode into screen/gfxmode.h
This commit is contained in:
2024-05-27 15:16:07 +02:00
parent eac71f137e
commit 536f6b2320
11 changed files with 285 additions and 111 deletions
+35
View File
@@ -0,0 +1,35 @@
--- Terminal Escape Sequences ---
Escape character:
char: '\e'
hex: 0x1b
oct: 0o33
dec: 27
Note: the escape character will be denoted by ESC here
Syntax:
All escape sequenced start with the escape character followed by an opening square bracket '['
The sequence can take any number of arguments in a semicolon separated list
If a argument is skipped, it will be implicitly set to 0
The escape sequence must end with a uppercase or lowercase letter
Available escape sequences:
- Cursor Controls -
`ESC[#A` - Moves cursor # rows up
`ESC[#B` - Moves cursor # rows down
`ESC[#C` - Moves cursor # columns left
`ESC[#D` - Moves cursor # columns right
`ESC[#E` - Moves cursor to #th row
`ESC[#F` - Moves cursor to #th column
`ESC[#G` - Show (# = 1) or hide (# = 0) cursor
`ESC[{row};{col}H` - Moves cursor to specified position (if not arguments given, moves to [0,0])a
- Erase functions -
`ESC[I` - Reserved
`ESC[J` - Erase screen
`ESC[K` - Erase line (not implemented)
`ESC[L` - Erase column (not implemented)
- Text Style -
`ESC[#M` - Sets foreground color to #
`ESC[#N` - Sets backgorund color to #
-8
View File
@@ -1,8 +0,0 @@
--- Memory Map ---
0x1000 - Kernel
0x6000 - Font
0x7000 - Filetable (0x7c00 - Bootloader)
0x8500 - ACPI Memory map
0x9000 - VBE Mode Info Block
0x30000 - Memory manager memmap
+17 -2
View File
@@ -2,10 +2,25 @@
Syscall handlers are prefixed by 'sys_'
Syscalls can be called using interrupt 0x80
The EAX register should countain a syscall number
The EAX register should countain a syscall number on calling and it will contain a return value (if applicable) after calling
Here's a list of syscalls: (and their numbers)
syscall(0) : Sleep()
Syscall(0) : Sleep()
Args: EBX - Number of miliseconds to sleep for
Syscall(1) : Write()
Args: EBX - File descriptor
ECX - Buffer to write
EDX - Length
Returns: Status
Syscall(2) : Read() #TBD
Syscall(3) : Malloc()
Args: EBX - Amount of bytes to malloc
Returns: Address of allocated memory
Syscall(4) : Free()
Args: EBX - Pointer to free
+10 -4
View File
@@ -1,12 +1,18 @@
#ifndef STDIO_H
#define STDIO_H
void print(const char* s) { // Use Syscall(1) - Puts()
__asm__ volatile ("int $0x80" : : "a"(1), "b"(s));
#include <syscall.h>
#include <string.h>
// TODO: Make a proper file descriptor table
#define STDOUT 1
void print(const char* s) {
write(STDOUT, s, strlen(s));
}
void read(char* s) { // Use Syscall(2) - Gets()
__asm__ volatile ("int $0x80" : : "a"(2), "b"(s));
void read(char* s) {
print("\x1b[1M[ ERROR: Read() Syscall not found! ]\n");
}
#endif
+23
View File
@@ -0,0 +1,23 @@
#ifndef SYSCALLNUMS_H
#define SYSCALLNUMS_H
#include <stdint.h>
#define MAX_SYSCALLS 5
typedef enum {
SYS_SLEEP,
SYS_WRITE,
SYS_GETS,
SYS_MALLOC,
SYS_FREE,
} SYSCALL_NUMBERS;
// TODO: Add malloc() and free() syscall wrappers??
int32_t write(int32_t fd, const void* buf, uint32_t len) {
int32_t result = -1;
__asm__ volatile ("int $0x80" : "=a"(result) : "a"(SYS_WRITE), "b"(fd), "c"(buf), "d"(len));
return result;
}
#endif
@@ -3,13 +3,13 @@
#include <interrupt/idt.h>
#include <interrupt/pit.h>
#include <screen/text.h>
#include <terminal/terminal.h>
#include <keyboard/keyboard.h>
#include <memory/malloc.h>
#include <syscall.h>
#include <stdint.h>
// System call count
#define MAX_SYSCALLS 5
// Syscall(0) - Sleep()
// Args: ebx - number of miliseconds
void sys_sleep() {
uint32_t ms;
@@ -21,12 +21,24 @@ void sys_sleep() {
}
}
// TODO: Use a Write() syscall and write to stdout
// Args: ebx - char* string
void sys_puts() {
char* s;
__asm__ volatile ("movl %%ebx, %0" : "=r"(s));
print(s);
// Syscall(1) - Write()
// Args: ebx - int fd
// ecx - void* buf
// edx - uint32_t len
void sys_write() {
int32_t fd = 0;
void* buf = NULL;
uint32_t len = 0;
__asm__ volatile ("nop" : "=b"(fd), "=c"(buf), "=d"(len));
// TODO: Open fd table?
if (fd == 1) { // "stdout"
int32_t result = terminalWrite(buf, len); // Call a terminal print function
__asm__ volatile ("movl %0, %%eax" : : "r"(result));
} else { // Not implemented
__asm__ volatile ("movl $1, %eax");
}
}
// TODO: Use a Read() sycall and read from stdin
@@ -37,7 +49,9 @@ void sys_gets() {
read(s);
}
// Syscall(3) - Malloc()
// Args: ebx - amount of bytes to malloc
// Returns: eax - Pointer to allocated memory
void sys_malloc() {
uint32_t size = 0;
__asm__ volatile ("movl %%ebx, %0" : "=b"(size));
@@ -54,6 +68,7 @@ void sys_malloc() {
__asm__ volatile ("movl %0, %%eax" : : "r"(ptr));
}
// Syscall(4) - Free()
// Args: ebx - allocated pointer
void sys_free() {
void* ptr = NULL;
@@ -62,12 +77,12 @@ void sys_free() {
}
// System call table
void* syscalls[MAX_SYSCALLS] = {
sys_sleep, // Syscall(0)
sys_puts, // Syscall(1)
sys_gets, // Syscall(2)
sys_malloc, // Syscall(3)
sys_free, // Syscall(4)
void (*syscalls[MAX_SYSCALLS])(void) = {
[SYS_SLEEP] = sys_sleep,
[SYS_WRITE] = sys_write,
[SYS_GETS] = sys_gets,
[SYS_MALLOC] = sys_malloc,
[SYS_FREE] = sys_free,
};
// int 0x80 - Syscall interrupt, handled by this function
+9
View File
@@ -1,9 +1,18 @@
#ifndef ADDRESSES_H
#define ADDRESSES_H
// TODO: Don't let these be just random numbers?
// Locations
#define KERNEL_LOC 0x100000
#define FILETABLE_LOC 0x7000
#define TERMINAL_INFO_LOC 0x2000
#define MODE_INFO_BLOCK_LOC 0x9000
// Font
#define FONT_LOC 0x6000
#define FONT_WIDTH (FONT_LOC)
#define FONT_HEIGHT (FONT_LOC + 1)
// Physical memory manager
#define MEMMAP_AREA 0x30000
+79
View File
@@ -0,0 +1,79 @@
#ifndef GFXMODE_H
#define GFXMODE_H
#include <memory/addresses.h>
#include <stdint.h>
#define BLACK 0x00000000 // 0
#define RED 0x00ff0000 // 1
#define GREEN 0x0000ff00 // 2
#define YELLOW 0x00ffff00 // 3
#define BLUE 0x000000ff // 4
#define MAGENTA 0x00ff00ff // 5
#define CYAN 0x0000ffff // 6
#define WHITE 0x00ffffff // 7
#define BG_COLOR 0x00010b17
#define FG_COLOR 0x00ebddf4
typedef struct modeInfoBlock_s {
// Required by all VBE revisions
uint16_t modeAttr;
uint8_t windowAAtrr;
uint8_t windowBAttr;
uint16_t windowGranularity;
uint16_t windowSize;
uint16_t windowASegment;
uint16_t windowBSegment;
uint32_t windowFunctionPtr;
uint16_t bytesPerScanline;
// Required by VBE 1.2+
uint16_t xRes;
uint16_t yRes;
uint8_t xCharSize;
uint8_t yCharSize;
uint8_t planeCount;
uint8_t bpp;
uint8_t bankCount;
uint8_t memoryModel;
uint8_t bankSize;
uint8_t imagePageCount;
uint8_t reserved1;
// Direct color fields
uint8_t redMaskSize;
uint8_t redFieldPos;
uint8_t greenMaskSize;
uint8_t greenFieldPos;
uint8_t blueMaskSize;
uint8_t blueFieldPos;
uint8_t reservedMaskSize;
uint8_t reservedFieldPos;
uint8_t directColorModeInfo;
// Required by VBE 2.0+
uint32_t physicalBasePtr;
uint32_t reserved2;
uint16_t reserved3;
// Required by VBE 3.0+
uint16_t linearBytesPerScanline;
uint8_t bankImagePageCount;
uint8_t linearImagePageCount;
uint8_t linearRedMaskSize;
uint8_t linearRedFieldPos;
uint8_t linearGreenMaskSize;
uint8_t linearGreenFieldPos;
uint8_t linearBlueMaskSize;
uint8_t linearBlueFieldPos;
uint8_t linearReservedMaskSize;
uint8_t linearReservedFieldPos;
uint32_t maxPixelClock;
uint8_t reserved4[190];
} __attribute__ ((packed)) modeInfoBlock_t;
static modeInfoBlock_t* gfxMode = (modeInfoBlock_t*)MODE_INFO_BLOCK_LOC;
#endif
+12 -78
View File
@@ -1,89 +1,18 @@
#ifndef SCREEN_H
#define SCREEN_H
#include <memory/addresses.h>
#include <screen/gfxmode.h>
#include <stdint.h>
#include <string.h>
// Basic full saturation colors
#define BLACK 0x00000000 // 0
#define RED 0x00ff0000 // 1
#define GREEN 0x0000ff00 // 2
#define YELLOW 0x00ffff00 // 3
#define BLUE 0x000000ff // 4
#define MAGENTA 0x00ff00ff // 5
#define CYAN 0x0000ffff // 6
#define WHITE 0x00ffffff // 7
#define MODE_INFO_BLOCK 0x9000
#define BG_COLOR 0x00010b17
#define FG_COLOR 0x00ebddf4
typedef struct modeInfoBlock_s {
// Required by all VBE revisions
uint16_t modeAttr;
uint8_t windowAAtrr;
uint8_t windowBAttr;
uint16_t windowGranularity;
uint16_t windowSize;
uint16_t windowASegment;
uint16_t windowBSegment;
uint32_t windowFunctionPtr;
uint16_t bytesPerScanline;
// Required by VBE 1.2+
uint16_t xRes;
uint16_t yRes;
uint8_t xCharSize;
uint8_t yCharSize;
uint8_t planeCount;
uint8_t bpp;
uint8_t bankCount;
uint8_t memoryModel;
uint8_t bankSize;
uint8_t imagePageCount;
uint8_t reserved1;
// Direct color fields
uint8_t redMaskSize;
uint8_t redFieldPos;
uint8_t greenMaskSize;
uint8_t greenFieldPos;
uint8_t blueMaskSize;
uint8_t blueFieldPos;
uint8_t reservedMaskSize;
uint8_t reservedFieldPos;
uint8_t directColorModeInfo;
// Required by VBE 2.0+
uint32_t physicalBasePtr;
uint32_t reserved2;
uint16_t reserved3;
// Required by VBE 3.0+
uint16_t linearBytesPerScanline;
uint8_t bankImagePageCount;
uint8_t linearImagePageCount;
uint8_t linearRedMaskSize;
uint8_t linearRedFieldPos;
uint8_t linearGreenMaskSize;
uint8_t linearGreenFieldPos;
uint8_t linearBlueMaskSize;
uint8_t linearBlueFieldPos;
uint8_t linearReservedMaskSize;
uint8_t linearReservedFieldPos;
uint32_t maxPixelClock;
uint8_t reserved4[190];
} __attribute__ ((packed)) modeInfoBlock_t;
struct cursor_s {
uint32_t x;
uint32_t y;
};
static char* font = (char*)0x6000;
static char* font = (char*)FONT_LOC;
static struct cursor_s cursor = { 0, 0 };
static modeInfoBlock_t* gfxMode = (modeInfoBlock_t*)MODE_INFO_BLOCK;
uint32_t bgColor = BG_COLOR;
uint32_t fgColor = FG_COLOR;
@@ -105,8 +34,8 @@ uint32_t convertColor(uint32_t color) {
// TODO: Reimplement larger text
void putcAt(unsigned char c, uint32_t x, uint32_t y) {
// Font info
uint8_t charWidth = *(font);
uint8_t charHeight = *(font + 1);
uint8_t charWidth = *(uint8_t*)FONT_WIDTH;
uint8_t charHeight = *(uint8_t*)FONT_HEIGHT;
// uint8_t bitmapRowLen = (charWidth - 1) / 8 + 1; // TODO: Larger font support
// Video stuff
@@ -133,6 +62,7 @@ void putcAt(unsigned char c, uint32_t x, uint32_t y) {
}
}
// TODO: Probably get rid of this, idk (use terminal control codes)
void printAt(const char* str, uint32_t x, uint32_t y) {
while (*str != '\0') {
putcAt(*str++, x, y);
@@ -140,8 +70,9 @@ void printAt(const char* str, uint32_t x, uint32_t y) {
}
}
// TODO: Use terminal.x/y instead of cursor.x/y
void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() helped alot)
uint8_t charHeight = *(font + 1);
uint8_t charHeight = *(uint8_t*)FONT_HEIGHT;
if ((cursor.y+1) * charHeight < gfxMode->yRes) { return; } // Check if we should scroll
uint32_t bytesPerLine = charHeight * gfxMode->bytesPerScanline;
@@ -167,8 +98,9 @@ void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() help
cursor.y--;
}
// DEPRICATED - TODO: Remove this from everywhere so i can delete it
void putc(char c) {
uint8_t charWidth = *(font);
uint8_t charWidth = *(uint8_t*)FONT_WIDTH;
if (c == '\n') {
putcAt(' ', cursor.x, cursor.y); // Make sure we don't leave an extra cursor
@@ -198,12 +130,14 @@ void putc(char c) {
scroll();
}
// DEPRICATED - TODO: Remove this everywhere it's used and delete it's definition here
void print(const char* str) {
while (*str != '\0') {
putc(*str++);
}
}
// TODO: Make this comply with the new terminal.h thing!
void clear() {
uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr;
uint8_t bytesPerPx = (gfxMode->bpp+1) / 8;
+65
View File
@@ -0,0 +1,65 @@
#ifndef TERMINAL_H
#define TERMINAL_H
#include <screen/text.h>
#include <screen/gfxmode.h>
#include <memory/addresses.h>
#include <stdint.h>
#include <stdbool.h>
typedef struct {
uint32_t x; // X Position of cursor in characters
uint32_t y; // Y Position of cursor in characters
uint32_t bg; // Printed character background
uint32_t fg; // Printed character foreground
uint32_t width; // Width in characters
uint32_t height; // Height in characters
bool showCursor; // Should we display the cursor
} terminal_t;
terminal_t* terminal = (terminal_t*)TERMINAL_INFO_LOC;
int32_t terminalWrite(const void* buf, uint32_t len) {
terminal->width = gfxMode->xRes / *(uint8_t*)FONT_WIDTH;
terminal->height = gfxMode->yRes / *(uint8_t*)FONT_HEIGHT;
char* str = (char*)buf;
uint32_t i;
// Do we need to check for NULL? Can we just skip it/ignore it?
for (i = 0; i < len && str[i] != '\0'; i++) {
if (str[i] == '\n') {
putcAt(' ', terminal->x, terminal->y); // Remove extra cursor
terminal->y++;
terminal->x = 0;
} else if (str[i] == '\b') {
putcAt(' ', terminal->x, terminal->y); // Remove extra cursor
if (terminal->x == 0) {
terminal->x = terminal->width - 1;
terminal->y--; // Y could be 0?
} else {
terminal->x--;
}
putcAt(' ', terminal->x, terminal->y);
} else if (str[i] == '\x1b') { // Escape sequence
if (str[++i] != '[') { // TODO: Suppord more types of escape sequences
continue;
}
putcAt(str[++i], terminal->x++, terminal->y);
} else {
putcAt(str[i], terminal->x, terminal->y);
terminal->x++;
if (terminal->x >= terminal->width) { // Go to next line
terminal->y++;
terminal->x = 0;
}
}
}
scroll();
return i; // Number of characters that were printed
}
#endif
+4 -3
View File
@@ -75,7 +75,8 @@ Legend:
- [x] PI
- [ ] Floating point macros/functions
- [ ] Filesystem
- [ ] Utility for filesystem building (not just an assembly file)
- [!] Utility for filesystem building (not just an assembly file)
- [x] Better header for file i/o (disk/filesys.h)
- [x] Filetable
- [ ] Files
- [x] Larger than one sector (512B)
@@ -89,7 +90,7 @@ Legend:
- [ ] Hard
- [ ] System Calls
- [x] Sleep()
- [ ] Write() (temporarly puts())
- [x] Write()
- [ ] Read() (temporarly gets())
- [ ] Open()
- [ ] Close()
@@ -131,7 +132,7 @@ Legend:
- [ ] Standalone shell program
- [ ] Userspace programs
- [ ] Calculator
- [ ] Caledar
- [ ] Calendar
- [ ] Code Editor
- [ ] Text editor
- [ ] Syntax highlighting