diff --git a/games/conway.cpp b/games/conway.cpp index 98d95d44..2fdc61f7 100644 --- a/games/conway.cpp +++ b/games/conway.cpp @@ -6,6 +6,11 @@ #include #include #include +#include +#include +#include +#include +#include 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() diff --git a/games/pong.cpp b/games/pong.cpp index d34ff3ba..f0c9cb28 100644 --- a/games/pong.cpp +++ b/games/pong.cpp @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include +#include 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 ) diff --git a/games/snake.cpp b/games/snake.cpp index bea1690e..de5eab0b 100644 --- a/games/snake.cpp +++ b/games/snake.cpp @@ -4,7 +4,12 @@ #include #include #include +#include #include +#include +#include +#include +#include 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; diff --git a/libmaxsi/Makefile b/libmaxsi/Makefile index c3beaa4f..9e241ce2 100644 --- a/libmaxsi/Makefile +++ b/libmaxsi/Makefile @@ -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 \ diff --git a/libmaxsi/hsrc/sortix-vga.h b/libmaxsi/hsrc/sortix-vga.h index ad2d00cc..8d5daa6d 100644 --- a/libmaxsi/hsrc/sortix-vga.h +++ b/libmaxsi/hsrc/sortix-vga.h @@ -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); } } diff --git a/libmaxsi/sortix-vga.cpp b/libmaxsi/sortix-vga.cpp deleted file mode 100644 index 292d3745..00000000 --- a/libmaxsi/sortix-vga.cpp +++ /dev/null @@ -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 . - - 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); - } - } -} diff --git a/sortix/fs/devfs.cpp b/sortix/fs/devfs.cpp index 9204032c..b06401ab 100644 --- a/sortix/fs/devfs.cpp +++ b/sortix/fs/devfs.cpp @@ -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; diff --git a/sortix/serialterminal.cpp b/sortix/serialterminal.cpp index 42ac91dc..67dad3be 100644 --- a/sortix/serialterminal.cpp +++ b/sortix/serialterminal.cpp @@ -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 diff --git a/sortix/uart.cpp b/sortix/uart.cpp index c950070a..37ff10ab 100644 --- a/sortix/uart.cpp +++ b/sortix/uart.cpp @@ -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; diff --git a/sortix/uart.h b/sortix/uart.h index 28cfe228..4984e4e4 100644 --- a/sortix/uart.h +++ b/sortix/uart.h @@ -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 } } diff --git a/sortix/vga.cpp b/sortix/vga.cpp index 9de757e3..a069c714 100644 --- a/sortix/vga.cpp +++ b/sortix/vga.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "platform.h" +#include #include #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; } } diff --git a/sortix/vga.h b/sortix/vga.h index a00dded6..18b6c830 100644 --- a/sortix/vga.h +++ b/sortix/vga.h @@ -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); }; }