// kio.c // Author: Josh Holtrop // Created: 12/25/03 // Modified: 04/06/04 #include "hos_defines.h" #include "kio.h" #include "asmfuncs.h" #include "video/video.h" dword cursorPosition; //Caches the current cursor position word console_memory[2000]; //holds a copy of the console's memory // This is the main output routine, it uses a format string and a variable // number of arguments to print formatted text extern "C" { void kio_init() { cursorPosition = 0; writeCursorPosition(0); word *vidmem = (word *)0xC00B8000; for (int i = 0; i < 2000; i++) { console_memory[i] = 0x0720; vidmem[i] = 0x0720; } } void printf(char *fmt, ...) { dword *params = ((dword *)(&fmt)) + 1; //points to the first paramater int i; int special = 0; for (i = 0; ; i++) { if (special) { special = 0; switch (fmt[i]) { case 0: return; case '%': putc('%'); break; case 's': case 'S': puts((char *)*params); params++; break; case 'c': case 'C': putc(*params); params++; break; case 'd': case 'D': case 'i': case 'I': putDec(*params); params++; break; case 'u': case 'U': putDecu(*params); params++; break; case 'x': case 'X': putHex(*params); params++; break; case 'b': case 'B': kio_putBCD(*params); params++; break; } } else { switch (fmt[i]) { case '%': special = 1; break; case 0: return; default: putc(fmt[i]); } } } } // This function draws a single character void putc(dword chr) { char charac = (char)chr; word *vidmem = (word *)0xC00B8000; if (charac == '\n') { if (cursorPosition % 80) cursorPosition = cursorPosition + 80 - (cursorPosition % 80); else cursorPosition += 80; } else if (charac == '\t') { if (cursorPosition % 8) cursorPosition = cursorPosition + 8 - (cursorPosition % 8); else cursorPosition += 8; } else { if (video_Mode()) { console_memory[cursorPosition] = charac | 0x0700; kio_drawConsoleChar(cursorPosition); } else { console_memory[cursorPosition] = charac | 0x0700; vidmem[cursorPosition] = charac | 0x0700; } cursorPosition++; } if (cursorPosition >= 2000) { kio_console_scroll(); cursorPosition = 2000-80; } if (!video_Mode()) writeCursorPosition(cursorPosition); } // This function displays a number in hexadecimal void putHex(dword number) { int hitNum = 0; int i; for (i = 7; i >= 0; i--) { dword val = (number >> (i*4)) & 0xF; if ((val != 0) || (i == 0)) hitNum = 1; if (hitNum) { val = val + '0'; if (val > '9') val = val + ('A' - '9' - 1); putc(val); } } } void kio_putBCD(dword bcd) { putc(((bcd & 0xF0) >> 4) + '0'); putc((bcd & 0xF) + '0'); } void kio_console_scroll() { memcpyd(console_memory, console_memory + 80, 960); memsetw(console_memory + 1920, 0x0720, 80); if (video_Mode()) kio_drawConsole(); else memcpyd((void *)0xC00B8000, console_memory, 1000); } void kio_console_cls() { memsetw(console_memory, 0x0720, 2000); if (video_Mode()) kio_drawConsole(); else memcpyd((void *)0xC00B8000, console_memory, 1000); writeCursorPosition(0); } // This function draws a simple "console" window in graphical mode to display text void kio_drawConsole() { video_rectf(8, 8, 491, 261, 0); video_rect(7, 7, 492, 262, 0x00777777); int x, y; x = 250, y = 135; int s = 100, p = 0; for (p = 0; p <= s; p += 16) { video_line(x + p, y, x, y + s - p, 0x00008800); video_line(x + p, y, x, y - s + p, 0x00008800); video_line(x - p, y, x, y + s - p, 0x00008800); video_line(x - p, y, x, y - s + p, 0x00008800); } for (x = 0; x < 80; x++) { for (y = 0; y < 25; y++) { video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0, 0x00FFFFFF, 0, 0); } } } // This function draws a "console" character to the graphical video screen void kio_drawConsoleChar(dword position) { int x = position % 80; int y = position / 80; video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0, 0x00FFFFFF, 1, 0); } dword kio_getCursorPosition() { return cursorPosition; } void kio_writeCursorPosition(dword position) { cursorPosition = position; writeCursorPosition(position); } }