Started work on Text16-Mode part of the int 0x30 Video Drived

This commit is contained in:
OmniaX 2024-09-02 18:04:12 +02:00
parent bed680aeb2
commit 58c7d9e0b9
18 changed files with 164 additions and 45 deletions

View file

@ -1 +1 @@
1602
1603

View file

@ -5,7 +5,7 @@ rm -r bin
if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
cmake -B bin -S ./
cd bin
make
make -j$(grep -c ^processor /proc/cpuinfo)
mkdir disassembly
if [ $? -eq 0 ]; then
cd ..
@ -19,7 +19,7 @@ if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
cmake -B bin -S ./ -G "MinGW Makefiles"
cd bin
mingw32-make.exe
mingw32-make.exe -j16
mkdir disassembly
if [ $? -eq 0 ]; then
cd ..

View file

@ -9,4 +9,4 @@ memory_extension_pages = 16
SingleColor_foreground = #009900FF
SingleColor_background = #111111FF
16Color_Palette = config/test_palette.dpal
16Color_Palette = 0

Binary file not shown.

Binary file not shown.

View file

@ -39,6 +39,8 @@
KEY_PRESSED 0xA0
KEY_RELEASED 0xA1
TEXT_ENTERED 0xA2
TEXT16_SCREEN_REFRESHED 0xE0
@end
@raw_export_end
@export_comment BIOS_API " --\n"
@ -57,10 +59,12 @@
TEXT_SIGNLE_STR { MemoryAddresses.VGA + 0x0006 }
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 }
MEMORY_CONTROLLER_X_BYTE { MemoryAddresses.VGA + 0x0080 + 1 }
MEMORY_CONTROLLER_Y { MemoryAddresses.VGA + 0x0082 }
MEMORY_CONTROLLER_Y_BYTE { MemoryAddresses.VGA + 0x0082 + 1 }
MEMORY_CONTROLLER_CHAR { MemoryAddresses.VGA + 0x0084 }
MEMORY_CONTROLLER_BG_COL { MemoryAddresses.VGA + 0x0085 }
MEMORY_CONTROLLER_FG_COL { MemoryAddresses.VGA + 0x0086 }
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
@end
@ -159,7 +163,7 @@
@export_comment BIOS_API " Structure to store a character cell for the Text16-Video-Mode."
@raw_export_start BIOS_API
@struct Text16VModeTextCell
@struct Text16VModeCell
Character:1
Foreground:1
Background:1

View file

@ -128,7 +128,16 @@ _int_30_print_string_buffered:
jmp $_int_30_end
_int_30_write_vram_text16:
movb [VGA_Registers.MEMORY_CONTROLLER_CHAR], *R9
inc R9
movb [VGA_Registers.MEMORY_CONTROLLER_FG_COL], *R9
inc R9
movb [VGA_Registers.MEMORY_CONTROLLER_BG_COL], *R9
inc R9
movb [VGA_Registers.MEMORY_CONTROLLER_X_BYTE], *R9
inc R9
movb [VGA_Registers.MEMORY_CONTROLLER_Y_BYTE], *R9
movb [VGA_Registers.SIGNAL], Sig_VGA_Text_16_Color.WRITE_VRAM
jmp $_int_30_end
_int_30_read_vram_text16:

View file

@ -1,5 +1,5 @@
## --
## -- This file is automatically generated by the DragonAssembler (version 0.4.1601)
## -- This file is automatically generated by the DragonAssembler (version 0.4.1602)
## -- Please do not modify this file in any way.
## --
@ -20,19 +20,27 @@
KEY_PRESSED 0xA0
KEY_RELEASED 0xA1
TEXT_ENTERED 0xA2
TEXT16_SCREEN_REFRESHED 0xE0
@end
## --
## 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 }
TEXT_SIGNLE_STR { MemoryAddresses.VGA + 0x0006 }
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
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 }
MEMORY_CONTROLLER_X { MemoryAddresses.VGA + 0x0080 }
MEMORY_CONTROLLER_X_BYTE { MemoryAddresses.VGA + 0x0080 + 1 }
MEMORY_CONTROLLER_Y { MemoryAddresses.VGA + 0x0082 }
MEMORY_CONTROLLER_Y_BYTE { MemoryAddresses.VGA + 0x0082 + 1 }
MEMORY_CONTROLLER_CHAR { MemoryAddresses.VGA + 0x0084 }
MEMORY_CONTROLLER_BG_COL { MemoryAddresses.VGA + 0x0085 }
MEMORY_CONTROLLER_FG_COL { MemoryAddresses.VGA + 0x0086 }
BUFF_START { MemoryAddresses.VGA + 0x00E0 }
@end
## --
@ -57,6 +65,16 @@
@end
## --
## These are signals used to comunicate with the video card's interface, when in TEXT16_COLOR mode.
@group Sig_VGA_Text_16_Color
CONTINUE 0x00
READ_VRAM 0x10
WRITE_VRAM 0x11
FORCE_REFRESH_SCREEN 0xE0
FORCE_CLEAR_SCREEN 0xE1
@end
## --
## Structure of a DPT (Dragon Partition Table).
@group DPTStructure
DISK_ADDR 0x0200
@ -81,3 +99,13 @@
@end
## --
## Structure to store a character cell for the Text16-Video-Mode.
@struct Text16VModeCell
Character:1
Foreground:1
Background:1
CoordX:1
CoordY:1
@end
## --

View file

@ -6,11 +6,49 @@
$string "Hello "
$ddd <DiskDriverData>
$dpt_block <DPTBlock>
$textCell <Text16VModeCell>
.code
push 0
call $_load_dpt_block
movb [VGA_Registers.VIDEO_MODE], VGA_VideoModes.TEXT_16_COLORS
mov R5, 0
draw_loop:
movb [$textCell.Character], 65
movb [$textCell.Foreground], 6
movb [$textCell.Background], 0
movb [$textCell.CoordX], R5
movb [$textCell.CoordY], 1
mov R10, 0x21
mov R9, $textCell
int 0x30
inc R5
mov ACC, R5
jgr $draw_loop, 90
mov R5, 0
draw_loop2:
movb [$textCell.Character], 65
movb [$textCell.Foreground], 6
movb [$textCell.Background], 0
movb [$textCell.CoordX], R5
movb [$textCell.CoordY], 10
mov R10, 0x21
mov R9, $textCell
int 0x30
inc R5
mov ACC, R5
jgr $draw_loop2, 90
mov R10, 0x0C
mov R9, $string
int 0x30

View file

@ -102,8 +102,8 @@
0x06: (2 bytes) Text Single Color Buffered String Address
0x80: Memory Controller
0x80: XCoordinate (4 Bytes)
0x84: YCoordinate (4 Bytes)
0x80: XCoordinate (2 Bytes)
0x84: YCoordinate (2 Bytes)
0x88: Character (1 Byte)
0x09: Foreground (1 Byte)
0x8A: Background (1 Byte)
@ -142,6 +142,9 @@
0x0A: Store Null-Terminated String in buffer in Text Single Mode (string address stored in R9 register)
0x0B: Toggles inverted colors in Text Single Mode
0x20: Read VRAM in Text16 Colors Mode (Cell address stored in R9)
0x20: Write VRAM in Text16 Colors Mode (Cell address stored in R9)
0xE0: Refresh Screen
0xE1: Clear Screen
@ -153,6 +156,7 @@
0xA0: Keyboard Interface - Key Pressed
0xA1: Keyboard Interface - Key Released
0xA2: Keyboard Interface - Text Entered
0xE0: Virtual Display - Text16_Mode Screen Refreshed

View file

@ -6,8 +6,8 @@ clear='\033[0m'
printf "${green}\n============================================[ Building Application ]============================================\n\n${clear}"
\cp -r ../extra/* ./
if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
make
make -j$(grep -c ^processor /proc/cpuinfo)
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
mingw32-make.exe
mingw32-make.exe -j16
fi
printf "${green}\n=================================================================================================================\n\n"

View file

@ -6,9 +6,9 @@ clear='\033[0m'
printf "${green}\n============================================[ Building Application ]============================================\n\n${clear}"
\cp -r ../extra/* ./
if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
make
make -j$(grep -c ^processor /proc/cpuinfo)
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
mingw32-make.exe
mingw32-make.exe -j16
fi
printf "${green}\n=================================================================================================================\n\n"
if [ $? -eq 0 ]; then

View file

@ -6,9 +6,9 @@ clear='\033[0m'
printf "${green}\n============================================[ Building Application ]============================================\n\n${clear}"
\cp -r ../extra/* ./
if [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
make
make -j$(grep -c ^processor /proc/cpuinfo)
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
mingw32-make.exe
mingw32-make.exe -j16
fi
printf "${green}\n=================================================================================================================\n\n"
if [ $? -eq 0 ]; then

View file

@ -12,7 +12,13 @@ namespace dragon
m_renderer.initialize(*this);
RawTextRenderer::initialize();
m_text16_palette = new data::BiosVideoDefaultPalette; //TODO: Delete, Memory Leak
text16_load_palettes();
m_currentPaletteID = DragonRuntime::machine_config.text16_palette;
if (m_currentPaletteID >= m_text16_palettes.size())
m_text16_Currentpalette = m_text16_palettes[0];
else
m_text16_Currentpalette = m_text16_palettes[m_currentPaletteID];
text16_init_buffer();
}
@ -49,17 +55,19 @@ namespace dragon
if (m_refreshScreen)
{
uint8_t clear_color = mem.read8(vga_addr + tRegisters::ClearColor);
ostd::Color clearColor = m_text16_palette->getColor(clear_color);
ostd::Color clearColor = m_text16_Currentpalette->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);
ostd::Color background = m_text16_Currentpalette->getColor(cell.backgroundColor);
ostd::Color foreground = m_text16_Currentpalette->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);
}
DragonRuntime::cpu.handleInterrupt(data::InterruptCodes::Text16ModeScreenRefreshed, true);
m_refreshScreen = false;
}
}
m_renderer.updateBuffer();
@ -121,6 +129,22 @@ namespace dragon
}
else if (video_mode == tVideoModeValues::Text16Colors)
{
if (signal == tSignalValues::Text16Color_ReadMemory)
{
}
else if (signal == tSignalValues::Text16Color_WriteMemory)
{
hw::interface::Graphics::tText16_Cell textCell;
textCell.foregroundColor = mem.read8(vga_addr + tRegisters::MemControllerFGCol);
textCell.backgroundColor = mem.read8(vga_addr + tRegisters::MemControllerBGCol);
textCell.character = mem.read8(vga_addr + tRegisters::MemControllerChar);
int16_t x = mem.read16(vga_addr + tRegisters::MemControllerX);
int16_t y = mem.read16(vga_addr + tRegisters::MemControllerY);
DragonRuntime::vGraphicsInterface.writeVRAM_16Colors(static_cast<uint8_t>(x), static_cast<uint8_t>(y), textCell.character, textCell.backgroundColor, textCell.foregroundColor);
}
}
else return;
mem.write8(vga_addr + tRegisters::Signal, tSignalValues::Continue);
@ -133,7 +157,6 @@ namespace dragon
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;
@ -147,8 +170,6 @@ namespace dragon
}
}
void VirtualDisplay::onFixedUpdate(void) { }
void VirtualDisplay::onSlowUpdate(void) { }
void VirtualDisplay::single_text_add_char_to_line(char c)
@ -244,12 +265,9 @@ namespace dragon
m_text16_buffer.push_back({ 0, 0, ' ' });
}
void VirtualDisplay::text16_buffer_diff(void)
void VirtualDisplay::text16_load_palettes(void)
{
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
{
}
m_text16_palettes.push_back(new data::BiosVideoDefaultPalette); //TODO: Delete, Memory Leak
}
}

View file

@ -20,6 +20,12 @@ namespace dragon
inline static constexpr uint8_t TextSingleCharacter = 0x04;
inline static constexpr uint8_t TextSingleInvertColors = 0x05;
inline static constexpr uint8_t TextSingleString = 0x06;
inline static constexpr uint8_t MemControllerX = 0x80;
inline static constexpr uint8_t MemControllerY = 0x82;
inline static constexpr uint8_t MemControllerChar = 0x84;
inline static constexpr uint8_t MemControllerBGCol = 0x85;
inline static constexpr uint8_t MemControllerFGCol = 0x86;
};
public: struct tVideoModeValues
{
@ -49,7 +55,6 @@ namespace dragon
void onRender(void) override;
void onUpdate(void) override;
void onFixedUpdate(void) override;
void onFixedUpdate(void) override;
void onSlowUpdate(void) override;
private:
@ -63,7 +68,7 @@ namespace dragon
void single_text_refresh_screen(void);
void text16_init_buffer(void);
void text16_buffer_diff(void);
void text16_load_palettes(void);
private:
Renderer m_renderer;
@ -72,7 +77,9 @@ namespace dragon
ostd::String m_singleTextBuffer { "" };
std::vector<hw::interface::Graphics::tText16_Cell> m_text16_buffer;
data::IBiosVideoPalette* m_text16_palette;
std::vector<data::IBiosVideoPalette*> m_text16_palettes;
data::IBiosVideoPalette* m_text16_Currentpalette { nullptr };
uint8_t m_currentPaletteID { 0 };
};
}
}

View file

@ -9,7 +9,7 @@ namespace dragon
{
tMachineConfig config;
ostd::TextFileBuffer file(configFilePath.cpp_str());
if (!file.exists()) return config;
if (!file.exists()) return config; //TODO: Error
auto lines = file.getLines();
for (auto& line : lines)
{
@ -102,6 +102,13 @@ namespace dragon
if (config.memory_extension_pages > data::DefaultValues::MaxMemoryExtensionPages)
config.memory_extension_pages = data::DefaultValues::MaxMemoryExtensionPages;
}
else if (lineEdit == "16color_palette")
{
lineEdit = tokens.next();
lineEdit.trim().toLower();
if (!lineEdit.isNumeric()) continue; //TODO: Error
config.text16_palette = lineEdit.toInt();
}
else continue; //TODO: Warning
}
return validate_machine_config(config);

View file

@ -17,6 +17,7 @@ namespace dragon
ostd::String cmos_path;
ostd::Color singleColor_background;
ostd::Color singleColor_foreground;
uint8_t text16_palette { 0 };
inline bool isValid(void) const { return m_valid; }
inline void destroy(void) { for (auto& ptr : cpuext_list) delete ptr.second; }

View file

@ -150,7 +150,7 @@ namespace dragon
return m_colors[col];
}
private:
protected:
std::vector<ostd::Color> m_colors;
};
@ -196,6 +196,8 @@ namespace dragon
inline static constexpr uint8_t KeyReleased = 0xA1;
inline static constexpr uint8_t TextEntered = 0xA2;
inline static constexpr uint8_t Text16ModeScreenRefreshed = 0xE0;
inline static ostd::String getInterruptName(uint8_t code)
{
switch (code)
@ -204,6 +206,7 @@ namespace dragon
case KeyPressed: return "Key_Pressed";
case KeyReleased: return "Key_Released";
case TextEntered: return "Text_Entered";
case Text16ModeScreenRefreshed: return "Text16_Mode_Screen_Refreshed";
default: return "UNKNOWN";
}
return "UNKNOWN";