Started work on infrastructure for Text16Colors-Video-Mode
This commit is contained in:
parent
d1dfc42a50
commit
bed680aeb2
9 changed files with 223 additions and 28 deletions
|
|
@ -1,6 +1,7 @@
|
|||
Disks = dragon/disk1.dr
|
||||
Bios = dragon/bios.bin
|
||||
CMOS = dragon/cmos.dr
|
||||
|
||||
cpuext = extmov, extalu
|
||||
fixed_clock = true
|
||||
clock_rate_sec = 644
|
||||
|
|
@ -8,3 +9,4 @@ memory_extension_pages = 16
|
|||
|
||||
SingleColor_foreground = #009900FF
|
||||
SingleColor_background = #111111FF
|
||||
16Color_Palette = config/test_palette.dpal
|
||||
|
|
@ -48,15 +48,21 @@
|
|||
@export_comment BIOS_API " These are the memory-mapped registers used to interact with the video card's interface."
|
||||
@raw_export_start BIOS_API
|
||||
@group VGA_Registers
|
||||
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
||||
CLEAR_COLOR { MemoryAddresses.VGA + 0x0001 }
|
||||
PALETTE { MemoryAddresses.VGA + 0x0002 }
|
||||
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
||||
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
||||
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
|
||||
TEXT_SIGNLE_STR { MemoryAddresses.VGA + 0x0006 }
|
||||
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
||||
CLEAR_COLOR { MemoryAddresses.VGA + 0x0001 }
|
||||
PALETTE { MemoryAddresses.VGA + 0x0002 }
|
||||
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
||||
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
||||
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
|
||||
TEXT_SIGNLE_STR { MemoryAddresses.VGA + 0x0006 }
|
||||
|
||||
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
|
||||
MEMORY_CONTROLLER_X { MemoryAddresses.VGA + 0x0080 }
|
||||
MEMORY_CONTROLLER_Y { MemoryAddresses.VGA + 0x0084 }
|
||||
MEMORY_CONTROLLER_CHAR { MemoryAddresses.VGA + 0x0088 }
|
||||
MEMORY_CONTROLLER_BG_COL { MemoryAddresses.VGA + 0x0089 }
|
||||
MEMORY_CONTROLLER_FG_COL { MemoryAddresses.VGA + 0x008A }
|
||||
|
||||
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
|
@ -93,6 +99,22 @@
|
|||
|
||||
|
||||
|
||||
@export_comment BIOS_API " These are signals used to comunicate with the video card's interface, when in TEXT16_COLOR mode."
|
||||
@raw_export_start BIOS_API
|
||||
@group Sig_VGA_Text_16_Color
|
||||
CONTINUE 0x00
|
||||
|
||||
READ_VRAM 0x10
|
||||
WRITE_VRAM 0x11
|
||||
|
||||
FORCE_REFRESH_SCREEN 0xE0
|
||||
FORCE_CLEAR_SCREEN 0xE1
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
|
||||
@define S_REG_1 0x07
|
||||
@define S_REG_2 0x08
|
||||
@define S_REG_OFFSET 0x09
|
||||
|
|
@ -133,6 +155,19 @@
|
|||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
|
||||
|
||||
@export_comment BIOS_API " Structure to store a character cell for the Text16-Video-Mode."
|
||||
@raw_export_start BIOS_API
|
||||
@struct Text16VModeTextCell
|
||||
Character:1
|
||||
Foreground:1
|
||||
Background:1
|
||||
CoordX:1
|
||||
CoordY:1
|
||||
@end
|
||||
@raw_export_end
|
||||
@export_comment BIOS_API " --\n"
|
||||
## ===============================================================================================
|
||||
|
||||
.data
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ _int_30_handler:
|
|||
jeq $_int_30_store_string_text_single, 0x000A
|
||||
jeq $_int_30_invert_colors_text_single, 0x000B
|
||||
jeq $_int_30_print_string_buffered, 0x000C
|
||||
|
||||
jeq $_int_30_read_vram_text16, 0x0020
|
||||
jeq $_int_30_write_vram_text16, 0x0021
|
||||
|
||||
jeq $_int_30_clear_screen, 0x00E0
|
||||
jeq $_int_30_refresh_screen, 0x00E1
|
||||
jmp $_int_30_end
|
||||
|
|
@ -123,6 +127,13 @@ _int_30_print_string_buffered:
|
|||
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_Single_Color.PRINT_STRING
|
||||
jmp $_int_30_end
|
||||
|
||||
_int_30_write_vram_text16:
|
||||
|
||||
jmp $_int_30_end
|
||||
_int_30_read_vram_text16:
|
||||
|
||||
jmp $_int_30_end
|
||||
|
||||
|
||||
|
||||
_int_30_clear_screen:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
## -- Please do not modify this file in any way.
|
||||
## --
|
||||
|
||||
##These are the base addresses of the memory map.
|
||||
## These are the base addresses of the memory map.
|
||||
@group MemoryAddresses
|
||||
MBR 0x1380
|
||||
INT_VEC 0x1080
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
@end
|
||||
## --
|
||||
|
||||
##These are the Hardware Interrupt codes of this machine.
|
||||
## These are the Hardware Interrupt codes of this machine.
|
||||
@group HW_Int
|
||||
DISK_INTERFACE_FINISHED 0x80
|
||||
KEY_PRESSED 0xA0
|
||||
|
|
@ -23,9 +23,11 @@
|
|||
@end
|
||||
## --
|
||||
|
||||
##These are the memory-mapped registers used to interact with the video card's interface.
|
||||
## These are the memory-mapped registers used to interact with the video card's interface.
|
||||
@group VGA_Registers
|
||||
VIDEO_MODE { MemoryAddresses.VGA + 0x0000 }
|
||||
CLEAR_COLOR { MemoryAddresses.VGA + 0x0001 }
|
||||
PALETTE { MemoryAddresses.VGA + 0x0002 }
|
||||
SIGNAL { MemoryAddresses.VGA + 0x0003 }
|
||||
TEXT_SINGLE_CHAR { MemoryAddresses.VGA + 0x0004 }
|
||||
TEXT_SIGNLE_INVERT { MemoryAddresses.VGA + 0x0005 }
|
||||
|
|
@ -34,13 +36,14 @@
|
|||
@end
|
||||
## --
|
||||
|
||||
##These are the different Video Modes that the video card supports.
|
||||
## These are the different Video Modes that the video card supports.
|
||||
@group VGA_VideoModes
|
||||
TEXT_SINGLE_COLOR 0x00
|
||||
TEXT_16_COLORS 0x01
|
||||
@end
|
||||
## --
|
||||
|
||||
##These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode.
|
||||
## These are signals used to comunicate with the video card's interface, when in TEXT_SINGLE_COLOR mode.
|
||||
@group Sig_VGA_Text_Single_Color
|
||||
CONTINUE 0x00
|
||||
PRINT_CHAR 0x02
|
||||
|
|
@ -54,7 +57,7 @@
|
|||
@end
|
||||
## --
|
||||
|
||||
##Structure of a DPT (Dragon Partition Table).
|
||||
## Structure of a DPT (Dragon Partition Table).
|
||||
@group DPTStructure
|
||||
DISK_ADDR 0x0200
|
||||
ENTRIES_START 0x000C
|
||||
|
|
@ -67,7 +70,7 @@
|
|||
@end
|
||||
## --
|
||||
|
||||
##Structure to store a DPT block.
|
||||
## Structure to store a DPT block.
|
||||
@struct DPTBlock
|
||||
ID:2
|
||||
VersionMaj:1
|
||||
|
|
|
|||
|
|
@ -92,11 +92,24 @@
|
|||
0x06: Text Single Color - Print Buffer Without Flushing
|
||||
0x07: Text Single Color - Print Buffered String
|
||||
|
||||
0x10: Text 16 Colors - Read Memory
|
||||
0x11: Text 16 Colors - Write Memory
|
||||
|
||||
0xE0: Refresh Screen
|
||||
0xE1: Clear Screen
|
||||
0x04: Text Single Color Character (1 Byte)
|
||||
0x05: Text Single Color Inverted colors (1 Byte)
|
||||
0x06: (2 bytes) Text Single Color Buffered String Address
|
||||
|
||||
0x80: Memory Controller
|
||||
0x80: XCoordinate (4 Bytes)
|
||||
0x84: YCoordinate (4 Bytes)
|
||||
0x88: Character (1 Byte)
|
||||
0x09: Foreground (1 Byte)
|
||||
0x8A: Background (1 Byte)
|
||||
|
||||
(VRAM Memory Cell: Character:1, Foreground:1, Background:1, Reserved:1)
|
||||
|
||||
0x16FF
|
||||
-------
|
||||
0x1700 GENERIC SERIAL INTERFACE (64 Bytes)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "VirtualDisplay.hpp"
|
||||
#include "../gui/RawTextRenderer.hpp"
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
#include "../tools/GlobalData.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
|
|
@ -10,6 +11,9 @@ namespace dragon
|
|||
{
|
||||
m_renderer.initialize(*this);
|
||||
RawTextRenderer::initialize();
|
||||
|
||||
m_text16_palette = new data::BiosVideoDefaultPalette; //TODO: Delete, Memory Leak
|
||||
text16_init_buffer();
|
||||
}
|
||||
|
||||
void VirtualDisplay::onDestroy(void) { }
|
||||
|
|
@ -19,22 +23,44 @@ namespace dragon
|
|||
auto& config = DragonRuntime::machine_config;
|
||||
auto& mem = DragonRuntime::memMap;
|
||||
uint16_t vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||
uint8_t invert_colors = mem.read8(vga_addr + tRegisters::TextSingleInvertColors);
|
||||
if (m_refreshScreen)
|
||||
uint8_t video_mode = mem.read8(vga_addr + tRegisters::VideoMode);
|
||||
if (video_mode == tVideoModeValues::TextSingleColor)
|
||||
{
|
||||
if (invert_colors == 0)
|
||||
m_renderer.clear(config.singleColor_background);
|
||||
else
|
||||
m_renderer.clear(config.singleColor_foreground);
|
||||
for (int32_t i = 0; i < m_singleTextLines.size(); i++)
|
||||
uint8_t invert_colors = mem.read8(vga_addr + tRegisters::TextSingleInvertColors);
|
||||
if (m_refreshScreen)
|
||||
{
|
||||
auto& line = m_singleTextLines[i];
|
||||
if (invert_colors == 0)
|
||||
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
|
||||
m_renderer.clear(config.singleColor_background);
|
||||
else
|
||||
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
|
||||
m_renderer.clear(config.singleColor_foreground);
|
||||
for (int32_t i = 0; i < m_singleTextLines.size(); i++)
|
||||
{
|
||||
auto& line = m_singleTextLines[i];
|
||||
if (invert_colors == 0)
|
||||
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
|
||||
else
|
||||
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
|
||||
}
|
||||
m_refreshScreen = false;
|
||||
}
|
||||
}
|
||||
else if (video_mode == tVideoModeValues::Text16Colors)
|
||||
{
|
||||
if (m_refreshScreen)
|
||||
{
|
||||
uint8_t clear_color = mem.read8(vga_addr + tRegisters::ClearColor);
|
||||
ostd::Color clearColor = m_text16_palette->getColor(clear_color);
|
||||
m_renderer.clear(clearColor);
|
||||
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
|
||||
{
|
||||
auto& cell = m_text16_buffer[i];
|
||||
ostd::Color background = m_text16_palette->getColor(cell.backgroundColor);
|
||||
ostd::Color foreground = m_text16_palette->getColor(cell.foregroundColor);
|
||||
char character = static_cast<char>(cell.character);
|
||||
auto xy = CONVERT_1D_2D(i, RawTextRenderer::CONSOLE_CHARS_H);
|
||||
RawTextRenderer::drawString(ostd::String().addChar(character), xy.x, xy.y, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, foreground, background);
|
||||
}
|
||||
}
|
||||
m_refreshScreen = false;
|
||||
}
|
||||
m_renderer.updateBuffer();
|
||||
m_renderer.displayBuffer();
|
||||
|
|
@ -93,10 +119,34 @@ namespace dragon
|
|||
single_text_refresh_screen();
|
||||
}
|
||||
}
|
||||
else if (video_mode == tVideoModeValues::Text16Colors)
|
||||
{
|
||||
}
|
||||
else return;
|
||||
mem.write8(vga_addr + tRegisters::Signal, tSignalValues::Continue);
|
||||
}
|
||||
|
||||
void VirtualDisplay::onFixedUpdate(void)
|
||||
{
|
||||
auto& config = DragonRuntime::machine_config;
|
||||
auto& mem = DragonRuntime::memMap;
|
||||
uint16_t vga_addr = data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||
uint8_t video_mode = mem.read8(vga_addr + tRegisters::VideoMode);
|
||||
uint8_t signal = mem.read8(vga_addr + tRegisters::Signal);
|
||||
if (signal == tSignalValues::Continue) return;
|
||||
if (video_mode == tVideoModeValues::Text16Colors)
|
||||
{
|
||||
m_refreshScreen = true;
|
||||
dragon::hw::interface::Graphics::tText16_Cell outTextCell;
|
||||
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
|
||||
{
|
||||
auto xy = CONVERT_1D_2D(i, RawTextRenderer::CONSOLE_CHARS_H);
|
||||
DragonRuntime::vGraphicsInterface.readVRAM_16Colors(xy.x, xy.y, outTextCell);
|
||||
m_text16_buffer[i] = outTextCell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualDisplay::onFixedUpdate(void) { }
|
||||
|
||||
void VirtualDisplay::onSlowUpdate(void) { }
|
||||
|
|
@ -176,7 +226,6 @@ namespace dragon
|
|||
single_text_add_char_to_line(ch);
|
||||
}
|
||||
|
||||
|
||||
void VirtualDisplay::single_text_clear_screen(void)
|
||||
{
|
||||
m_singleTextLines.clear();
|
||||
|
|
@ -188,5 +237,20 @@ namespace dragon
|
|||
m_refreshScreen = true;
|
||||
}
|
||||
|
||||
|
||||
void VirtualDisplay::text16_init_buffer(void)
|
||||
{
|
||||
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
|
||||
m_text16_buffer.push_back({ 0, 0, ' ' });
|
||||
}
|
||||
|
||||
void VirtualDisplay::text16_buffer_diff(void)
|
||||
{
|
||||
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
#include "../gui/Window.hpp"
|
||||
#include "../gui/Renderer.hpp"
|
||||
#include "../hardware/VirtualIODevices.hpp"
|
||||
|
||||
namespace dragon
|
||||
{
|
||||
namespace data { class IBiosVideoPalette; }
|
||||
namespace hw
|
||||
{
|
||||
class VirtualDisplay : public Window
|
||||
|
|
@ -12,6 +14,8 @@ namespace dragon
|
|||
public: struct tRegisters
|
||||
{
|
||||
inline static constexpr uint8_t VideoMode = 0x00;
|
||||
inline static constexpr uint8_t ClearColor = 0x01;
|
||||
inline static constexpr uint8_t Palette = 0x02;
|
||||
inline static constexpr uint8_t Signal = 0x03;
|
||||
inline static constexpr uint8_t TextSingleCharacter = 0x04;
|
||||
inline static constexpr uint8_t TextSingleInvertColors = 0x05;
|
||||
|
|
@ -20,6 +24,7 @@ namespace dragon
|
|||
public: struct tVideoModeValues
|
||||
{
|
||||
inline static constexpr uint8_t TextSingleColor = 0x00;
|
||||
inline static constexpr uint8_t Text16Colors = 0x01;
|
||||
};
|
||||
public: struct tSignalValues
|
||||
{
|
||||
|
|
@ -32,6 +37,9 @@ namespace dragon
|
|||
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffNoFlush = 0x06;
|
||||
inline static constexpr uint8_t TextSingleColor_DirectPrintString = 0x07;
|
||||
|
||||
inline static constexpr uint8_t Text16Color_ReadMemory = 0x10;
|
||||
inline static constexpr uint8_t Text16Color_WriteMemory = 0x11;
|
||||
|
||||
inline static constexpr uint8_t RefreshScreen = 0xE0;
|
||||
inline static constexpr uint8_t ClearSCreen = 0xE1;
|
||||
};
|
||||
|
|
@ -41,6 +49,7 @@ namespace dragon
|
|||
void onRender(void) override;
|
||||
void onUpdate(void) override;
|
||||
void onFixedUpdate(void) override;
|
||||
void onFixedUpdate(void) override;
|
||||
void onSlowUpdate(void) override;
|
||||
|
||||
private:
|
||||
|
|
@ -53,11 +62,17 @@ namespace dragon
|
|||
void single_text_clear_screen(void);
|
||||
void single_text_refresh_screen(void);
|
||||
|
||||
void text16_init_buffer(void);
|
||||
void text16_buffer_diff(void);
|
||||
|
||||
private:
|
||||
Renderer m_renderer;
|
||||
|
||||
std::vector<ostd::String> m_singleTextLines;
|
||||
ostd::String m_singleTextBuffer { "" };
|
||||
|
||||
std::vector<hw::interface::Graphics::tText16_Cell> m_text16_buffer;
|
||||
data::IBiosVideoPalette* m_text16_palette;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#include "VirtualRAM.hpp"
|
||||
|
||||
#include "../runtime/DragonRuntime.hpp"
|
||||
#include "../gui/RawTextRenderer.hpp"
|
||||
|
||||
//TODO: Fix all access functions (reads and writes) ensuring the address is not out of bounds.
|
||||
// Right now the check is done, but just to push an error if out of bounds; the address
|
||||
|
|
@ -660,6 +661,7 @@ namespace dragon
|
|||
Graphics::Graphics(void)
|
||||
{
|
||||
m_videoMemory.init(0xFFFF);
|
||||
m_vramStart = data::MemoryMapAddresses::VideoCardInterface_End - data::MemoryMapAddresses::VideoCardInterface_Start;
|
||||
}
|
||||
|
||||
int8_t Graphics::read8(uint16_t addr)
|
||||
|
|
@ -709,6 +711,36 @@ namespace dragon
|
|||
return &m_videoMemory.getData();
|
||||
}
|
||||
|
||||
bool Graphics::readVRAM_16Colors(uint8_t x, uint8_t y, Graphics::tText16_Cell& outTextCell)
|
||||
{
|
||||
uint16_t cellOffset = static_cast<uint16_t>(CONVERT_2D_1D(x, y, RawTextRenderer::CONSOLE_CHARS_H)) * 4;
|
||||
cellOffset += m_vramStart;
|
||||
int8_t outVal = 0;
|
||||
if (!m_videoMemory.r_Byte(cellOffset + tText16_CellStructure::character, outVal))
|
||||
return false; //TODO: Error
|
||||
outTextCell.character = outVal;
|
||||
if (!m_videoMemory.r_Byte(cellOffset + tText16_CellStructure::background, outVal))
|
||||
return false; //TODO: Error
|
||||
outTextCell.backgroundColor = outVal;
|
||||
if (!m_videoMemory.r_Byte(cellOffset + tText16_CellStructure::foreground, outVal))
|
||||
return false; //TODO: Error
|
||||
outTextCell.foregroundColor = outVal;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Graphics::writeVRAM_16Colors(uint8_t x, uint8_t y, uint8_t character, uint8_t background, uint8_t foreground)
|
||||
{
|
||||
uint16_t cellOffset = static_cast<uint16_t>(CONVERT_2D_1D(x, y, RawTextRenderer::CONSOLE_CHARS_H)) * 4;
|
||||
cellOffset += m_vramStart;
|
||||
if (!m_videoMemory.w_Byte(cellOffset + tText16_CellStructure::character, character))
|
||||
return false; //TODO: Error
|
||||
if (!m_videoMemory.w_Byte(cellOffset + tText16_CellStructure::background, background))
|
||||
return false; //TODO: Error
|
||||
if (!m_videoMemory.w_Byte(cellOffset + tText16_CellStructure::foreground, foreground))
|
||||
return false; //TODO: Error
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -345,6 +345,19 @@ namespace dragon
|
|||
};
|
||||
class Graphics : public IMemoryDevice
|
||||
{
|
||||
public: struct tText16_Cell
|
||||
{
|
||||
uint8_t backgroundColor;
|
||||
uint8_t foregroundColor;
|
||||
uint8_t character;
|
||||
};
|
||||
public: struct tText16_CellStructure
|
||||
{
|
||||
inline static constexpr uint8_t character = 0x00;
|
||||
inline static constexpr uint8_t foreground = 0x01;
|
||||
inline static constexpr uint8_t background = 0x02;
|
||||
inline static constexpr uint8_t reserved = 0x03;
|
||||
};
|
||||
public:
|
||||
Graphics(void);
|
||||
int8_t read8(uint16_t addr) override;
|
||||
|
|
@ -354,8 +367,15 @@ namespace dragon
|
|||
|
||||
ostd::ByteStream* getByteStream(void) override;
|
||||
|
||||
inline uint16_t getVRAMStart(void) { return m_vramStart; }
|
||||
bool readVRAM_16Colors(uint8_t x, uint8_t y, tText16_Cell& outTextCell);
|
||||
bool writeVRAM_16Colors(uint8_t x, uint8_t y, uint8_t character = 0, uint8_t background = 0xFF, uint8_t foreground = 0xFF);
|
||||
|
||||
private:
|
||||
ostd::serial::SerialIO m_videoMemory;
|
||||
|
||||
uint16_t m_vramStart { 0 };
|
||||
uint8_t m_16Color_cellSize { 4 };
|
||||
};
|
||||
class SerialPort : public IMemoryDevice
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue