Page 1 of 1

I can't print strings longer than ~60 chars?

Posted: Fri May 26, 2023 6:17 am
by Kaius
Hi. I'm developing a very sloppy, basic kernel, and for some reason my print function doesn't want to work for strings over ~60 characters in length; My GDT is the basic flat model; Here's my code:
kernel.c

Code: Select all

#define VIDEO_ADDRESS 0xb8000
#define MAX_ROWS 25
#define MAX_COLS 80
#define MAX_LEN 0xb8fa1

typedef unsigned char uint8;
typedef unsigned short int uint16;
typedef unsigned int uint32;
typedef unsigned long int uint64;

#include "../libc/libc.h"
#include "../drivers/screen.h"
#include "../drivers/io.h"
#include "../drivers/keyboard.h"


int main() {
  enableKeyboard();
  char string[] = "Hello, World!";
  char two[] = "Welcome to NIGHTMARE OS!!!";
  char test[] = "1234567890123456789012345678901234567890123456789012345678901234";
  uint8 color = 0x00;
  clear_screen(' ', color);
  kprint(test, 0, 0);
  
  while (1) {
    handleKeyboardInput();
  }
  return 0;
}
screen.c:

Code: Select all

int cursorX = 0;
int cursorY = 0;

char *xyToVidmem(int x, int y) {
  char *vidmem = (char *)VIDEO_ADDRESS;
  vidmem += x * 2;
  vidmem += y * 2 * MAX_COLS;
  return vidmem;
}

void newl() {
  cursorY++;
  cursorX = 0;
  //// scrolling
  if (cursorY == MAX_ROWS) {
    char *vidmem = xyToVidmem(0, 1);
    while (vidmem <= MAX_LEN) {
      *(vidmem - (MAX_COLS * 2)) = *vidmem;
      vidmem++;
    }
    //// clear final line
    cursorY--;
  }
}

int print(char string[]) {
  int len = strlen(string);

  char *vidmem = xyToVidmem(cursorX, cursorY);


  while (*string != 0) {
    cursorX++;
    if (cursorX == MAX_ROWS) {
      newl();
    }

    *vidmem++ = *string++;
    *vidmem++ = 0x07;
  }

  return 0;
}

int printf(char string[]) {
  int len = strlen(string);

  char *vidmem = xyToVidmem(cursorX, cursorY);


  while (*string != 0) {
    cursorX++;
    if (cursorX == MAX_ROWS) {
      newl();
    }

    *vidmem++ = *string++;
    *vidmem++ = 0x07;
  }
  newl();

  return 0;
}



int kprint(char string[], int x, int y) {
  // don't write outside of video buffer
  if (x >= MAX_COLS || y >= MAX_ROWS || x < 0 || y < 0) return -1;

  char *vidmem = (char *)VIDEO_ADDRESS;
  vidmem += x * 2;
  vidmem += y * 2 * MAX_COLS;


  while (*string != 0) {
    if (vidmem >= MAX_LEN) return -2;
    *vidmem++ = *string++;
    *vidmem++ = 0x07;
  }

  return 0;
}

void clear_screen(char character, uint8 color) {
  char *vidmem = (char *)VIDEO_ADDRESS;
  while (vidmem <= MAX_LEN) {
    *vidmem++ = character;
    *vidmem++ = color;
  }
}

char* itoa(int val) {
  static char buffer[8];  // Static buffer

  // if (val > 255) return '\0';

  char hexChars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

  buffer[0] = '0';
  buffer[1] = 'x';
  buffer[2] = hexChars[(val & 0xF0000) >> 16];
  buffer[3] = hexChars[(val & 0xF000) >> 12];
  buffer[4] = hexChars[(val & 0xF00) >> 8];
  buffer[5] = hexChars[(val & 0xF0) >> 4];
  buffer[6] = hexChars[val & 0x0F];
  buffer[7] = '\0';

  return buffer;
}
(very messy I know)

The string "test" in the main function will print if it's one character shorter, but QEMU doesn't crash or anything when it's longer.

The full code is available here: https://github.com/TylerSelden/os

Re: I can't print strings longer than ~60 chars?

Posted: Fri May 26, 2023 6:46 am
by Octocontrabass
Your kernel is either being linked or loaded incorrectly. It's the same reason why ordinary strings don't work, but writable array strings do work.

How big is your kernel, exactly?

Which broken tutorial did you copy this code from?

Re: I can't print strings longer than ~60 chars?

Posted: Fri May 26, 2023 6:56 am
by Kaius
Octocontrabass wrote:Your kernel is either being linked or loaded incorrectly. It's the same reason why ordinary strings don't work, but writable array strings do work.

How big is your kernel, exactly?

Which broken tutorial did you copy this code from?
I found one on Github that seemed promising. I'll likely rewrite the bootloader and the makefile using a different tutorial.