Ja na gut... die Sache mit dem Singleton ist ja aus dem Game-Bereich übernommen, als ich noch so was gemacht hab... da hat es Größtenteils geklappt.
Hier die video.h (der relevante Teil jedenfalls)
#ifndef __VIDEO_H__
#define __VIDEO_H__
class CVideo
{
protected:
void putc(char c);
void putnum(int num);
void scroll();
void update_cursor();
CVideo();
unsigned short *m_pVideoMem;
unsigned char m_nColour;
unsigned short m_nCursor;
static CVideo m_Instance;
public:
static CVideo getInstance();
CVideo &operator << (const char c);
CVideo &operator << (const char *str);
CVideo &operator << (const int num);
void setColour(unsigned char colour);
void cls();
};
#endif
Und die Implementation, video.cpp (diesmal fast alles):
#include <system.h>
#include <video.h>
extern "C" void cursor(unsigned short crs);
const int COLS = 80;
const int ROWS = 25;
CVideo CVideo::m_Instance = CVideo();
CVideo::CVideo()
{
m_pVideoMem = (unsigned short*)(0xb8000);
m_nColour = 0x07;
outport(0x03d4,0x0f);
m_nCursor = inport(0x03d5);
outport(0x03d4,0x0e);
m_nCursor |= inport(0x03d5) << 8;
}
CVideo CVideo::getInstance()
{
return m_Instance;
}
void CVideo::putc(char c)
{
if(c == '\n')
{
m_nCursor = (m_nCursor + COLS) & ~(COLS - 1);
}
else if(c == '\b')
{
if(m_nCursor > 0) m_nCursor--;
}
else if(c == '\t')
{
m_nCursor = (m_nCursor + 8) & ~(8-1);
}
else if(c >= 0x20)
{
m_pVideoMem[m_nCursor] = c | m_nColour << 8;
m_nCursor++;
}
scroll();
update_cursor();
}
void CVideo::putnum(int num)
{
char tmp[8];
int i = 0;
if (num == 0) putc('0');
else
{
while (num > 0)
{
int j = num % 0x10;
if(j < 10) tmp[i++] = '0' + j;
else
{
j -= 10;
tmp[i++] = 'A' + j;
}
num /= 0x10;
}
while (i-- > 0)
{
putc(tmp[i]);
}
}
}
void CVideo::scroll()
{
if(m_nCursor >= (COLS * ROWS))
{
memcpy(m_pVideoMem,&m_pVideoMem[COLS],COLS * (ROWS-1));
memsetw(&m_pVideoMem[COLS * (ROWS-1)],0,COLS);
m_nCursor = COLS * (ROWS-1);
}
}
void CVideo::update_cursor()
{
outport(0x03d4,0x0f);
outport(0x03d5,m_nCursor & 0xff);
outport(0x03d4,0x0e);
outport(0x03d5,m_nCursor >> 8);
}
void CVideo::cls()
{
memsetw(m_pVideoMem,0,COLS*ROWS);
outport(0x03d4,0x0f);
outport(0x03d5,0x00);
outport(0x03d4,0x0e);
outport(0x03d5,0x00);
}
void CVideo::setColour(unsigned char colour)
{
m_nColour = colour;
}
CVideo &CVideo::operator <<(const char c)
{
putc(c);
return *this;
}
CVideo &CVideo::operator <<(const char *str)
{
while(*str != '\0') putc(*str++);
return *this;
}
CVideo &CVideo::operator <<(const int num)
{
putnum(num);
return *this;
}
Dazu noch der Assemblerteil für die Konstruktoren:
extern __ctors_start__, __ctors_end__, __dtors_start__, __dtors_end__
; call the constructors
static_ctors_loop:
mov ebx, __ctors_start__
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, __ctors_end__
jb .body
sti
; call kernel proper
mov eax, [multiboot]
push eax
call main
add esp, 4
; call the destructors
static_dtors_loop:
mov ebx, __dtors_start__
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, __dtors_end__
jb .body
cli
hlt
Das war's so weit...