commit aac558f8a7a7670e1965637a5f8a64b011039259
parent 3c1904252a6c0afedb50ce154067f734b0087867
Author: Samdal <samdal@protonmail.com>
Date: Thu, 20 Feb 2025 19:25:26 +0100
add terminal seksjon i vga kontroller
Diffstat:
2 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/_posts/2024-05-08-VGA-Kontroller.md b/_posts/2024-05-08-VGA-Kontroller.md
@@ -688,3 +688,131 @@ void vga_text_mode_set_xy(int base_address, unsigned char x, unsigned char y, vg
IOWR_32DIRECT(base_address, (y*80+x)*4, c.raw_word);
}
```
+
+## C eksempel [Terminal]
+
+
+{: style="text-align: center; margin-bottom: 0px; padding-bottom: 0px"}
+Figur 19. Bilde av terminalen
+{: style="color:gray; font-size: 80%; text-align: center;"}
+```
+void random_tm(const char* cb)
+{
+ vga_set_mode(VGA_CONTROLLER_0_BASE, VGA_MODE_TEXT_MODE);
+ for (uint32_t i = 0; i < 80*30; i++) {
+ vga_text_mode_t c = {
+ .raw_word = rand() % 0xffff,
+ };
+ vga_text_mode_set(VGA_CONTROLLER_0_BASE, i, c);
+ }
+}
+
+struct commands {
+ void(*func)(const char* cb);
+ const char* name;
+ const char* desc;
+ int quit_immidiately;
+} commands[] = {
+ {cat, "cat", "shows a picture of a cat"},
+ {gradient, "gradient", "RGB gradient"},
+ {cycle_rgb_slow, "cycle", "slowly cycle rgb", 1},
+ {0, "clear", "clears screen", 1},
+ {display_char, "char", "displays all combinations of arg1 (1 character)"},
+ {random, "rand", "random colors"},
+ {random_tm, "tmrand", "random colors text mode"},
+
+};
+
+#define vga_printstr(_base, _x, _y, _str) do { \
+ for (uint32_t _i = 0; _i < strlen(_str); _i++) { \
+ c.codepoint = (_str)[_i]; \
+ vga_text_mode_set_xy(_base, _x, _y, c); \
+ (_x)++; \
+ } \
+ } while (0)
+
+#define vga_printstr_ln(_base, _x, _y, _str) do { \
+ vga_printstr(_base, _x, _y, _str); \
+ (_y) += 1; \
+ (_y) += (_x) / 80; \
+ (_x) = 0; \
+ } while (0)
+
+int main() {
+clear_screen:
+ vga_clear_screen(VGA_CONTROLLER_0_BASE);
+ vga_set_mode(VGA_CONTROLLER_0_BASE, VGA_MODE_TEXT_MODE);
+ char command_buffer[128] = {0};
+ uint32_t x = 0;
+ uint32_t y = 0;
+ vga_text_mode_t c = {
+ .bg = 0,
+ .fg = 15,
+ };
+line_begin:
+ vga_printstr(VGA_CONTROLLER_0_BASE, x, y, "$> ");
+ for (;;) {
+ c.codepoint = 221;
+ c.blink = 1;
+ vga_text_mode_set_xy(VGA_CONTROLLER_0_BASE, x, y, c);
+ c.blink = 0;
+
+ unsigned char codepoint = getchar();
+
+ c.codepoint = 0;
+ vga_text_mode_set_xy(VGA_CONTROLLER_0_BASE, x, y, c);
+ if (codepoint == '\n' || codepoint == '\r') {
+ vga_printstr_ln(VGA_CONTROLLER_0_BASE, x, y, "");
+
+ for (uint32_t i = 0; i < sizeof(commands) / sizeof(*commands); i++) {
+ if (memcmp(commands[i].name, command_buffer, strlen(commands[i].name)) == 0) {
+ if (commands[i].func)
+ commands[i].func(command_buffer);
+ command_buffer[0] = 0;
+ if (!commands[i].quit_immidiately)
+ getchar();
+ goto clear_screen;
+ }
+ }
+ if (memcmp("help", command_buffer, strlen("help")) == 0) {
+ for (uint32_t i = 0; i < sizeof(commands) / sizeof(*commands); i++) {
+ vga_printstr(VGA_CONTROLLER_0_BASE, x, y, "> ");
+ vga_printstr(VGA_CONTROLLER_0_BASE, x, y, commands[i].name);
+ vga_printstr(VGA_CONTROLLER_0_BASE, x, y, " | ");
+ vga_printstr_ln(VGA_CONTROLLER_0_BASE, x, y, commands[i].desc);
+ }
+ } else if (*command_buffer != 0) {
+ if (strchr(command_buffer, ' ')) *strchr(command_buffer, ' ') = 0;
+ vga_printstr(VGA_CONTROLLER_0_BASE, x, y, "[term: error]: command '");
+ vga_printstr(VGA_CONTROLLER_0_BASE, x, y, command_buffer);
+ vga_printstr_ln(VGA_CONTROLLER_0_BASE, x, y, "' not found");
+ }
+ command_buffer[0] = 0;
+ goto line_begin;
+ continue;
+ }
+ if (codepoint == 127) {
+ if (x > 3) x--;
+ c.codepoint = 0;
+ vga_text_mode_set_xy(VGA_CONTROLLER_0_BASE, x, y, c);
+ command_buffer[x-3] = codepoint;
+ command_buffer[x-3+1] = 0;
+ continue;
+ }
+ c.codepoint = codepoint;
+ vga_text_mode_set_xy(VGA_CONTROLLER_0_BASE, x, y, c);
+ if (x-3 < sizeof(command_buffer)) {
+ command_buffer[x-3] = codepoint;
+ command_buffer[x-3+1] = 0;
+ }
+ x++;
+ }
+}
+```
+
+
+
+
+
+
+
diff --git a/assets/images/VGA/VGA_fig19.jpeg b/assets/images/VGA/VGA_fig19.jpeg
Binary files differ.