The Pedigree Project  0.1
kernel/machine/mach_pc/Vga.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "Vga.h"
21 #include "pedigree/kernel/machine/x86_common/Bios.h"
22 #include "pedigree/kernel/processor/PhysicalMemoryManager.h"
23 #include "pedigree/kernel/processor/VirtualAddressSpace.h"
24 #include "pedigree/kernel/utilities/utility.h"
25 
26 X86Vga::X86Vga(uint32_t nRegisterBase, uint32_t nFramebufferBase)
27  : m_RegisterPort("VGA controller"), m_Framebuffer("VGA framebuffer"),
28  m_pFramebuffer(reinterpret_cast<uint8_t *>(nFramebufferBase)),
29  m_nWidth(80), m_nHeight(25), m_ModeStack(0), m_nMode(3), m_nControls(0)
30 {
31 }
32 
33 X86Vga::~X86Vga()
34 {
35 }
36 
37 uint8_t X86Vga::getControls()
38 {
39  // Go into index state.
40  m_RegisterPort.read8(VGA_INSTAT_READ);
41 
42  // Get current.
43  m_RegisterPort.write8(VGA_REG_ATTR_MODE_CTL | VGA_PAS, VGA_AC_INDEX);
44  return m_RegisterPort.read8(VGA_AC_READ);
45 }
46 
47 void X86Vga::setControls(uint8_t newControls)
48 {
49  m_nControls = newControls;
50 
51  // Ensure we are in index state again.
52  m_RegisterPort.read8(VGA_INSTAT_READ);
53 
54  // Set!
55  m_RegisterPort.write8(VGA_REG_ATTR_MODE_CTL | VGA_PAS, VGA_AC_INDEX);
56  m_RegisterPort.write8(m_nControls, VGA_AC_WRITE);
57 }
58 
59 void X86Vga::setControl(Vga::VgaControl which)
60 {
61  uint8_t current = getControls();
62  current |= 1 << static_cast<uint8_t>(which);
63  setControls(current);
64 }
65 
66 void X86Vga::clearControl(Vga::VgaControl which)
67 {
68  uint8_t current = getControls();
69  current &= ~(1 << static_cast<uint8_t>(which));
70  setControls(current);
71 }
72 
73 bool X86Vga::setMode(int mode)
74 {
75  m_nMode = mode;
76  return true;
77 }
78 
80 {
81  return true;
82 }
83 
84 bool X86Vga::isMode(size_t nCols, size_t nRows, bool bIsText, size_t nBpp)
85 {
86  return false;
87 }
88 
90 {
91  return true;
92 }
93 
95 {
96  m_ModeStack++;
97 
98  if (m_ModeStack == 1)
99  {
100  // SET SuperVGA VIDEO MODE - AX=4F02h, BX=new mode
101  Bios::instance().setAx(0x4F02);
102  Bios::instance().setBx(3);
103  Bios::instance().setEs(0x0000);
104  Bios::instance().setDi(0x0000);
106 
107  setControls(m_nControls);
108  }
109 }
110 
112 {
113  if (m_ModeStack == 0)
114  return;
115  m_ModeStack--;
116 
117  if (m_ModeStack == 0 && m_nMode != 3)
118  {
119  // SET SuperVGA VIDEO MODE - AX=4F02h, BX=new mode
120  Bios::instance().setAx(0x4F02);
122  Bios::instance().setEs(0x0000);
123  Bios::instance().setDi(0x0000);
125 
126  setControls(m_nControls);
127  }
128 }
129 
130 void X86Vga::pokeBuffer(uint8_t *pBuffer, size_t nBufLen)
131 {
132  if (!pBuffer)
133  return;
134  if (m_Framebuffer == true)
135  MemoryCopy(m_Framebuffer.virtualAddress(), pBuffer, nBufLen);
136  else
137  MemoryCopy(m_pFramebuffer, pBuffer, nBufLen);
138 }
139 
140 void X86Vga::peekBuffer(uint8_t *pBuffer, size_t nBufLen)
141 {
142  if (m_Framebuffer == true)
143  MemoryCopy(pBuffer, m_Framebuffer.virtualAddress(), nBufLen);
144  else
145  MemoryCopy(pBuffer, m_pFramebuffer, nBufLen);
146 }
147 
148 void X86Vga::moveCursor(size_t nX, size_t nY)
149 {
150  if (!m_RegisterPort)
151  return;
152 
153  uint16_t tmp = nY * m_nWidth + nX;
154 
155  m_RegisterPort.write8(14, VGA_CRTC_INDEX);
156  m_RegisterPort.write8(tmp >> 8, VGA_CRTC_DATA);
157  m_RegisterPort.write8(15, VGA_CRTC_INDEX);
158  m_RegisterPort.write8(tmp, VGA_CRTC_DATA);
159 }
160 
161 bool X86Vga::initialise()
162 {
163  // TODO: We should allocate the value passed to the constructor
164  if (m_RegisterPort.allocate(VGA_BASE, 0x1B) == false)
165  return false;
166 
167  // Allocate the Video RAM
168  PhysicalMemoryManager &physicalMemoryManager =
170  bool result = physicalMemoryManager.allocateRegion(
171  m_Framebuffer, 2,
175  reinterpret_cast<uintptr_t>(m_pFramebuffer));
176  m_nControls = getControls();
177 
178  return result;
179 }
virtual void restoreMode()
virtual void peekBuffer(uint8_t *pBuffer, size_t nBufLen)
static PhysicalMemoryManager & instance()
virtual void moveCursor(size_t nX, size_t nY)
virtual void pokeBuffer(uint8_t *pBuffer, size_t nBufLen)
virtual void clearControl(VgaControl which)
void setAx(int n)
Definition: Bios.cc:211
void executeInterrupt(int interrupt)
Definition: Bios.cc:172
static Bios & instance()
Definition: Bios.h:32
void setBx(int n)
Definition: Bios.cc:215
virtual bool isMode(size_t nCols, size_t nRows, bool bIsText, size_t nBpp=0)
virtual bool isLargestTextMode()
virtual void setControl(VgaControl which)
virtual bool setMode(int mode)
virtual bool allocateRegion(MemoryRegion &Region, size_t cPages, size_t pageConstraints, size_t Flags, physical_uintptr_t start=-1)=0
virtual bool setLargestTextMode()
void setDi(int n)
Definition: Bios.cc:227
virtual void rememberMode()
void setEs(int n)
Definition: Bios.cc:231