//----------------------------------------------------------------------------// // GNU GPL OS/K // // // // Desc: VGA terminal functions // // // // // // Copyright © 2018-2019 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K 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 General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #include #include #include // // VGA-related macros // #define VGA_ComputeColorCode(fg, bg) ((fg) | (bg) << 4) #define VGA_ComputeOffset(term, x, y) ((y) * (term)->width + (x)) #define VGA_ComputeEntry(ch, cl) (((ushort)(ch)) | (ushort)(cl) << 8) static uint bscroll = 0; // // VGA Buffer Flusher // error_t bvgaflusher(Buffer_t *buf) { ushort *fbp = BtVideoInfo.framebufferAddr; uchar color = 0xf; uchar *currentLine = buf->wp - buf->lastLF; uchar *bufStart = (uchar *)lmax((size_t)buf->buf, (size_t)currentLine - (buf->nLines - 1 + bscroll) * buf->lineLen); uchar *ptr = bufStart; // Writes the buffer's content for (; ptr < buf->wp ; ptr++) { *fbp++ = VGA_ComputeEntry(*ptr, color); } // Update the cursor size_t curX = ((size_t)ptr - (size_t)bufStart) % buf->lineLen; size_t curY = ((size_t)ptr - (size_t)bufStart) / buf->lineLen; IoUpdateCursor(curX, curY); // Empty the rest of the buffer const size_t bufSize = buf->nLines * buf->lineLen; ushort *fbe = BtVideoInfo.framebufferAddr + (bufSize * sizeof(ushort)); if (fbp < fbe) { const ushort filler = VGA_ComputeEntry(' ', color); while (fbp < fbe) *fbp++ = filler; } return EOK; } void IoScrollDown(void) { if (bscroll > 0) bscroll--; bvgaflusher(BStdOut); } void IoScrollUp(void) { BLockBuf(BStdOut); uchar *currentLine = BStdOut->wp - BStdOut->lastLF; assert(currentLine >= BStdOut->buf); // Scrollable lines uint scrabble = max(0, (currentLine-BStdOut->buf)/BStdOut->lineLen - BStdOut->nLines + 1); if (bscroll < scrabble) bscroll++; bvgaflusher(BStdOut); BUnlockBuf(BStdOut); } // // Initialize VGA buffer // error_t IoInitVGABuffer(void) { static char bvgabufsrc[1 * MB]; static Buffer_t bvgabufstruct; BStdOut = &bvgabufstruct; BOpenTermBufEx(&BStdOut, bvgabufsrc, BS_WRONLY, BtVideoInfo.framebufferWidth, BtVideoInfo.framebufferHeight, 10, bvgaflusher); BEnableAutoScroll(BStdOut); BStdDbg = BStdOut; return EOK; }