1
Lowlevel-Coding / Re: Cursor setzen
« am: 18. May 2007, 13:41 »
Ja da hast du vollkommen recht.
25. November 2024, 06:34
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
jmp Pmode
Pmode:
jmp dword Pmode
Pmode:
mov dx, 0x03d4
mov al, 0x0e
out dx, al
mov dx, 0x03d5
mov al, 0x00
out dx, al
mov dx, 0x03d4
mov al, 0x0f
out dx, al
mov dx, 0x03d5
mov al, 0x00
out dx, al
#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
#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;
}
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
CVideo::getInstance() << "String";
Wird das objekt erzeugt, der String wird dargestellt, aber der Cursor nicht gesetzt. Beim nächsten Aufruf startet er also wieder an der Adresse des Hardware-Cursors, der noch von Bochs stammt.mov eax, cr4
or eax, 0x11
mov cr4, eax
Für die 4MB-Pages, aber das isses nicht oder?
[GLOBAL cursor]
cursor:
push ebp
mov ebp, esp
mov ebx, [ebp + 8]
mov al, 0x0e
mov dx, 0x03d4
out dx, al
mov al, bl
mov dx, 0x03d5
out dx, al
mov al, 0x0f
mov dx, 0x03d4
out dx, al
mov al, bh
mov dx, 0x03d5
out dx, al
leave
ret
[GLOBAL outport]
outport:
push ebp
mov ebp, esp
mov edx, [ebp+8]
mov eax, [ebp+12]
out dx, al
leave
ret
[GLOBAL inport]
inport:
push ebp
mov ebp, esp
mov edx, [ebp+8]
in al, dx
leave
ret
So hab ich sie immer genutzt... Als das auf einmal im C++ Kernel nicht funktioniert hat, hab ich versucht, das so zu machen:unsigned char inport(unsigned short port)
{
unsigned char value;
__asm__ __volatile__ ("inb %1, %0" : "=a"(value) : "d"(port));
return value;
}
void outport(unsigned short port,unsigned char value)
{
__asm__ __volatile__ ("outb %b0,%w1" : : "a"(value), "d"(port));
}
(Gefunden in dem OSD Kernel Paket auf Bona Fide)outport(0x03d4,0x0f);
m_nCursor = inport(0x03d5);
outport(0x03d4,0x0e);
m_nCursor |= inport(0x03d5) << 8;
muss ja funktionieren, da der Cursor richtig ausgelesen wird. Nur nicht richtig gesetzt... Der steht im Konstruktor (weil statische Klasseninstanz), also wird die Variable initialisiert. outport(0x03d4,0x0e);
outport(0x03d5,0x00);
outport(0x03d4,0x0f);
outport(0x03d5,0x00);
geht ja auch nicht... outport(0x03d4,0x0f);
outport(0x03d5,m_nCursor & 0xff);
outport(0x03d4,0x0e);
outport(0x03d5,m_nCursor >> 8);
Oder zumindest sehr ähnlich. Also, dieser Code funktioniert bei mir auf einmal nicht mehr. Zuerst dachte ich, es wäre ein neuer Bug von Bochs. Nein. Es ist auch kein Compilerfehler, hab den Assmblercode überprüft. Ich habe auch die outport Funktion in Assembler und in C geschrieben, kein Unterschied. Ich hab jetzt keine Ahnung was ich hier machen soll, denn der Cursor wird einfach nicht gesetzt. outport(0x03d4,0x0f);
m_nCursor = inport(0x03d5);
outport(0x03d4,0x0e);
m_nCursor |= inport(0x03d5) << 8;
Auch der Versuch, den Cursor auf 0|0 zu setzen, also direkt 0x00 als Positionen zu übergeben, hat nicht funktioniert. [EXTERN main]
[EXTERN __phys_kernel_start__]
[EXTERN __phys_kernel_end__]
[GLOBAL start]
start:
cmp eax, 0x2badb002
je start1
failure:
cli
hlt
start1:
mov eax, multiboot
sub eax, DIFF
mov [eax], ebx
;clear the page directory
mov eax, 0x00200000
mov ecx, 0x1000 / 0x04
.0:
mov dword [eax], 0x02
add eax, 0x04
loop .0
;mirror-map 0x00000000 to 0x00100000
mov eax, 0x00201000
mov ebx, 0x00000000 | 0x03
mov ecx, 0x1000 / 0x04
.1:
mov [eax], ebx
add eax, 0x04
add ebx, 0x1000
loop .1
;mirror-map 0x00100000 to 0x00200000
mov eax, 0x00202000
mov ebx, 0x00100000 | 0x03
mov ecx, 0x1000 / 0x04
.2:
mov [eax], ebx
add eax, 0x04
add ebx, 0x1000
loop .2
;map the kernel
mov eax, 0x00203000
mov ebx, __phys_kernel_start__
or ebx, 0x03
.3:
mov [eax], ebx
add eax, 0x04
add ebx, 0x1000
cmp ebx, __phys_kernel_end__
jle .3
;set the pages
mov dword [0x00200000], 0x00201000 | 0x03
mov dword [0x00200001], 0x00202000 | 0x03
mov dword [0x00200c00], 0x00203000 | 0x03
;set directory
mov eax, 0x00200000
mov cr3, eax
;activate paging
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
lgdt [gdtp]
jmp OS_CODE_SEL:start2
start2:
mov ax, OS_DATA_SEL
mov ds, ax
mov es, ax
mov ss, ax
mov fs, ax
mov gs, ax
mov esp, stack
mov eax, [multiboot]
push eax
call main
add esp, 4
cli
hlt
[SECTION .data]
multiboot dd 0