( bkerndev tutorial + De Deyn Kim tutorial ) = wrong output
Posted: Thu Jun 05, 2008 1:35 am
After reading both tutorials, I decided to combine them. As the implementation language, I use Pascal with FreePascal as the compiler. I make everything from scratch, except for the stub.asm and I choose the better implementation (at least IMO) between both for some functions. However, the output under Qemu doesn't seem correct. The screen doesn't get cleared and no message is printed. I'll provide both code and other functions they call:
The kernel code only calls ClearScreen, WriteStr('Hello, World'), and finally an infinite loop. If you want to check yourself, please download the attachment. I've made a build.bat script to make building easier, please notice that some things might need to be set (i.e. my ld is named i386-linux-ld because it's a cross linker).
Code: Select all
var
VidMem: PChar;
CursorPosX,CursorPosY: Integer;
Attrib: Integer;
Blank: Word;
...
procedure Move(Src,Dest: Pointer; Count: Word);
var
sp,dp: PByte;
begin
//{
// Assembler way
asm
mov esi,Src
mov edi,Dest
mov ecx,Count
rep movsb
end;
//}
{
// Pascal way
sp:=PByte(Src);
dp:=PByte(Dest);
while Count>0 do begin
dp^:=sp^;
Inc(dp);
Inc(sp);
Dec(Count);
end;
}
end;
procedure FillWord(Dest: Pointer; const W: Word; Count: Word);
var
dp: PWord;
begin
dp:=PWord(Dest);
while Count>0 do begin
dp^:=W;
Inc(dp);
Dec(Count);
end;
end;
procedure WritePort(Port: LongInt; Value: Byte);
begin
asm
mov edx,port
mov al,value
out dx,al
end ['EAX','EDX'];
end;
procedure Scroll;
var
temp: Word;
dest: PChar;
begin
if CursorPosY>=25 then begin
temp:=CursorPosY-26;
dest:=VidMem+temp*80;
Move(VidMem,dest,(25-temp)*160);
dest:=VidMem+(25-temp)*80;
FillWord(dest,Blank,80);
CursorPosY:=24;
end;
end;
procedure MoveCursor;
var
temp: Word;
begin
temp:=CursorPosY*80+CursorPosX;
WritePort($3D4,14);
WritePort($3D5,temp shr 8);
WritePort($3D4,15);
WritePort($3D5,temp);
end;
procedure ClearScreen;
var
i: Word;
begin
for i:=0 to 3999 do
VidMem[i]:=#0;
CursorPosX:=0;
CursorPosY:=0;
MoveCursor;
end;
procedure WriteChr(const c: Char);
var
offset: Word;
begin
case c of
#08: if CursorPosX<>0 then Dec(CursorPosX);
#09: Inc(CursorPosX,8);
#13: CursorPosX:=0;
#10: Inc(CursorPosY);
#32..#255: begin
offset:=(CursorPosX shl 1)+(CursorPosY*160);
VidMem[offset]:=c;
Inc(offset);
VidMem[offset]:=Char(Attrib shl 8);
Inc(CursorPosX);
end;
end;
if CursorPosX>=80 then begin
CursorPosX:=0;
Inc(CursorPosY);
end;
Scroll;
MoveCursor;
end;
procedure WriteStr(const P: PChar);
var
i: LongWord;
begin
i:=0;
while P[i]<>#0 do
WriteChr(P[i]);
end;
...
initialization
VidMem:=PChar($b8000);
CursorPosX:=0;
CursorPosY:=0;
Attrib:=$0F;
Blank:=$20 or (Attrib shl 8);
...