sos

[unmaintained] experimenting with low level OS development
Log | Files | Refs | README | LICENSE

io.c (2084B)


      1 #include "io.h"
      2 #include "math.h"
      3 
      4 static uint16_t curpos = 0;
      5 
      6 static void shift_screen_up() {
      7     char *vidmem = (char*)0xb8000;
      8 
      9     // Move existing lines one row up
     10     for (int line = 1; line < VIDEO_SCREEN_HEIGHT; line++) {
     11         for (int line_byte = 0; line_byte < 2 * VIDEO_SCREEN_WIDTH; line_byte++) {
     12             int offset = 2 * VIDEO_SCREEN_WIDTH * line + line_byte;
     13 
     14             vidmem[offset - 2 * VIDEO_SCREEN_WIDTH] = vidmem[offset];
     15         }
     16     }
     17     // Reset text on "new" line
     18     for (int col = 0; col < VIDEO_SCREEN_WIDTH; col++) {
     19         int offset = 2 * VIDEO_SCREEN_WIDTH * (VIDEO_SCREEN_HEIGHT - 1) + 2 * col;
     20 
     21         vidmem[offset] = ' ';
     22     }
     23     // Reset colors on "new" line
     24     for (int col = 0; col < VIDEO_SCREEN_WIDTH; col++) {
     25         int offset = 2 * VIDEO_SCREEN_WIDTH * (VIDEO_SCREEN_HEIGHT - 1) + 2 * col + 1;
     26 
     27         vidmem[offset] = 0xf;
     28     }
     29 
     30     curpos -= VIDEO_SCREEN_WIDTH;
     31 }
     32 
     33 static void increment_cursor() {
     34     curpos++;
     35 
     36     if (curpos >= VIDEO_SCREEN_WIDTH * VIDEO_SCREEN_HEIGHT) {
     37         shift_screen_up();
     38     }
     39 }
     40 
     41 void kprint(char *str) {
     42     for (int i = 0; str[i] != 0; i++) {
     43         kprintc(str[i]);
     44     }
     45 }
     46 
     47 void kprintc(char c) {
     48     char *vidmem = (char*)VIDMEM;
     49     vidmem[2*curpos] = c;
     50     vidmem[2*curpos + 1] = 0x9;
     51 
     52     increment_cursor();
     53 }
     54 
     55 static short no_of_digits(int value) {
     56     short len = 0;
     57     int tmp = 1;
     58 
     59     while (tmp < value) {
     60         len++;
     61         tmp = (tmp << 3) + (tmp << 1);
     62     }
     63 
     64     return len;
     65 }
     66 
     67 void kprinti(int value) {
     68     short digits = no_of_digits(value);
     69 
     70     int divisor = (int)power(10, digits - 1);
     71     for (int i = divisor; i > 0; i /= 10) {
     72         short digit = value / i;
     73         value %= i;
     74         kprintc((char)(digit + 48));
     75     }
     76 }
     77 
     78 void kprintx(int value) {
     79     kprint("0x");
     80 
     81     int divisor = power(16, 7);
     82     for (int i = 0; i < 8; i++) {
     83         short digit = value / divisor;
     84         value %= divisor;
     85         divisor /= 16;
     86 
     87         if (digit < 10)
     88             kprintc((char)(digit + 48));
     89         else
     90             kprintc((char)(digit + 55));
     91     }
     92 }