Removed deprecated VGA API and moved it to /dev/vga.

This commit is contained in:
Jonas 'Sortie' Termansen 2011-11-25 13:38:31 +01:00
parent c0fa3a6aae
commit b6a0fd0374
12 changed files with 163 additions and 331 deletions

View File

@ -6,6 +6,11 @@
#include <libmaxsi/sortix-vga.h>
#include <libmaxsi/sortix-keyboard.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
using namespace Maxsi;
using namespace Maxsi::Keyboard;
@ -16,7 +21,8 @@ const int height = 25;
const int rowstride = width + 2;
const int buffersize = (height+2) * (width+2);
System::VGA::Frame* frame;
int vgafd;
uint16_t frame[width*height];
bool running;
int posx;
@ -33,17 +39,15 @@ void Clear()
for ( int i = 0; i < buffersize; i++ ) { framea[i] = 0; frameb[i] = 0; }
}
bool FlushVGA()
{
return writeall(vgafd, frame, sizeof(frame)) == 0;
}
int Init()
{
// Create a VGA frame we can render onto.
frame = System::VGA::CreateFrame();
if ( frame == NULL )
{
Print("Could not create VGA frame\n");
return -1;
}
System::VGA::ChangeFrame(frame->fd);
vgafd = open("/dev/vga", O_RDWR);
if ( vgafd < 0 ) { printf("Unable to open vga device: %s", strerror(errno)); return 1; }
Clear();
@ -87,7 +91,7 @@ void Cycle()
void Render()
{
uint16_t* dest = frame->text;
uint16_t* dest = frame;
uint16_t set = 'O' | (COLOR8_LIGHT_GREY << 8);
uint16_t unset = ' ' | (COLOR8_LIGHT_GREY << 8);
@ -106,6 +110,8 @@ void Render()
}
}
}
FlushVGA();
}
void Update()

View File

@ -8,6 +8,10 @@
#include <libmaxsi/sortix-sound.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
using namespace Maxsi;
using namespace Maxsi::Keyboard;
@ -29,7 +33,8 @@ const int padsize = 5;
const unsigned goalfreq = 800;
const unsigned collisionfreq = 1200;
System::VGA::Frame* frame;
int vgafd;
uint16_t frame[width*height];
int ballx;
int bally;
@ -48,16 +53,15 @@ unsigned p2score;
unsigned time;
unsigned soundleft;
bool FlushVGA()
{
return writeall(vgafd, frame, sizeof(frame)) == 0;
}
int Init()
{
frame = System::VGA::CreateFrame();
if ( frame == NULL )
{
Print("Could not create VGA frame\n");
return -1;
}
System::VGA::ChangeFrame(frame->fd);
vgafd = open("/dev/vga", O_RDWR);
if ( vgafd < 0 ) { printf("Unable to open vga device: %s", strerror(errno)); return 1; }
Reset();
@ -94,9 +98,11 @@ void ClearScreen()
for ( int x = 0; x < width; x++ )
{
frame->text[x + y*width] = ' ' | color;
frame[x + y*width] = ' ' | color;
}
}
FlushVGA();
}
void Collision()
@ -107,7 +113,7 @@ void Collision()
void Goal(nat player)
{
frame->text[ballx + bally*width] = ' ' | (COLOR8_WHITE << 8);
frame[ballx + bally*width] = ' ' | (COLOR8_WHITE << 8);
int offset = (rand() % 4) - 2;
ballx = width/2;
@ -137,16 +143,16 @@ void Goal(nat player)
void UpdateUI()
{
for ( int x = 0; x < width; x++ ) { frame->text[x] = ' ' | (COLOR8_LIGHT_GREY << 12) | (COLOR8_RED << 8); }
for ( int x = 0; x < width; x++ ) { frame[x] = ' ' | (COLOR8_LIGHT_GREY << 12) | (COLOR8_RED << 8); }
char num[12];
int len;
len = String::ConvertUInt32(p1score, num);
for ( int i = 0; i < len; i++ ) { frame->text[i] = ( frame->text[i] & 0xFF00 ) | num[i]; }
for ( int i = 0; i < len; i++ ) { frame[i] = ( frame[i] & 0xFF00 ) | num[i]; }
len = String::ConvertUInt32(p2score, num);
for ( int i = 0; i < len; i++ ) { frame->text[width - len + i] = ( frame->text[width - len + i] & 0xFF00 ) | num[i]; }
for ( int i = 0; i < len; i++ ) { frame[width - len + i] = ( frame[width - len + i] & 0xFF00 ) | num[i]; }
}
void Update()
@ -163,12 +169,12 @@ void Update()
for ( int y = 1; y < height; y++ )
{
uint16_t color = ( y < p1y || y >= p1y + padsize ) ? COLOR8_BLACK << 12 : COLOR8_RED << 12; frame->text[y*width] = ' ' | color;
uint16_t color = ( y < p1y || y >= p1y + padsize ) ? COLOR8_BLACK << 12 : COLOR8_RED << 12; frame[y*width] = ' ' | color;
}
for ( int y = 1; y < height; y++ )
{
uint16_t color = ( y < p2y || y >= p2y + padsize ) ? COLOR8_BLACK << 12 : COLOR8_BLUE << 12; frame->text[width-1 + y*width] = ' ' | color;
uint16_t color = ( y < p2y || y >= p2y + padsize ) ? COLOR8_BLACK << 12 : COLOR8_BLUE << 12; frame[width-1 + y*width] = ' ' | color;
}
if ( bally + ballvely <= 1 ) { ballvely = 0 - ballvely; Collision(); }
@ -177,14 +183,14 @@ void Update()
if ( ballx + ballvelx < 1 ) { if ( bally + ballvely < p1y - 1 || bally + ballvely > p1y + padsize + 1 ) { Goal(2); } else { ballvelx = 0 - ballvelx; Collision(); } }
if ( ballx + ballvelx >= width-1 ) { if ( bally + ballvely < p2y - 1 || bally + ballvely > p2y + padsize + 1 ) { Goal(1); } else { ballvelx = 0 - ballvelx; Collision(); } }
frame->text[oldballx + oldbally*width] = ' ' | (COLOR8_WHITE << 8);
frame->text[ballx + bally*width] = '.' | (COLOR8_WHITE << 8);
frame[oldballx + oldbally*width] = ' ' | (COLOR8_WHITE << 8);
frame[ballx + bally*width] = '.' | (COLOR8_WHITE << 8);
oldballx = ballx; oldbally = bally;
ballx += ballvelx;
bally += ballvely;
frame->text[ballx + bally*width] = 'o' | (COLOR8_WHITE << 8);
frame[ballx + bally*width] = 'o' | (COLOR8_WHITE << 8);
}
void ReadInput()
@ -236,6 +242,7 @@ int main(int argc, char* argv[])
ReadInput();
Update();
UpdateUI();
FlushVGA();
Thread::USleep(sleepms * 1000);
if ( soundleft < 0 ) { continue; }
if ( soundleft <= 50 )

View File

@ -4,7 +4,12 @@
#include <libmaxsi/keyboard.h>
#include <libmaxsi/sortix-vga.h>
#include <libmaxsi/sortix-keyboard.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
using namespace Maxsi;
using namespace Maxsi::Keyboard;
@ -14,7 +19,8 @@ const int height = 25;
const int buffersize = height * width;
System::VGA::Frame* frame;
int vgafd;
uint16_t frame[width*height];
int posx;
int posy;
@ -40,7 +46,7 @@ volatile int speed;
void Clear()
{
// Reset the game data.
for ( int i = 0; i < buffersize; i++ ) { frame->text[i] = ' '; direction[i] = -1; }
for ( int i = 0; i < buffersize; i++ ) { frame[i] = ' '; direction[i] = -1; }
}
void Reset()
@ -62,22 +68,20 @@ void Reset()
taillen = 0;
tailmax = 3;
frame->text[animaly * width + animalx] = animal;
frame[animaly * width + animalx] = animal;
speed = defaultspeed;
}
bool FlushVGA()
{
return writeall(vgafd, frame, sizeof(frame)) == 0;
}
int Init()
{
// Create a VGA frame we can render onto.
frame = System::VGA::CreateFrame();
if ( frame == NULL )
{
Print("Could not create VGA frame\n");
return -1;
}
System::VGA::ChangeFrame(frame->fd);
vgafd = open("/dev/vga", O_RDWR);
if ( vgafd < 0 ) { printf("Unable to open vga device: %s", strerror(errno)); return 1; }
Reset();
@ -124,7 +128,7 @@ void Update()
// Move the tail, if needed.
if ( taillen == tailmax )
{
frame->text[taily * width + tailx] = ' '; taillen--;
frame[taily * width + tailx] = ' '; taillen--;
switch ( direction[taily * width + tailx] )
{
case 0: tailx--; break;
@ -135,7 +139,7 @@ void Update()
}
// Check for collision.
if ( frame->text[newy * width + newx] == snake ) { Reset(); return; }
if ( frame[newy * width + newx] == snake ) { Reset(); return; }
// Check for food.
if ( newx == animalx && newy == animaly )
@ -148,7 +152,7 @@ void Update()
if ( maxspeed < speed ) { speed += speedincrease; }
}
frame->text[animaly * width + animalx] = animal;
frame[animaly * width + animalx] = animal;
// Remember where we are going.
int dir = 0;
@ -161,7 +165,7 @@ void Update()
// Move the head.
posx = newx;
posy = newy;
frame->text[posy * width + posx] = snake; taillen++;
frame[posy * width + posx] = snake; taillen++;
}
int main(int argc, char* argv[])
@ -174,6 +178,7 @@ int main(int argc, char* argv[])
{
Thread::USleep(speed * 1000);
Update();
FlushVGA();
}
return 0;

View File

@ -50,7 +50,6 @@ c/h/signal.h \
COMMONOBJS=c++.o memory.o string.o error.o format.o
SORTIXOBJS:=$(addprefix sortix/,$(COMMONOBJS))
LIBMAXSIOBJS:=$(COMMONOBJS) \
sortix-vga.o \
sortix-keyboard.o \
sortix-sound.o \
process.o \

View File

@ -47,47 +47,6 @@ namespace System
#define COLOR8_LIGHT_MAGENTA 13
#define COLOR8_LIGHT_BROWN 14
#define COLOR8_WHITE 15
// This is the contents of a VGA framebuffer used in text mode. The
// lower 8 lower bits correspond to an ASCII character, the next 4 bits
// is the text color, and the upper 4 bits are the background color.
struct Frame
{
public:
// The width of each line in characters.
const static size_t width = 80;
// The number of lines.
const static size_t height = 25;
// The data containing the frame.
uint16_t text[width * height];
// An opaque file descriptor that defines this frame. Used to change
// the current frame or deleting frames.
int fd;
// Beware: The kernel may or may keep more hidden data here. You may
// not depend on the usage of this area.
private:
// Only the kernel may create an instance of this structure.
Frame() { }
};
// Allocates a framebuffer able to store VGA data. This buffer is not
// relocatable and must remain at this position.
Frame* CreateFrame();
// Sets the process' current VGA frame. If the process currently have
// focus, then this is the frame shown on the screen. Any edits done
// on this frame while it is active will be shown instantly on the
// screen if the process have focus.
int ChangeFrame(int fd);
// Deletes a frame. This is equivalent to IO::Close(fd).
int DeleteFrame(int fd);
}
}

View File

@ -1,54 +0,0 @@
/******************************************************************************
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
This file is part of LibMaxsi.
LibMaxsi is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
sortix-vga.cpp
Provides access to the VGA framebuffer under Sortix. This is highly
unportable and is very likely to be removed or changed radically.
******************************************************************************/
#include "platform.h"
#include "syscall.h"
#include "sortix-vga.h"
namespace System
{
namespace VGA
{
DEFN_SYSCALL0(Frame*, SysCreateFrame, 5);
DEFN_SYSCALL1(int, SysChangeFrame, 6, int);
DEFN_SYSCALL1(int, SysDeleteFrame, 7, int);
Frame* CreateFrame()
{
return SysCreateFrame();
}
int ChangeFrame(int fd)
{
return SysChangeFrame(fd);
}
int DeleteFrame(int fd)
{
return SysDeleteFrame(fd);
}
}
}

View File

@ -29,6 +29,7 @@
#include "../filesystem.h"
#include "../directory.h"
#include "../stream.h"
#include "../vga.h"
#include "devfs.h"
using namespace Maxsi;
@ -170,8 +171,8 @@ namespace Sortix
int DevDevFSDir::Read(sortix_dirent* dirent, size_t available)
{
const char* names[] = { "null", "tty" };
const size_t nameslength = 2;
const char* names[] = { "null", "tty", "vga" };
const size_t nameslength = 3;
if ( available <= sizeof(sortix_dirent) ) { return -1; }
if ( nameslength <= position )
@ -217,6 +218,7 @@ namespace Sortix
if ( String::Compare(path, "/null") == 0 ) { return new DevNull; }
if ( String::Compare(path, "/tty") == 0 ) { return new DevLogTTY; }
if ( String::Compare(path, "/vga") == 0 ) { return new DevVGA; }
Error::Set(flags & O_CREAT ? EPERM : ENOENT);
return NULL;

View File

@ -96,7 +96,7 @@ namespace Sortix
// TODO: But this hack may be worse.
if ( numvgaframes )
{
UART::RenderVGA((VGA::Frame*) 0xB8000);
UART::RenderVGA((const uint16_t*) 0xB8000);
}
#endif
}
@ -128,7 +128,7 @@ namespace Sortix
{
VGATerminal::Print(NULL, string, stringlen);
#ifdef PLATFORM_SERIAL
UART::RenderVGA((VGA::Frame*) 0xB8000);
UART::RenderVGA((const uint16_t*) 0xB8000);
#endif
}
else

View File

@ -69,7 +69,9 @@ namespace Sortix
const nat BOTH_EMPTY = LSR_TEMT | LSR_THRE;
#ifdef SORTIX_VGA_H
VGA::Frame VGALastFrame;
const unsigned FrameWidth = 80;
const unsigned FrameHeight = 25;
uint16_t VGALastFrame[FrameWidth * FrameHeight];
#endif
nat ProbeBaud(nat Port)
@ -212,25 +214,25 @@ namespace Sortix
void InvalidateVGA()
{
for ( nat I = 0; I < VGALastFrame.Width * VGALastFrame.Height; I++ ) { VGALastFrame.Data[I] = 0; }
for ( nat I = 0; I < FrameWidth * FrameHeight; I++ ) { VGALastFrame[I] = 0; }
}
void RenderVGA(const VGA::Frame* Frame)
void RenderVGA(const uint16_t* Frame)
{
const uint16_t* Source = Frame->Data;
const uint16_t* Source = Frame;
nat LastColor = 1337;
nat SkippedSince = 0;
bool posundefined = true;
for ( nat Y = 0; Y < Frame->Height; Y++)
for ( nat Y = 0; Y < FrameHeight; Y++)
{
for ( nat X = 0; X < Frame->Width; X++ )
for ( nat X = 0; X < FrameWidth; X++ )
{
nat Index = Y * Frame->Width + X;
nat Index = Y * FrameWidth + X;
nat Element = Source[Index];
nat OldElement = VGALastFrame.Data[Index];
nat OldElement = VGALastFrame[Index];
if ( Element == OldElement ) { continue; }
@ -267,7 +269,7 @@ namespace Sortix
for ( nat Pos = SkippedSince; Pos <= Index; Pos++ )
{
Element = Source[Pos];
OldElement = VGALastFrame.Data[Pos];
OldElement = VGALastFrame[Pos];
nat NewColor = (ConversionTable[ (Element >> 12) & 0xF ] << 3) | (ConversionTable[ (Element >> 8) & 0xF ]);
@ -311,7 +313,7 @@ namespace Sortix
LastColor = NewColor;
}
VGALastFrame.Data[Pos] = Element;
VGALastFrame[Pos] = Element;
Element &= 0x7F;

View File

@ -36,7 +36,7 @@ namespace Sortix
int TryPopChar();
#ifdef SORTIX_VGA_H
void InvalidateVGA();
void RenderVGA(const VGA::Frame* Frame = (const VGA::Frame*) 0xB8000);
void RenderVGA(const uint16_t* frame = (const uint16_t*) 0xB8000UL);
#endif
}
}

View File

@ -23,6 +23,7 @@
******************************************************************************/
#include "platform.h"
#include <libmaxsi/error.h>
#include <libmaxsi/memory.h>
#include "vga.h"
#include "memorymanagement.h"
@ -37,29 +38,19 @@ namespace Sortix
{
namespace VGA
{
addr_t SysCreateFrame();
int SysChangeFrame(int fd);
int SysDeleteFrame(int fd);
uint16_t* const vga = (uint16_t* const) 0xB8000;
const int width = 80;
const int height = 80;
DevVGAFrame* currentframe;
byte* const VGA = (byte* const) 0xB8000;
const unsigned WIDTH = 80;
const unsigned HEIGHT = 25;
const size_t VGA_SIZE = sizeof(uint16_t) * WIDTH * HEIGHT;
void Init()
{
currentframe = NULL;
Syscall::Register(SYSCALL_CREATE_FRAME, (void*) SysCreateFrame);
Syscall::Register(SYSCALL_CHANGE_FRAME, (void*) SysChangeFrame);
Syscall::Register(SYSCALL_DELETE_FRAME, (void*) SysDeleteFrame);
}
// Changes the position of the hardware cursor.
void SetCursor(nat x, nat y)
{
nat value = x + y * width;
nat value = x + y * WIDTH;
// This sends a command to indicies 14 and 15 in the
// CRT Control Register of the VGA controller. These
@ -69,149 +60,71 @@ namespace Sortix
CPU::OutPortB(0x3D5, (value >> 8) & 0xFF);
CPU::OutPortB(0x3D4, 15);
CPU::OutPortB(0x3D5, (value >> 0) & 0xFF);
}
addr_t SysCreateFrame()
{
addr_t page = Page::Get();
if ( !page ) { return 0; }
Process* process = CurrentProcess();
addr_t mapto = process->AllocVirtualAddr(0x1000UL);
UserFrame* userframe = (UserFrame*) mapto;
// TODO: Check if mapto collides with any other memory section!
if ( !Memory::MapUser(page, mapto) )
{
Page::Put(page); return 0;
}
Maxsi::Memory::Set(userframe, 0, sizeof(UserFrame));
DevVGAFrame* frame = new DevVGAFrame();
if ( frame == NULL )
{
Memory::UnmapUser(mapto);
Page::Put(page); return 0;
}
int fd = process->descriptors.Allocate(frame);
if ( fd < 0 )
{
delete frame;
Memory::UnmapUser(mapto);
Page::Put(page); return 0;
}
userframe->fd = fd;
frame->process = process;
frame->physical = page;
frame->userframe = userframe;
return mapto;
}
int SysChangeFrame(int fd)
{
Process* process = CurrentProcess();
Device* device = process->descriptors.Get(fd);
if ( !device ) { return -1; }
if ( !device->IsType(Device::VGABUFFER) ) { return -2; }
DevVGAFrame* frame = (DevVGAFrame*) device;
ASSERT(frame->process == process);
ASSERT(frame->physical != 0);
ASSERT(frame->userframe != NULL);
ASSERT(frame->onscreen == (frame == currentframe));
// TODO: Check if userframe is actually user-space writable!
// Check if we need to do anything.
if ( frame == currentframe ) { return 0; }
// If there is already a currently used frame? If so, swap it from
// the VGA memory and back to the RAM. This should be done
// transparently such that the program doesn't feel the difference.
if ( currentframe != NULL )
{
ASSERT(currentframe->physical != frame->physical);
ASSERT(currentframe->userframe != frame->userframe);
ASSERT(currentframe->onscreen == true);
if ( currentframe->process != process )
{
Memory::SwitchAddressSpace(currentframe->process->addrspace);
}
// Remap the pages in the owning process.
// TODO: Check if userframe is actually user-space writable!
Memory::UnmapUser((addr_t) currentframe->userframe);
Memory::MapUser(currentframe->physical, (addr_t) currentframe->userframe);
Memory::InvalidatePage((addr_t) frame->userframe);
// Restore the contents of this frame to the VGA framebuffer.
Maxsi::Memory::Copy(currentframe->userframe, vga, sizeof(UserFrame));
if ( currentframe->process != process )
{
Memory::SwitchAddressSpace(process->addrspace);
}
currentframe->onscreen = false;
}
// Now move the contents of this frame to the VGA framebuffer.
Maxsi::Memory::Copy(vga, frame->userframe, sizeof(UserFrame));
// Remap the pages such that the current process now uses the vga.
Memory::UnmapUser((addr_t) frame->userframe);
Memory::MapUser((addr_t) vga, (addr_t) frame->userframe);
Memory::InvalidatePage((addr_t) frame->userframe);
frame->onscreen = true;
currentframe = frame;
SetCursor(width, height-1);
return 0;
}
int SysDeleteFrame(int fd)
{
Process* process = CurrentProcess();
Device* device = process->descriptors.Get(fd);
process->descriptors.Free(fd);
if ( device == NULL ) { return -1; }
device->Unref();
return 0;
}
}
}
DevVGAFrame::DevVGAFrame()
DevVGA::DevVGA()
{
process = NULL;
userframe = NULL;
physical = 0;
onscreen = false;
SerialTerminal::OnVGAFrameCreated();
offset = 0;
}
DevVGAFrame::~DevVGAFrame()
DevVGA::~DevVGA()
{
SerialTerminal::OnVGAFrameDeleted();
if ( process != NULL ) { ASSERT(CurrentProcess() == process); }
if ( userframe != NULL ) { Memory::UnmapUser((addr_t) userframe); Memory::InvalidatePage((addr_t) userframe); }
if ( physical != 0 ) { Page::Put(physical); }
if ( VGA::currentframe == this ) { VGA::currentframe = NULL; }
}
bool DevVGAFrame::IsType(unsigned type)
ssize_t DevVGA::Read(byte* dest, size_t count)
{
return type == Device::VGABUFFER;
if ( VGA::VGA_SIZE - offset < count ) { count = VGA::VGA_SIZE - offset; }
Maxsi::Memory::Copy(dest, VGA::VGA + offset, count);
offset += count;
return count;
}
ssize_t DevVGA::Write(const byte* src, size_t count)
{
if ( offset == VGA::VGA_SIZE && count ) { Error::Set(ENOSPC); return -1; }
if ( VGA::VGA_SIZE - offset < count ) { count = VGA::VGA_SIZE - offset; }
Maxsi::Memory::Copy(VGA::VGA + offset, src, count);
offset = (offset + count) % VGA::VGA_SIZE;
return count;
}
bool DevVGA::IsReadable()
{
return true;
}
bool DevVGA::IsWritable()
{
return true;
}
size_t DevVGA::BlockSize()
{
return 1;
}
uintmax_t DevVGA::Size()
{
return VGA::VGA_SIZE;
}
uintmax_t DevVGA::Position()
{
return offset;
}
bool DevVGA::Seek(uintmax_t position)
{
if ( VGA::VGA_SIZE < position ) { Error::Set(EINVAL); return false; }
offset = position;
return true;
}
bool DevVGA::Resize(uintmax_t size)
{
if ( size == VGA::VGA_SIZE ) { return false; }
Error::Set(ENOSPC);
return false;
}
}

View File

@ -26,11 +26,10 @@
#define SORTIX_VGA_H
#include "device.h"
#include "stream.h"
namespace Sortix
{
class Process;
namespace VGA
{
// TODO: Move these to a better place
@ -51,38 +50,32 @@ namespace Sortix
#define COLOR8_LIGHT_BROWN 14
#define COLOR8_WHITE 15
struct Frame
{
static const nat Mode = 0x3;
static const size_t Width = 80;
static const size_t Height = 25;
uint16_t Data[80*25];
};
struct UserFrame : public Frame
{
int fd;
};
void Init();
void SetCursor(nat x, nat y);
}
class DevVGAFrame : public Device
class DevVGA : public DevBuffer
{
public:
DevVGAFrame();
~DevVGAFrame();
typedef DevBuffer BaseClass;
public:
virtual bool IsType(unsigned type);
DevVGA();
virtual ~DevVGA();
private:
size_t offset;
public:
Process* process;
addr_t physical;
VGA::UserFrame* userframe;
bool onscreen;
virtual ssize_t Read(byte* dest, size_t count);
virtual ssize_t Write(const byte* src, size_t count);
virtual bool IsReadable();
virtual bool IsWritable();
virtual size_t BlockSize();
virtual uintmax_t Size();
virtual uintmax_t Position();
virtual bool Seek(uintmax_t position);
virtual bool Resize(uintmax_t size);
};
}