Asuro/src/driver/video/video.pas

141 lines
4.5 KiB
ObjectPascal

unit video;
interface
uses
multiboot, lmemorymanager, tracer, color, rand, console;
procedure init();
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
procedure Flush();
type
VideoBuffer = uint64;
TVESALinearBuffer = record
Initialized : Boolean;
Location : VideoBuffer;
BitsPerPixel : uint8;
Width : uint32;
Height : uint32;
end;
TBackBuffer = record
Initialized : Boolean;
Location : VideoBuffer;
BitsPerPixel : uint8;
Width : uint32;
Height : uint32;
end;
TVESA = record
DefaultBuffer : VideoBuffer;
Framebuffer : TVESALinearBuffer;
BackBuffer : TBackBuffer;
end;
PVESA = ^TVESA;
implementation
var
VESA : TVESA;
function allocateBackBuffer(Width : uint32; Height : uint32; BitsPerPixel : uint8) : uint64;
begin
Outputln('VIDEO','Start Kalloc Backbuffer');
//This doesn't currently work... Needs a rework of lmemorymanager
allocateBackBuffer:= uint64(klalloc((Width * Height) * BitsPerPixel));
Outputln('VIDEO','End Kalloc Backbuffer');
end;
procedure initBackBuffer(VESAInfo : PVESA; Width : uint32; Height : uint32; BitsPerPixel : uint8);
begin
VESAInfo^.BackBuffer.Width:= Width;
VESAInfo^.BackBuffer.Height:= Height;
VESAInfo^.BackBuffer.BitsPerPixel:= BitsPerPixel;
VESAInfo^.BackBuffer.Location:= allocateBackBuffer(VESAInfo^.BackBuffer.Width, VESAInfo^.BackBuffer.Height, VESAInfo^.BackBuffer.BitsPerPixel);
VESAInfo^.DefaultBuffer:= VESAInfo^.BackBuffer.Location;
VESAInfo^.BackBuffer.Initialized:= True;
end;
procedure allocateVESAFrameBuffer(Address : uint32; Width : uint32; Height : uint32);
var
LowerAddress, UpperAddress : uint32;
Block : uint32;
begin
tracer.push_trace('video.allocateFrameBuffer.enter');
LowerAddress:= ((Address) SHR 22)-1;
UpperAddress:= ((Address + (Width * Height)) SHR 22)+1;
For Block:=LowerAddress to UpperAddress do begin
kpalloc(Block SHL 22);
end;
tracer.push_trace('video.allocateFrameBuffer.enter');
end;
procedure initVESAFrameBuffer(VESAInfo : PVESA; Location : uint64; Width : uint32; Height : uint32; BitsPerPixel : uint8);
begin
if not(VESAInfo^.Framebuffer.Initialized) then begin
VESAInfo^.Framebuffer.Location:= Location;
VESAInfo^.Framebuffer.BitsPerPixel:= BitsPerPixel;
VESAInfo^.Framebuffer.Width:= Width;
VESAInfo^.Framebuffer.Height:= Height;
allocateVESAFrameBuffer(VESAInfo^.Framebuffer.Location, VESAInfo^.Framebuffer.Width, VESAInfo^.Framebuffer.Height);
VESAInfo^.DefaultBuffer:= VESAInfo^.Framebuffer.Location;
VESAInfo^.Framebuffer.Initialized:= True;
end;
end;
procedure init();
var
RGB : TRGB32;
x,y : uint32;
begin
tracer.push_trace('video.init.enter');
console.Outputln('VIDEO', 'Init VESA Framebuffer');
initVESAFrameBuffer(@VESA, multiboot.multibootinfo^.framebuffer_addr, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp);
console.Outputln('VIDEO', 'Init VESA Backbuffer');
initBackBuffer(@VESA, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp);
console.Outputln('VIDEO', 'Start Test Draw Loop');
srand(98354754397);
while true do begin
Inc(RGB.R);
for x:=0 to VESA.Framebuffer.Width-1 do begin
Inc(RGB.G);
for y:=0 to VESA.Framebuffer.Height-1 do begin
DrawPixel(x,y,RGB);
Inc(RGB.B);
end;
end;
Flush();
end;
tracer.push_trace('video.init.exit');
end;
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
var
Location : PuInt32;
LocationIndex : Uint32;
begin
Location:= Puint32(VESA.DefaultBuffer);
LocationIndex:= (Y * VESA.Framebuffer.Width) + X;
Location[LocationIndex]:= uint32(Pixel);
end;
procedure Flush();
var
x,y : uint32;
Back,Front : PuInt64;
begin
if not(VESA.BackBuffer.Initialized) then exit;
Back:= PUint64(VESA.BackBuffer.Location);
Front:= PuInt64(VESA.Framebuffer.Location);
for x:=0 to (VESA.Framebuffer.Width-1) div 2 do begin
for y:=0 to (VESA.Framebuffer.Height-1) div 2 do begin
Front[(Y * VESA.Framebuffer.Width)+X]:= Back[(Y * VESA.Framebuffer.Width)+X];
end;
end;
end;
end.