Initial commit
This commit is contained in:
commit
66dd6670f6
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "vga"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Ryan Kennedy <rkennedy9064@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
conquer-once = "0.2.0"
|
||||||
|
spinning_top = "0.1.0"
|
||||||
|
x86_64 = "0.9.6"
|
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nightly
|
21
src/lib.rs
Normal file
21
src/lib.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//! This crate provides vga specific functions, data structures,
|
||||||
|
//! and access to various registers.
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
pub mod vga;
|
||||||
|
pub mod vga_colors;
|
||||||
|
mod vga_configurations;
|
||||||
|
mod vga_fonts;
|
||||||
|
mod vga_registers;
|
||||||
|
|
||||||
|
pub use vga::VGA;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
343
src/vga.rs
Normal file
343
src/vga.rs
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
//! Provides access to the vga graphics card.
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
vga_configurations::{
|
||||||
|
VgaConfiguration, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
||||||
|
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
|
||||||
|
},
|
||||||
|
vga_fonts::{VgaFont, TEXT_8X16_FONT, TEXT_8X8_FONT},
|
||||||
|
vga_registers::{
|
||||||
|
AttributeControllerRegisters, CrtcControllerIndex, CrtcControllerRegisters, EmulationMode,
|
||||||
|
GeneralRegisters, GraphicsControllerIndex, GraphicsControllerRegisters, SequencerIndex,
|
||||||
|
SequencerRegisters,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use conquer_once::spin::Lazy;
|
||||||
|
use spinning_top::Spinlock;
|
||||||
|
|
||||||
|
/// Provides mutable access to the vga graphics card.
|
||||||
|
pub static VGA: Lazy<Spinlock<Vga>> = Lazy::new(|| Spinlock::new(Vga::new()));
|
||||||
|
|
||||||
|
/// Represents the starting address of the frame buffer for
|
||||||
|
/// various video modes.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum FrameBuffer {
|
||||||
|
/// The starting address for graphics modes.
|
||||||
|
GraphicsMode = 0xa0000,
|
||||||
|
/// The starting address for color text modes.
|
||||||
|
CgaMode = 0xb8000,
|
||||||
|
/// The starting address for monochrome text modes.
|
||||||
|
MdaMode = 0xb0000,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for FrameBuffer {
|
||||||
|
fn from(value: u8) -> FrameBuffer {
|
||||||
|
match value {
|
||||||
|
0x1 => FrameBuffer::GraphicsMode,
|
||||||
|
0x2 => FrameBuffer::MdaMode,
|
||||||
|
0x3 => FrameBuffer::CgaMode,
|
||||||
|
_ => panic!("{:X} is not a valid FrameBuffer value", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FrameBuffer> for u32 {
|
||||||
|
fn from(value: FrameBuffer) -> u32 {
|
||||||
|
value as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a plane for reading and writing vga data.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum Plane {
|
||||||
|
/// Represents `Plane 0 (0x0)`.
|
||||||
|
Plane0 = 0x0,
|
||||||
|
/// Represents `Plane 1 (0x1)`.
|
||||||
|
Plane1 = 0x1,
|
||||||
|
/// Represents `Plane 2 (0x2)`.
|
||||||
|
Plane2 = 0x2,
|
||||||
|
/// Represents `Plane 3 (0x3)`.
|
||||||
|
Plane3 = 0x3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Plane> for u8 {
|
||||||
|
fn from(value: Plane) -> u8 {
|
||||||
|
value as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a specified vga video mode.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum VideoMode {
|
||||||
|
/// Represents text mode 40x25.
|
||||||
|
Mode40x25,
|
||||||
|
/// Represents text mode 40x50.
|
||||||
|
Mode40x50,
|
||||||
|
/// Represents text mode 80x25.
|
||||||
|
Mode80x25,
|
||||||
|
/// Represents graphics mode 640x480x16.
|
||||||
|
Mode640x480x16,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a vga graphics card with it's common registers,
|
||||||
|
/// as well as the most recent video mode.
|
||||||
|
pub struct Vga {
|
||||||
|
general_registers: GeneralRegisters,
|
||||||
|
sequencer_registers: SequencerRegisters,
|
||||||
|
graphics_controller_registers: GraphicsControllerRegisters,
|
||||||
|
attribute_controller_registers: AttributeControllerRegisters,
|
||||||
|
crtc_controller_registers: CrtcControllerRegisters,
|
||||||
|
most_recent_video_mode: Option<VideoMode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vga {
|
||||||
|
fn new() -> Vga {
|
||||||
|
Vga {
|
||||||
|
general_registers: GeneralRegisters::new(),
|
||||||
|
sequencer_registers: SequencerRegisters::new(),
|
||||||
|
graphics_controller_registers: GraphicsControllerRegisters::new(),
|
||||||
|
attribute_controller_registers: AttributeControllerRegisters::new(),
|
||||||
|
crtc_controller_registers: CrtcControllerRegisters::new(),
|
||||||
|
most_recent_video_mode: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the vga graphics card to the given `VideoMode`.
|
||||||
|
pub fn set_video_mode(&mut self, video_mode: VideoMode) {
|
||||||
|
match video_mode {
|
||||||
|
VideoMode::Mode40x25 => self.set_video_mode_40x25(),
|
||||||
|
VideoMode::Mode40x50 => self.set_video_mode_40x50(),
|
||||||
|
VideoMode::Mode80x25 => self.set_video_mode_80x25(),
|
||||||
|
VideoMode::Mode640x480x16 => self.set_video_mode_640x480x16(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the `FrameBuffer` address as specified by the
|
||||||
|
/// `Miscellaneous Output Register`.
|
||||||
|
pub fn get_frame_buffer(&mut self) -> FrameBuffer {
|
||||||
|
let miscellaneous_graphics = self
|
||||||
|
.graphics_controller_registers
|
||||||
|
.read(GraphicsControllerIndex::Miscellaneous);
|
||||||
|
let memory_map_mode = (miscellaneous_graphics >> 0x2) & 0x3;
|
||||||
|
FrameBuffer::from(memory_map_mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the most recent video mode, or `None` if no
|
||||||
|
/// video mode has been set yet.
|
||||||
|
pub fn get_most_recent_video_mode(&self) -> Option<VideoMode> {
|
||||||
|
self.most_recent_video_mode
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `I/O Address Select` Bit 0 `(value & 0x1)` of MSR selects 3Bxh or 3Dxh as the I/O address for the CRT Controller
|
||||||
|
/// registers, the Feature Control Register (FCR), and Input Status Register 1 (ST01). Presently
|
||||||
|
/// ignored (whole range is claimed), but will "ignore" 3Bx for color configuration or 3Dx for
|
||||||
|
/// monochrome.
|
||||||
|
/// Note that it is typical in AGP chipsets to shadow this bit and properly steer I/O cycles to the
|
||||||
|
/// proper bus for operation where a MDA exists on another bus such as ISA.
|
||||||
|
///
|
||||||
|
/// 0 = Select 3Bxh I/O address `(EmulationMode::Mda)`
|
||||||
|
///
|
||||||
|
/// 1 = Select 3Dxh I/O address `(EmulationMode:Cga)`
|
||||||
|
fn get_emulation_mode(&mut self) -> EmulationMode {
|
||||||
|
EmulationMode::from(self.general_registers.read_msr() & 0x1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_font(&mut self, vga_font: &VgaFont) {
|
||||||
|
// Save registers
|
||||||
|
let (
|
||||||
|
plane_mask,
|
||||||
|
sequencer_memory_mode,
|
||||||
|
read_plane_select,
|
||||||
|
graphics_mode,
|
||||||
|
miscellaneous_graphics,
|
||||||
|
) = self.save_font_registers();
|
||||||
|
|
||||||
|
// Switch to flat addressing
|
||||||
|
self.sequencer_registers
|
||||||
|
.write(SequencerIndex::MemoryMode, sequencer_memory_mode | 0x04);
|
||||||
|
|
||||||
|
// Disable Even/Odd addressing
|
||||||
|
self.graphics_controller_registers
|
||||||
|
.write(GraphicsControllerIndex::GraphicsMode, graphics_mode & !0x10);
|
||||||
|
self.graphics_controller_registers.write(
|
||||||
|
GraphicsControllerIndex::Miscellaneous,
|
||||||
|
miscellaneous_graphics & !0x02,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write font to plane
|
||||||
|
self.set_plane(Plane::Plane2);
|
||||||
|
|
||||||
|
let frame_buffer = u32::from(self.get_frame_buffer()) as *mut u8;
|
||||||
|
|
||||||
|
for character in 0..vga_font.characters {
|
||||||
|
for row in 0..vga_font.character_height {
|
||||||
|
let offset = (character * 32) + row;
|
||||||
|
let font_offset = (character * vga_font.character_height) + row;
|
||||||
|
unsafe {
|
||||||
|
frame_buffer
|
||||||
|
.offset(offset as isize)
|
||||||
|
.write_volatile(vga_font.font_data[font_offset as usize]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.restore_font_registers(
|
||||||
|
plane_mask,
|
||||||
|
sequencer_memory_mode,
|
||||||
|
read_plane_select,
|
||||||
|
graphics_mode,
|
||||||
|
miscellaneous_graphics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore_font_registers(
|
||||||
|
&mut self,
|
||||||
|
plane_mask: u8,
|
||||||
|
sequencer_memory_mode: u8,
|
||||||
|
read_plane_select: u8,
|
||||||
|
graphics_mode: u8,
|
||||||
|
miscellaneous_graphics: u8,
|
||||||
|
) {
|
||||||
|
self.sequencer_registers
|
||||||
|
.write(SequencerIndex::PlaneMask, plane_mask);
|
||||||
|
self.sequencer_registers
|
||||||
|
.write(SequencerIndex::MemoryMode, sequencer_memory_mode);
|
||||||
|
self.graphics_controller_registers
|
||||||
|
.write(GraphicsControllerIndex::ReadPlaneSelect, read_plane_select);
|
||||||
|
self.graphics_controller_registers
|
||||||
|
.write(GraphicsControllerIndex::GraphicsMode, graphics_mode);
|
||||||
|
self.graphics_controller_registers.write(
|
||||||
|
GraphicsControllerIndex::Miscellaneous,
|
||||||
|
miscellaneous_graphics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_font_registers(&mut self) -> (u8, u8, u8, u8, u8) {
|
||||||
|
(
|
||||||
|
self.sequencer_registers.read(SequencerIndex::PlaneMask),
|
||||||
|
self.sequencer_registers.read(SequencerIndex::MemoryMode),
|
||||||
|
self.graphics_controller_registers
|
||||||
|
.read(GraphicsControllerIndex::ReadPlaneSelect),
|
||||||
|
self.graphics_controller_registers
|
||||||
|
.read(GraphicsControllerIndex::GraphicsMode),
|
||||||
|
self.graphics_controller_registers
|
||||||
|
.read(GraphicsControllerIndex::Miscellaneous),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns on the given `Plane` in the vga graphics card.
|
||||||
|
pub fn set_plane(&mut self, plane: Plane) {
|
||||||
|
let mut plane = u8::from(plane);
|
||||||
|
|
||||||
|
plane &= 0x3;
|
||||||
|
|
||||||
|
self.graphics_controller_registers
|
||||||
|
.write(GraphicsControllerIndex::ReadPlaneSelect, plane);
|
||||||
|
self.sequencer_registers
|
||||||
|
.write(SequencerIndex::PlaneMask, 0x1 << plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_registers(&mut self, configuration: &VgaConfiguration) {
|
||||||
|
let emulation_mode = self.get_emulation_mode();
|
||||||
|
|
||||||
|
// Set miscellaneous output
|
||||||
|
self.general_registers
|
||||||
|
.write_msr(configuration.miscellaneous_output);
|
||||||
|
|
||||||
|
// Set the sequencer registers.
|
||||||
|
for (index, value) in configuration.sequencer_registers {
|
||||||
|
self.sequencer_registers.write(*index, *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock the crtc registers.
|
||||||
|
self.unlock_crtc_registers(emulation_mode);
|
||||||
|
|
||||||
|
// Set the crtc registers.
|
||||||
|
for (index, value) in configuration.crtc_controller_registers {
|
||||||
|
self.crtc_controller_registers
|
||||||
|
.write(emulation_mode, *index, *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the grx registers.
|
||||||
|
for (index, value) in configuration.graphics_controller_registers {
|
||||||
|
self.graphics_controller_registers.write(*index, *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blank the screen so the palette registers are unlocked.
|
||||||
|
self.attribute_controller_registers
|
||||||
|
.blank_screen(emulation_mode);
|
||||||
|
|
||||||
|
// Set the arx registers.
|
||||||
|
for (index, value) in configuration.attribute_controller_registers {
|
||||||
|
self.attribute_controller_registers
|
||||||
|
.write(emulation_mode, *index, *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unblank the screen so the palette registers are locked.
|
||||||
|
self.attribute_controller_registers
|
||||||
|
.unblank_screen(emulation_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the video card to Mode 40x25.
|
||||||
|
fn set_video_mode_40x25(&mut self) {
|
||||||
|
self.set_registers(&MODE_40X25_CONFIGURATION);
|
||||||
|
self.load_font(&TEXT_8X16_FONT);
|
||||||
|
self.most_recent_video_mode = Some(VideoMode::Mode40x25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the video card to Mode 40x50.
|
||||||
|
fn set_video_mode_40x50(&mut self) {
|
||||||
|
self.set_registers(&MODE_40X50_CONFIGURATION);
|
||||||
|
self.load_font(&TEXT_8X8_FONT);
|
||||||
|
self.most_recent_video_mode = Some(VideoMode::Mode40x50);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the video card to Mode 80x25.
|
||||||
|
fn set_video_mode_80x25(&mut self) {
|
||||||
|
self.set_registers(&MODE_80X25_CONFIGURATION);
|
||||||
|
self.load_font(&TEXT_8X16_FONT);
|
||||||
|
self.most_recent_video_mode = Some(VideoMode::Mode80x25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the video card to Mode 640x480x16.
|
||||||
|
fn set_video_mode_640x480x16(&mut self) {
|
||||||
|
self.set_registers(&MODE_640X480X16_CONFIGURATION);
|
||||||
|
self.most_recent_video_mode = Some(VideoMode::Mode640x480x16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unlocks the CRTC registers by setting bit 7 to 0 `(value & 0x7F)`.
|
||||||
|
///
|
||||||
|
/// `Protect Registers [0:7]`: Note that the ability to write to Bit 4 of the Overflow Register (CR07)
|
||||||
|
/// is not affected by this bit (i.e., bit 4 of the Overflow Register is always writeable).
|
||||||
|
///
|
||||||
|
/// 0 = Enable writes to registers `CR[00:07]`
|
||||||
|
///
|
||||||
|
/// 1 = Disable writes to registers `CR[00:07]`
|
||||||
|
fn unlock_crtc_registers(&mut self, emulation_mode: EmulationMode) {
|
||||||
|
// Setting bit 7 to 1 used to be required for `VGA`, but says it's
|
||||||
|
// ignored in modern hardware. Setting it to 1 just to be safe for older
|
||||||
|
// hardware. More information can be found here
|
||||||
|
// https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-hsw-display.pdf
|
||||||
|
// under `CR03 - Horizontal Blanking End Register`.
|
||||||
|
let horizontal_blanking_end = self
|
||||||
|
.crtc_controller_registers
|
||||||
|
.read(emulation_mode, CrtcControllerIndex::HorizontalBlankingEnd);
|
||||||
|
self.crtc_controller_registers.write(
|
||||||
|
emulation_mode,
|
||||||
|
CrtcControllerIndex::HorizontalBlankingEnd,
|
||||||
|
horizontal_blanking_end | 0x80,
|
||||||
|
);
|
||||||
|
|
||||||
|
let vertical_sync_end = self
|
||||||
|
.crtc_controller_registers
|
||||||
|
.read(emulation_mode, CrtcControllerIndex::VerticalSyncEnd);
|
||||||
|
self.crtc_controller_registers.write(
|
||||||
|
emulation_mode,
|
||||||
|
CrtcControllerIndex::VerticalSyncEnd,
|
||||||
|
vertical_sync_end & 0x7F,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
52
src/vga_colors.rs
Normal file
52
src/vga_colors.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
//! Common color structures used in vga.
|
||||||
|
|
||||||
|
/// Represents a 16 bit color used for vga display.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum Color16Bit {
|
||||||
|
/// Represents the color `Black (0x0)`.
|
||||||
|
Black = 0x0,
|
||||||
|
/// Represents the color `Blue (0x1)`.
|
||||||
|
Blue = 0x1,
|
||||||
|
/// Represents the color `Green (0x2)`.
|
||||||
|
Green = 0x2,
|
||||||
|
/// Represents the color `Cyan (0x3)`.
|
||||||
|
Cyan = 0x3,
|
||||||
|
/// Represents the color `Red (0x4)`.
|
||||||
|
Red = 0x4,
|
||||||
|
/// Represents the color `Magenta (0x5)`.
|
||||||
|
Magenta = 0x5,
|
||||||
|
/// Represents the color `Brown (0x6)`.
|
||||||
|
Brown = 0x6,
|
||||||
|
/// Represents the color `LightGrey (0x7)`.
|
||||||
|
LightGrey = 0x7,
|
||||||
|
/// Represents the color `DarkGrey (0x8)`.
|
||||||
|
DarkGrey = 0x8,
|
||||||
|
/// Represents the color `LightBlue (0x9)`.
|
||||||
|
LightBlue = 0x9,
|
||||||
|
/// Represents the color `LightGreen (0xA)`.
|
||||||
|
LightGreen = 0xA,
|
||||||
|
/// Represents the color `LightCyan (0xB)`.
|
||||||
|
LightCyan = 0xB,
|
||||||
|
/// Represents the color `LightRed (0xC)`.
|
||||||
|
LightRed = 0xC,
|
||||||
|
/// Represents the color `Pink (0xD)`.
|
||||||
|
Pink = 0xD,
|
||||||
|
/// Represents the color `Yellow (0xE)`.
|
||||||
|
Yellow = 0xE,
|
||||||
|
/// Represents the color `White (0xF)`.
|
||||||
|
White = 0xF,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a color for vga text modes.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct TextModeColor(u8);
|
||||||
|
|
||||||
|
impl TextModeColor {
|
||||||
|
/// Returns a new `TextModeColor` given the specified `foreground`
|
||||||
|
/// and `background` color.
|
||||||
|
pub const fn new(foreground: Color16Bit, background: Color16Bit) -> TextModeColor {
|
||||||
|
TextModeColor((background as u8) << 4 | (foreground as u8))
|
||||||
|
}
|
||||||
|
}
|
310
src/vga_configurations.rs
Normal file
310
src/vga_configurations.rs
Normal file
|
@ -0,0 +1,310 @@
|
||||||
|
use super::vga_registers::{
|
||||||
|
AttributeControllerIndex, CrtcControllerIndex, GraphicsControllerIndex, SequencerIndex,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a set of vga registers for a given mode.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct VgaConfiguration {
|
||||||
|
pub miscellaneous_output: u8,
|
||||||
|
pub sequencer_registers: &'static [(SequencerIndex, u8)],
|
||||||
|
pub crtc_controller_registers: &'static [(CrtcControllerIndex, u8)],
|
||||||
|
pub graphics_controller_registers: &'static [(GraphicsControllerIndex, u8)],
|
||||||
|
pub attribute_controller_registers: &'static [(AttributeControllerIndex, u8)],
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register values for Vga mode 40x25 Text.
|
||||||
|
pub const MODE_40X25_CONFIGURATION: VgaConfiguration = VgaConfiguration {
|
||||||
|
// Configuration values acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
|
||||||
|
miscellaneous_output: 0x67,
|
||||||
|
sequencer_registers: &[
|
||||||
|
(SequencerIndex::SequencerReset, 0x03),
|
||||||
|
(SequencerIndex::ClockingMode, 0x08),
|
||||||
|
(SequencerIndex::PlaneMask, 0x03),
|
||||||
|
(SequencerIndex::CharacterFont, 0x00),
|
||||||
|
(SequencerIndex::MemoryMode, 0x02),
|
||||||
|
],
|
||||||
|
crtc_controller_registers: &[
|
||||||
|
(CrtcControllerIndex::HorizontalTotal, 0x2D),
|
||||||
|
(CrtcControllerIndex::HorizontalDisplayEnableEnd, 0x27),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingStart, 0x28),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingEnd, 0x90),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncStart, 0x2B),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncEnd, 0xA0),
|
||||||
|
(CrtcControllerIndex::VeritcalTotal, 0xBF),
|
||||||
|
(CrtcControllerIndex::Overflow, 0x1F),
|
||||||
|
(CrtcControllerIndex::PresetRowScan, 0x00),
|
||||||
|
(CrtcControllerIndex::MaximumScanLine, 0x4F),
|
||||||
|
(CrtcControllerIndex::TextCursorStart, 0x0A),
|
||||||
|
(CrtcControllerIndex::TextCursorEnd, 0x20),
|
||||||
|
(CrtcControllerIndex::StartAddressHigh, 0x00),
|
||||||
|
(CrtcControllerIndex::StartAddressLow, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationHigh, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationLow, 0xA0),
|
||||||
|
(CrtcControllerIndex::VerticalSyncStart, 0x9C),
|
||||||
|
(CrtcControllerIndex::VerticalSyncEnd, 0x8E),
|
||||||
|
(CrtcControllerIndex::VerticalDisplayEnableEnd, 0x8F),
|
||||||
|
(CrtcControllerIndex::Offset, 0x14),
|
||||||
|
(CrtcControllerIndex::UnderlineLocationRegister, 0x1F),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingStart, 0x96),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingEnd, 0xB9),
|
||||||
|
(CrtcControllerIndex::ModeControl, 0xA3),
|
||||||
|
(CrtcControllerIndex::LineCompare, 0xFF),
|
||||||
|
],
|
||||||
|
graphics_controller_registers: &[
|
||||||
|
(GraphicsControllerIndex::SetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::EnableSetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::ColorCompare, 0x00),
|
||||||
|
(GraphicsControllerIndex::DataRotate, 0x00),
|
||||||
|
(GraphicsControllerIndex::ReadPlaneSelect, 0x00),
|
||||||
|
(GraphicsControllerIndex::GraphicsMode, 0x10),
|
||||||
|
(GraphicsControllerIndex::Miscellaneous, 0x0E),
|
||||||
|
(GraphicsControllerIndex::ColorDontCare, 0x00),
|
||||||
|
(GraphicsControllerIndex::BitMask, 0xFF),
|
||||||
|
],
|
||||||
|
attribute_controller_registers: &[
|
||||||
|
(AttributeControllerIndex::PaletteRegister0, 0x00),
|
||||||
|
(AttributeControllerIndex::PaletteRegister1, 0x01),
|
||||||
|
(AttributeControllerIndex::PaletteRegister2, 0x02),
|
||||||
|
(AttributeControllerIndex::PaletteRegister3, 0x03),
|
||||||
|
(AttributeControllerIndex::PaletteRegister4, 0x04),
|
||||||
|
(AttributeControllerIndex::PaletteRegister5, 0x05),
|
||||||
|
(AttributeControllerIndex::PaletteRegister6, 0x14),
|
||||||
|
(AttributeControllerIndex::PaletteRegister7, 0x07),
|
||||||
|
(AttributeControllerIndex::PaletteRegister8, 0x38),
|
||||||
|
(AttributeControllerIndex::PaletteRegister9, 0x39),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterA, 0x3A),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterB, 0x3B),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterC, 0x3C),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterD, 0x3D),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterE, 0x3E),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterF, 0x3F),
|
||||||
|
(AttributeControllerIndex::ModeControl, 0x0C),
|
||||||
|
(AttributeControllerIndex::OverscanColor, 0x00),
|
||||||
|
(AttributeControllerIndex::MemoryPlaneEnable, 0x0F),
|
||||||
|
(AttributeControllerIndex::HorizontalPixelPanning, 0x08),
|
||||||
|
(AttributeControllerIndex::ColorSelect, 0x00),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Register values for Vga mode 40x50 Text.
|
||||||
|
pub const MODE_40X50_CONFIGURATION: VgaConfiguration = VgaConfiguration {
|
||||||
|
// Configuration values acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
|
||||||
|
miscellaneous_output: 0x67,
|
||||||
|
sequencer_registers: &[
|
||||||
|
(SequencerIndex::SequencerReset, 0x03),
|
||||||
|
(SequencerIndex::ClockingMode, 0x08),
|
||||||
|
(SequencerIndex::PlaneMask, 0x03),
|
||||||
|
(SequencerIndex::CharacterFont, 0x00),
|
||||||
|
(SequencerIndex::MemoryMode, 0x02),
|
||||||
|
],
|
||||||
|
crtc_controller_registers: &[
|
||||||
|
(CrtcControllerIndex::HorizontalTotal, 0x2D),
|
||||||
|
(CrtcControllerIndex::HorizontalDisplayEnableEnd, 0x27),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingStart, 0x28),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingEnd, 0x90),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncStart, 0x2B),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncEnd, 0xA0),
|
||||||
|
(CrtcControllerIndex::VeritcalTotal, 0xBF),
|
||||||
|
(CrtcControllerIndex::Overflow, 0x1F),
|
||||||
|
(CrtcControllerIndex::PresetRowScan, 0x00),
|
||||||
|
(CrtcControllerIndex::MaximumScanLine, 0x47),
|
||||||
|
(CrtcControllerIndex::TextCursorStart, 0x0A),
|
||||||
|
(CrtcControllerIndex::TextCursorEnd, 0x20),
|
||||||
|
(CrtcControllerIndex::StartAddressHigh, 0x00),
|
||||||
|
(CrtcControllerIndex::StartAddressLow, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationHigh, 0x04),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationLow, 0x60),
|
||||||
|
(CrtcControllerIndex::VerticalSyncStart, 0x9C),
|
||||||
|
(CrtcControllerIndex::VerticalSyncEnd, 0x8E),
|
||||||
|
(CrtcControllerIndex::VerticalDisplayEnableEnd, 0x8F),
|
||||||
|
(CrtcControllerIndex::Offset, 0x14),
|
||||||
|
(CrtcControllerIndex::UnderlineLocationRegister, 0x1F),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingStart, 0x96),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingEnd, 0xB9),
|
||||||
|
(CrtcControllerIndex::ModeControl, 0xA3),
|
||||||
|
(CrtcControllerIndex::LineCompare, 0xFF),
|
||||||
|
],
|
||||||
|
graphics_controller_registers: &[
|
||||||
|
(GraphicsControllerIndex::SetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::EnableSetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::ColorCompare, 0x00),
|
||||||
|
(GraphicsControllerIndex::DataRotate, 0x00),
|
||||||
|
(GraphicsControllerIndex::ReadPlaneSelect, 0x00),
|
||||||
|
(GraphicsControllerIndex::GraphicsMode, 0x10),
|
||||||
|
(GraphicsControllerIndex::Miscellaneous, 0x0E),
|
||||||
|
(GraphicsControllerIndex::ColorDontCare, 0x00),
|
||||||
|
(GraphicsControllerIndex::BitMask, 0xFF),
|
||||||
|
],
|
||||||
|
attribute_controller_registers: &[
|
||||||
|
(AttributeControllerIndex::PaletteRegister0, 0x00),
|
||||||
|
(AttributeControllerIndex::PaletteRegister1, 0x01),
|
||||||
|
(AttributeControllerIndex::PaletteRegister2, 0x02),
|
||||||
|
(AttributeControllerIndex::PaletteRegister3, 0x03),
|
||||||
|
(AttributeControllerIndex::PaletteRegister4, 0x04),
|
||||||
|
(AttributeControllerIndex::PaletteRegister5, 0x05),
|
||||||
|
(AttributeControllerIndex::PaletteRegister6, 0x14),
|
||||||
|
(AttributeControllerIndex::PaletteRegister7, 0x07),
|
||||||
|
(AttributeControllerIndex::PaletteRegister8, 0x38),
|
||||||
|
(AttributeControllerIndex::PaletteRegister9, 0x39),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterA, 0x3A),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterB, 0x3B),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterC, 0x3C),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterD, 0x3D),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterE, 0x3E),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterF, 0x3F),
|
||||||
|
(AttributeControllerIndex::ModeControl, 0x0C),
|
||||||
|
(AttributeControllerIndex::OverscanColor, 0x00),
|
||||||
|
(AttributeControllerIndex::MemoryPlaneEnable, 0x0F),
|
||||||
|
(AttributeControllerIndex::HorizontalPixelPanning, 0x08),
|
||||||
|
(AttributeControllerIndex::ColorSelect, 0x00),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Register values for Vga mode 80x25 Text.
|
||||||
|
pub const MODE_80X25_CONFIGURATION: VgaConfiguration = VgaConfiguration {
|
||||||
|
// Configuration values acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
|
||||||
|
miscellaneous_output: 0x67,
|
||||||
|
sequencer_registers: &[
|
||||||
|
(SequencerIndex::SequencerReset, 0x03),
|
||||||
|
(SequencerIndex::ClockingMode, 0x00),
|
||||||
|
(SequencerIndex::PlaneMask, 0x03),
|
||||||
|
(SequencerIndex::CharacterFont, 0x00),
|
||||||
|
(SequencerIndex::MemoryMode, 0x02),
|
||||||
|
],
|
||||||
|
crtc_controller_registers: &[
|
||||||
|
(CrtcControllerIndex::HorizontalTotal, 0x5F),
|
||||||
|
(CrtcControllerIndex::HorizontalDisplayEnableEnd, 0x4F),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingStart, 0x50),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingEnd, 0x82),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncStart, 0x55),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncEnd, 0x81),
|
||||||
|
(CrtcControllerIndex::VeritcalTotal, 0xBF),
|
||||||
|
(CrtcControllerIndex::Overflow, 0x1F),
|
||||||
|
(CrtcControllerIndex::PresetRowScan, 0x00),
|
||||||
|
(CrtcControllerIndex::MaximumScanLine, 0x4F),
|
||||||
|
(CrtcControllerIndex::TextCursorStart, 0x0D),
|
||||||
|
(CrtcControllerIndex::TextCursorEnd, 0x0E),
|
||||||
|
(CrtcControllerIndex::StartAddressHigh, 0x00),
|
||||||
|
(CrtcControllerIndex::StartAddressLow, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationHigh, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationLow, 0x50),
|
||||||
|
(CrtcControllerIndex::VerticalSyncStart, 0x9C),
|
||||||
|
(CrtcControllerIndex::VerticalSyncEnd, 0x0E),
|
||||||
|
(CrtcControllerIndex::VerticalDisplayEnableEnd, 0x8F),
|
||||||
|
(CrtcControllerIndex::Offset, 0x28),
|
||||||
|
(CrtcControllerIndex::UnderlineLocationRegister, 0x1F),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingStart, 0x96),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingEnd, 0xB9),
|
||||||
|
(CrtcControllerIndex::ModeControl, 0xA3),
|
||||||
|
(CrtcControllerIndex::LineCompare, 0xFF),
|
||||||
|
],
|
||||||
|
graphics_controller_registers: &[
|
||||||
|
(GraphicsControllerIndex::SetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::EnableSetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::ColorCompare, 0x00),
|
||||||
|
(GraphicsControllerIndex::DataRotate, 0x00),
|
||||||
|
(GraphicsControllerIndex::ReadPlaneSelect, 0x00),
|
||||||
|
(GraphicsControllerIndex::GraphicsMode, 0x10),
|
||||||
|
(GraphicsControllerIndex::Miscellaneous, 0x0E),
|
||||||
|
(GraphicsControllerIndex::ColorDontCare, 0x00),
|
||||||
|
(GraphicsControllerIndex::BitMask, 0xFF),
|
||||||
|
],
|
||||||
|
attribute_controller_registers: &[
|
||||||
|
(AttributeControllerIndex::PaletteRegister0, 0x00),
|
||||||
|
(AttributeControllerIndex::PaletteRegister1, 0x01),
|
||||||
|
(AttributeControllerIndex::PaletteRegister2, 0x02),
|
||||||
|
(AttributeControllerIndex::PaletteRegister3, 0x03),
|
||||||
|
(AttributeControllerIndex::PaletteRegister4, 0x04),
|
||||||
|
(AttributeControllerIndex::PaletteRegister5, 0x05),
|
||||||
|
(AttributeControllerIndex::PaletteRegister6, 0x14),
|
||||||
|
(AttributeControllerIndex::PaletteRegister7, 0x07),
|
||||||
|
(AttributeControllerIndex::PaletteRegister8, 0x38),
|
||||||
|
(AttributeControllerIndex::PaletteRegister9, 0x39),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterA, 0x3A),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterB, 0x3B),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterC, 0x3C),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterD, 0x3D),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterE, 0x3E),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterF, 0x3F),
|
||||||
|
(AttributeControllerIndex::ModeControl, 0x0C),
|
||||||
|
(AttributeControllerIndex::OverscanColor, 0x00),
|
||||||
|
(AttributeControllerIndex::MemoryPlaneEnable, 0x0F),
|
||||||
|
(AttributeControllerIndex::HorizontalPixelPanning, 0x08),
|
||||||
|
(AttributeControllerIndex::ColorSelect, 0x00),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Register values for Vga mode 640x480x16 Graphics.
|
||||||
|
pub const MODE_640X480X16_CONFIGURATION: VgaConfiguration = VgaConfiguration {
|
||||||
|
// Configuration values acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
|
||||||
|
// and https://forum.osdev.org/viewtopic.php?f=1&t=20137&hilit=640x480x16
|
||||||
|
miscellaneous_output: 0xE3,
|
||||||
|
sequencer_registers: &[
|
||||||
|
(SequencerIndex::SequencerReset, 0x03),
|
||||||
|
(SequencerIndex::ClockingMode, 0x01),
|
||||||
|
(SequencerIndex::PlaneMask, 0x08),
|
||||||
|
(SequencerIndex::CharacterFont, 0x00),
|
||||||
|
(SequencerIndex::MemoryMode, 0x06),
|
||||||
|
],
|
||||||
|
crtc_controller_registers: &[
|
||||||
|
(CrtcControllerIndex::HorizontalTotal, 0x5F),
|
||||||
|
(CrtcControllerIndex::HorizontalDisplayEnableEnd, 0x4F),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingStart, 0x50),
|
||||||
|
(CrtcControllerIndex::HorizontalBlankingEnd, 0x82),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncStart, 0x54),
|
||||||
|
(CrtcControllerIndex::HorizontalSyncEnd, 0x80),
|
||||||
|
(CrtcControllerIndex::VeritcalTotal, 0x0B),
|
||||||
|
(CrtcControllerIndex::Overflow, 0x3E),
|
||||||
|
(CrtcControllerIndex::PresetRowScan, 0x00),
|
||||||
|
(CrtcControllerIndex::MaximumScanLine, 0x40),
|
||||||
|
(CrtcControllerIndex::TextCursorStart, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorEnd, 0x00),
|
||||||
|
(CrtcControllerIndex::StartAddressHigh, 0x00),
|
||||||
|
(CrtcControllerIndex::StartAddressLow, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationHigh, 0x00),
|
||||||
|
(CrtcControllerIndex::TextCursorLocationLow, 0x00),
|
||||||
|
(CrtcControllerIndex::VerticalSyncStart, 0xEA),
|
||||||
|
(CrtcControllerIndex::VerticalSyncEnd, 0x0C),
|
||||||
|
(CrtcControllerIndex::VerticalDisplayEnableEnd, 0xDF),
|
||||||
|
(CrtcControllerIndex::Offset, 0x28),
|
||||||
|
(CrtcControllerIndex::UnderlineLocationRegister, 0x00),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingStart, 0xE7),
|
||||||
|
(CrtcControllerIndex::VerticalBlankingEnd, 0x04),
|
||||||
|
(CrtcControllerIndex::ModeControl, 0xE3),
|
||||||
|
(CrtcControllerIndex::LineCompare, 0xFF),
|
||||||
|
],
|
||||||
|
graphics_controller_registers: &[
|
||||||
|
(GraphicsControllerIndex::SetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::EnableSetReset, 0x00),
|
||||||
|
(GraphicsControllerIndex::ColorCompare, 0x00),
|
||||||
|
(GraphicsControllerIndex::DataRotate, 0x00),
|
||||||
|
(GraphicsControllerIndex::ReadPlaneSelect, 0x03),
|
||||||
|
(GraphicsControllerIndex::GraphicsMode, 0x00),
|
||||||
|
(GraphicsControllerIndex::Miscellaneous, 0x05),
|
||||||
|
(GraphicsControllerIndex::ColorDontCare, 0x0F),
|
||||||
|
(GraphicsControllerIndex::BitMask, 0xFF),
|
||||||
|
],
|
||||||
|
attribute_controller_registers: &[
|
||||||
|
(AttributeControllerIndex::PaletteRegister0, 0x00),
|
||||||
|
(AttributeControllerIndex::PaletteRegister1, 0x01),
|
||||||
|
(AttributeControllerIndex::PaletteRegister2, 0x02),
|
||||||
|
(AttributeControllerIndex::PaletteRegister3, 0x03),
|
||||||
|
(AttributeControllerIndex::PaletteRegister4, 0x04),
|
||||||
|
(AttributeControllerIndex::PaletteRegister5, 0x05),
|
||||||
|
(AttributeControllerIndex::PaletteRegister6, 0x14),
|
||||||
|
(AttributeControllerIndex::PaletteRegister7, 0x07),
|
||||||
|
(AttributeControllerIndex::PaletteRegister8, 0x38),
|
||||||
|
(AttributeControllerIndex::PaletteRegister9, 0x39),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterA, 0x3A),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterB, 0x3B),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterC, 0x3C),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterD, 0x3D),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterE, 0x3E),
|
||||||
|
(AttributeControllerIndex::PaletteRegisterF, 0x3F),
|
||||||
|
(AttributeControllerIndex::ModeControl, 0x01),
|
||||||
|
(AttributeControllerIndex::OverscanColor, 0x00),
|
||||||
|
(AttributeControllerIndex::MemoryPlaneEnable, 0x0F),
|
||||||
|
(AttributeControllerIndex::HorizontalPixelPanning, 0x00),
|
||||||
|
(AttributeControllerIndex::ColorSelect, 0x00),
|
||||||
|
],
|
||||||
|
};
|
435
src/vga_fonts.rs
Normal file
435
src/vga_fonts.rs
Normal file
|
@ -0,0 +1,435 @@
|
||||||
|
/// Represents a font to be used for text mode.
|
||||||
|
pub struct VgaFont {
|
||||||
|
pub characters: u16,
|
||||||
|
pub character_height: u16,
|
||||||
|
pub font_data: &'static [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Standard 8x8 character font.
|
||||||
|
pub const TEXT_8X8_FONT: VgaFont = VgaFont {
|
||||||
|
characters: 256,
|
||||||
|
character_height: 8,
|
||||||
|
// Font data acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
|
||||||
|
font_data: &[
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81,
|
||||||
|
0x7E, 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38,
|
||||||
|
0x10, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE,
|
||||||
|
0x92, 0x10, 0x7C, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x00, 0x18, 0x3C,
|
||||||
|
0x3C, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x3C, 0x66,
|
||||||
|
0x42, 0x42, 0x66, 0x3C, 0x00, 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, 0x0F, 0x07,
|
||||||
|
0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x3F,
|
||||||
|
0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
|
||||||
|
0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80,
|
||||||
|
0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E,
|
||||||
|
0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, 0x7F, 0xDB, 0xDB, 0x7B, 0x1B,
|
||||||
|
0x1B, 0x1B, 0x00, 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, 0x18, 0x3C, 0x7E,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x18,
|
||||||
|
0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00,
|
||||||
|
0x18, 0x00, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0xFE,
|
||||||
|
0x6C, 0x6C, 0x00, 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, 0x00, 0xC6, 0xCC, 0x18,
|
||||||
|
0x30, 0x66, 0xC6, 0x00, 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, 0x30, 0x30, 0x60,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30,
|
||||||
|
0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
|
||||||
|
0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
|
||||||
|
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6,
|
||||||
|
0x7C, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x38, 0x60,
|
||||||
|
0xCC, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, 0x1C, 0x3C, 0x6C, 0xCC,
|
||||||
|
0xFE, 0x0C, 0x1E, 0x00, 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, 0x38, 0x60, 0xC0,
|
||||||
|
0xF8, 0xCC, 0xCC, 0x78, 0x00, 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, 0x78, 0xCC,
|
||||||
|
0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
|
||||||
|
0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00,
|
||||||
|
0x18, 0x00, 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x30, 0x78, 0xCC, 0xCC, 0xFC,
|
||||||
|
0xCC, 0xCC, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x3C, 0x66, 0xC0, 0xC0,
|
||||||
|
0xC0, 0x66, 0x3C, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0xFE, 0x62, 0x68,
|
||||||
|
0x78, 0x68, 0x62, 0xFE, 0x00, 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, 0x3C, 0x66,
|
||||||
|
0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, 0x78,
|
||||||
|
0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
|
||||||
|
0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE,
|
||||||
|
0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6,
|
||||||
|
0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x60,
|
||||||
|
0x60, 0xF0, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, 0xFC, 0x66, 0x66, 0x7C,
|
||||||
|
0x6C, 0x66, 0xE6, 0x00, 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, 0xFC, 0xB4, 0x30,
|
||||||
|
0x30, 0x30, 0x30, 0x78, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, 0xCC, 0xCC,
|
||||||
|
0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, 0xC6,
|
||||||
|
0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
|
||||||
|
0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78,
|
||||||
|
0x00, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x78, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xFF, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C,
|
||||||
|
0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x78,
|
||||||
|
0xCC, 0xC0, 0xCC, 0x78, 0x00, 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, 0x00,
|
||||||
|
0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
|
||||||
|
0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC,
|
||||||
|
0x78, 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
|
0x78, 0x00, 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0xB8, 0xCC, 0xCC,
|
||||||
|
0xCC, 0xCC, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0xDC, 0x66,
|
||||||
|
0x66, 0x7C, 0x60, 0xF0, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, 0x00, 0x00, 0xDC,
|
||||||
|
0x76, 0x62, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, 0x10, 0x30,
|
||||||
|
0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
|
||||||
|
0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
|
||||||
|
0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C,
|
||||||
|
0xF8, 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30,
|
||||||
|
0x1C, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xE0, 0x30, 0x30, 0x1C, 0x30,
|
||||||
|
0x30, 0xE0, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C,
|
||||||
|
0xC6, 0xC6, 0xFE, 0x00, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, 0x00, 0xCC, 0x00,
|
||||||
|
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0x81,
|
||||||
|
0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0xE0,
|
||||||
|
0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
|
||||||
|
0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C,
|
||||||
|
0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0,
|
||||||
|
0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x7C, 0x82, 0x38, 0x18, 0x18,
|
||||||
|
0x18, 0x3C, 0x00, 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0xC6, 0x10, 0x7C, 0xC6,
|
||||||
|
0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, 0x1C, 0x00, 0xFC,
|
||||||
|
0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, 0x3E, 0x6C,
|
||||||
|
0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00,
|
||||||
|
0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
|
||||||
|
0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76,
|
||||||
|
0x00, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C,
|
||||||
|
0x18, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0,
|
||||||
|
0x7E, 0x18, 0x18, 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0x30,
|
||||||
|
0xFC, 0x30, 0xFC, 0x30, 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, 0x0E, 0x1B, 0x18,
|
||||||
|
0x3C, 0x18, 0x18, 0xD8, 0x70, 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x38, 0x00,
|
||||||
|
0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00,
|
||||||
|
0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00,
|
||||||
|
0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00,
|
||||||
|
0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x30, 0x66,
|
||||||
|
0x3C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0C,
|
||||||
|
0x0C, 0x00, 0x00, 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, 0xC3, 0xC6, 0xCC, 0xDB,
|
||||||
|
0x37, 0x6D, 0xCF, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x33, 0x66,
|
||||||
|
0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, 0x22, 0x88,
|
||||||
|
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0xDB,
|
||||||
|
0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18,
|
||||||
|
0x18, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36,
|
||||||
|
0x36, 0x36, 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06,
|
||||||
|
0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0xFE, 0x00, 0x00, 0x00, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18,
|
||||||
|
0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00,
|
||||||
|
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
|
||||||
|
0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x36, 0x36,
|
||||||
|
0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18,
|
||||||
|
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
|
||||||
|
0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0,
|
||||||
|
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
|
||||||
|
0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0,
|
||||||
|
0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC,
|
||||||
|
0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
|
||||||
|
0x7C, 0x60, 0xC0, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, 0xFC, 0x30, 0x78, 0xCC,
|
||||||
|
0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6,
|
||||||
|
0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00,
|
||||||
|
0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, 0x38,
|
||||||
|
0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
|
||||||
|
0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E,
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00,
|
||||||
|
0xFC, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0xD8, 0xD8, 0x70, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xDC, 0x00,
|
||||||
|
0x76, 0xDC, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C,
|
||||||
|
0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70,
|
||||||
|
0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Standard 8x16 character font.
|
||||||
|
pub const TEXT_8X16_FONT: VgaFont = VgaFont {
|
||||||
|
characters: 256,
|
||||||
|
character_height: 16,
|
||||||
|
// Font data acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
|
||||||
|
font_data: &[
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, 0x99, 0x81, 0x81, 0x7E, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0xFF, 0x7E, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x99,
|
||||||
|
0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E,
|
||||||
|
0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C,
|
||||||
|
0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7,
|
||||||
|
0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
|
||||||
|
0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x0E,
|
||||||
|
0x1A, 0x32, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30, 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0xFE, 0x3E, 0x1E, 0x0E, 0x06, 0x02, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66,
|
||||||
|
0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B,
|
||||||
|
0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, 0x6C,
|
||||||
|
0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x28, 0x6C, 0xFE, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE,
|
||||||
|
0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x86,
|
||||||
|
0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18,
|
||||||
|
0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76,
|
||||||
|
0xDC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30,
|
||||||
|
0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
|
||||||
|
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xCE, 0xD6, 0xD6, 0xE6, 0xC6, 0xC6, 0x7C,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0,
|
||||||
|
0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06,
|
||||||
|
0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE,
|
||||||
|
0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC,
|
||||||
|
0x0E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0,
|
||||||
|
0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x06,
|
||||||
|
0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6,
|
||||||
|
0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
|
||||||
|
0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0,
|
||||||
|
0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6,
|
||||||
|
0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0,
|
||||||
|
0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68,
|
||||||
|
0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x62,
|
||||||
|
0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66,
|
||||||
|
0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C,
|
||||||
|
0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
|
||||||
|
0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C,
|
||||||
|
0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38,
|
||||||
|
0x0C, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xC6, 0xC6, 0x6C, 0x6C, 0x38, 0x38, 0x6C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C,
|
||||||
|
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
|
||||||
|
0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0C, 0x0C,
|
||||||
|
0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
|
||||||
|
0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, 0x00,
|
||||||
|
0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66,
|
||||||
|
0x3C, 0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xD6,
|
||||||
|
0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
|
||||||
|
0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC,
|
||||||
|
0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC,
|
||||||
|
0x76, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
|
||||||
|
0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C,
|
||||||
|
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6,
|
||||||
|
0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0,
|
||||||
|
0xC0, 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0x00, 0xCC,
|
||||||
|
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x00,
|
||||||
|
0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C,
|
||||||
|
0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC,
|
||||||
|
0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
|
||||||
|
0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x10, 0x38, 0x6C, 0xC6, 0xC6,
|
||||||
|
0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6,
|
||||||
|
0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xFE, 0x66,
|
||||||
|
0x60, 0x7C, 0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xCC, 0x76, 0x36, 0x7E, 0xD8, 0xD8, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x6C,
|
||||||
|
0xCC, 0xCC, 0xFE, 0xCC, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
|
||||||
|
0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06,
|
||||||
|
0x0C, 0x78, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
|
||||||
|
0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C,
|
||||||
|
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60,
|
||||||
|
0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
|
||||||
|
0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xF8, 0xC4, 0xCC,
|
||||||
|
0xDE, 0xCC, 0xCC, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18,
|
||||||
|
0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00,
|
||||||
|
0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30,
|
||||||
|
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30,
|
||||||
|
0x60, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xC0, 0xC6, 0xC6, 0x7C,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0x06, 0x06,
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x60,
|
||||||
|
0xCE, 0x93, 0x06, 0x0C, 0x1F, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30,
|
||||||
|
0x66, 0xCE, 0x9A, 0x3F, 0x06, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18,
|
||||||
|
0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
|
||||||
|
0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
|
||||||
|
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xAA, 0x55,
|
||||||
|
0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0xDD, 0x77,
|
||||||
|
0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06,
|
||||||
|
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
|
||||||
|
0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
|
||||||
|
0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||||
|
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F,
|
||||||
|
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0, 0xC0, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xC6, 0xFE,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
|
||||||
|
0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C,
|
||||||
|
0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66,
|
||||||
|
0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
|
||||||
|
0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
|
||||||
|
0xC6, 0x6C, 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x30, 0x18,
|
||||||
|
0x0C, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x03, 0x06, 0x7E, 0xCF, 0xDB, 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x7E,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8,
|
||||||
|
0xD8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, 0x00,
|
||||||
|
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00,
|
||||||
|
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C,
|
||||||
|
0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C,
|
||||||
|
0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
|
||||||
|
0x98, 0x30, 0x60, 0xC8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00,
|
||||||
|
],
|
||||||
|
};
|
385
src/vga_registers.rs
Normal file
385
src/vga_registers.rs
Normal file
|
@ -0,0 +1,385 @@
|
||||||
|
use x86_64::instructions::port::{Port, PortReadOnly, PortWriteOnly};
|
||||||
|
|
||||||
|
const ST00_READ_ADDRESS: u16 = 0x3C2;
|
||||||
|
const ST01_READ_CGA_ADDRESS: u16 = 0x3DA;
|
||||||
|
const ST01_READ_MDA_ADDRESS: u16 = 0x3BA;
|
||||||
|
const FCR_READ_ADDRESS: u16 = 0x3CA;
|
||||||
|
const FCR_CGA_WRITE_ADDRESS: u16 = 0x3DA;
|
||||||
|
const FCR_MDA_WRITE_ADDRESS: u16 = 0x3BA;
|
||||||
|
const MSR_READ_ADDRESS: u16 = 0x3CC;
|
||||||
|
const MSR_WRITE_ADDRESS: u16 = 0x3C2;
|
||||||
|
|
||||||
|
const SRX_INDEX_ADDRESS: u16 = 0x3C4;
|
||||||
|
const SRX_DATA_ADDRESS: u16 = 0x3C5;
|
||||||
|
|
||||||
|
const GRX_INDEX_ADDRESS: u16 = 0x3CE;
|
||||||
|
const GRX_DATA_ADDRESS: u16 = 0x3CF;
|
||||||
|
|
||||||
|
const ARX_INDEX_ADDRESS: u16 = 0x3C0;
|
||||||
|
const ARX_DATA_ADDRESS: u16 = 0x3C1;
|
||||||
|
|
||||||
|
const CRX_INDEX_CGA_ADDRESS: u16 = 0x3D4;
|
||||||
|
const CRX_INDEX_MDA_ADDRESS: u16 = 0x3B4;
|
||||||
|
const CRX_DATA_CGA_ADDRESS: u16 = 0x3D5;
|
||||||
|
const CRX_DATA_MDA_ADDRESS: u16 = 0x3B5;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum EmulationMode {
|
||||||
|
Mda = 0x0,
|
||||||
|
Cga = 0x1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for EmulationMode {
|
||||||
|
fn from(value: u8) -> EmulationMode {
|
||||||
|
match value {
|
||||||
|
0x0 => EmulationMode::Mda,
|
||||||
|
0x1 => EmulationMode::Cga,
|
||||||
|
_ => panic!("{} is an invalid emulation mode", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum SequencerIndex {
|
||||||
|
SequencerReset = 0x0,
|
||||||
|
ClockingMode = 0x1,
|
||||||
|
PlaneMask = 0x2,
|
||||||
|
CharacterFont = 0x3,
|
||||||
|
MemoryMode = 0x4,
|
||||||
|
CounterReset = 0x7,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SequencerIndex> for u8 {
|
||||||
|
fn from(value: SequencerIndex) -> u8 {
|
||||||
|
value as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum GraphicsControllerIndex {
|
||||||
|
SetReset = 0x0,
|
||||||
|
EnableSetReset = 0x1,
|
||||||
|
ColorCompare = 0x2,
|
||||||
|
DataRotate = 0x3,
|
||||||
|
ReadPlaneSelect = 0x4,
|
||||||
|
GraphicsMode = 0x5,
|
||||||
|
Miscellaneous = 0x6,
|
||||||
|
ColorDontCare = 0x7,
|
||||||
|
BitMask = 0x8,
|
||||||
|
AddressMapping = 0x10,
|
||||||
|
PageSelector = 0x11,
|
||||||
|
SoftwareFlags = 0x18,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<GraphicsControllerIndex> for u8 {
|
||||||
|
fn from(value: GraphicsControllerIndex) -> u8 {
|
||||||
|
value as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum AttributeControllerIndex {
|
||||||
|
PaletteRegister0 = 0x00,
|
||||||
|
PaletteRegister1 = 0x01,
|
||||||
|
PaletteRegister2 = 0x02,
|
||||||
|
PaletteRegister3 = 0x03,
|
||||||
|
PaletteRegister4 = 0x04,
|
||||||
|
PaletteRegister5 = 0x05,
|
||||||
|
PaletteRegister6 = 0x06,
|
||||||
|
PaletteRegister7 = 0x07,
|
||||||
|
PaletteRegister8 = 0x08,
|
||||||
|
PaletteRegister9 = 0x09,
|
||||||
|
PaletteRegisterA = 0x0A,
|
||||||
|
PaletteRegisterB = 0x0B,
|
||||||
|
PaletteRegisterC = 0x0C,
|
||||||
|
PaletteRegisterD = 0x0D,
|
||||||
|
PaletteRegisterE = 0x0E,
|
||||||
|
PaletteRegisterF = 0x0F,
|
||||||
|
ModeControl = 0x10,
|
||||||
|
OverscanColor = 0x11,
|
||||||
|
MemoryPlaneEnable = 0x12,
|
||||||
|
HorizontalPixelPanning = 0x13,
|
||||||
|
ColorSelect = 0x14,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AttributeControllerIndex> for u8 {
|
||||||
|
fn from(value: AttributeControllerIndex) -> u8 {
|
||||||
|
value as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum CrtcControllerIndex {
|
||||||
|
HorizontalTotal = 0x00,
|
||||||
|
HorizontalDisplayEnableEnd = 0x01,
|
||||||
|
HorizontalBlankingStart = 0x02,
|
||||||
|
HorizontalBlankingEnd = 0x03,
|
||||||
|
HorizontalSyncStart = 0x04,
|
||||||
|
HorizontalSyncEnd = 0x05,
|
||||||
|
VeritcalTotal = 0x06,
|
||||||
|
Overflow = 0x07,
|
||||||
|
PresetRowScan = 0x08,
|
||||||
|
MaximumScanLine = 0x09,
|
||||||
|
TextCursorStart = 0x0A,
|
||||||
|
TextCursorEnd = 0x0B,
|
||||||
|
StartAddressHigh = 0x0C,
|
||||||
|
StartAddressLow = 0x0D,
|
||||||
|
TextCursorLocationHigh = 0x0E,
|
||||||
|
TextCursorLocationLow = 0x0F,
|
||||||
|
VerticalSyncStart = 0x10,
|
||||||
|
VerticalSyncEnd = 0x11,
|
||||||
|
VerticalDisplayEnableEnd = 0x12,
|
||||||
|
Offset = 0x13,
|
||||||
|
UnderlineLocationRegister = 0x14,
|
||||||
|
VerticalBlankingStart = 0x15,
|
||||||
|
VerticalBlankingEnd = 0x16,
|
||||||
|
ModeControl = 0x17,
|
||||||
|
LineCompare = 0x18,
|
||||||
|
MemoryReadLatchData = 0x22,
|
||||||
|
ToggleStateOfAttributeController = 0x24,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CrtcControllerIndex> for u8 {
|
||||||
|
fn from(value: CrtcControllerIndex) -> u8 {
|
||||||
|
value as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GeneralRegisters {
|
||||||
|
st00_read: PortReadOnly<u8>,
|
||||||
|
st01_read_cga: PortReadOnly<u8>,
|
||||||
|
st01_read_mda: PortReadOnly<u8>,
|
||||||
|
fcr_read: PortReadOnly<u8>,
|
||||||
|
fcr_write_cga: PortWriteOnly<u8>,
|
||||||
|
fcr_write_mda: PortWriteOnly<u8>,
|
||||||
|
msr_read: PortReadOnly<u8>,
|
||||||
|
msr_write: PortWriteOnly<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeneralRegisters {
|
||||||
|
pub fn new() -> GeneralRegisters {
|
||||||
|
GeneralRegisters {
|
||||||
|
st00_read: PortReadOnly::new(ST00_READ_ADDRESS),
|
||||||
|
st01_read_cga: PortReadOnly::new(ST01_READ_CGA_ADDRESS),
|
||||||
|
st01_read_mda: PortReadOnly::new(ST01_READ_MDA_ADDRESS),
|
||||||
|
fcr_read: PortReadOnly::new(FCR_READ_ADDRESS),
|
||||||
|
fcr_write_cga: PortWriteOnly::new(FCR_CGA_WRITE_ADDRESS),
|
||||||
|
fcr_write_mda: PortWriteOnly::new(FCR_MDA_WRITE_ADDRESS),
|
||||||
|
msr_read: PortReadOnly::new(MSR_READ_ADDRESS),
|
||||||
|
msr_write: PortWriteOnly::new(MSR_WRITE_ADDRESS),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_msr(&mut self) -> u8 {
|
||||||
|
unsafe { self.msr_read.read() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_msr(&mut self, value: u8) {
|
||||||
|
unsafe {
|
||||||
|
self.msr_write.write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SequencerRegisters {
|
||||||
|
srx_index: Port<u8>,
|
||||||
|
srx_data: Port<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SequencerRegisters {
|
||||||
|
pub fn new() -> SequencerRegisters {
|
||||||
|
SequencerRegisters {
|
||||||
|
srx_index: Port::new(SRX_INDEX_ADDRESS),
|
||||||
|
srx_data: Port::new(SRX_DATA_ADDRESS),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&mut self, index: SequencerIndex) -> u8 {
|
||||||
|
self.set_index(index);
|
||||||
|
unsafe { self.srx_data.read() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(&mut self, index: SequencerIndex, value: u8) {
|
||||||
|
self.set_index(index);
|
||||||
|
unsafe {
|
||||||
|
self.srx_data.write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_index(&mut self, index: SequencerIndex) {
|
||||||
|
unsafe {
|
||||||
|
self.srx_index.write(u8::from(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GraphicsControllerRegisters {
|
||||||
|
grx_index: Port<u8>,
|
||||||
|
grx_data: Port<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GraphicsControllerRegisters {
|
||||||
|
pub fn new() -> GraphicsControllerRegisters {
|
||||||
|
GraphicsControllerRegisters {
|
||||||
|
grx_index: Port::new(GRX_INDEX_ADDRESS),
|
||||||
|
grx_data: Port::new(GRX_DATA_ADDRESS),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&mut self, index: GraphicsControllerIndex) -> u8 {
|
||||||
|
self.set_index(index);
|
||||||
|
unsafe { self.grx_data.read() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(&mut self, index: GraphicsControllerIndex, value: u8) {
|
||||||
|
self.set_index(index);
|
||||||
|
unsafe {
|
||||||
|
self.grx_data.write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_index(&mut self, index: GraphicsControllerIndex) {
|
||||||
|
unsafe {
|
||||||
|
self.grx_index.write(u8::from(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AttributeControllerRegisters {
|
||||||
|
arx_index: Port<u8>,
|
||||||
|
arx_data: Port<u8>,
|
||||||
|
st01_read_cga: Port<u8>,
|
||||||
|
st01_read_mda: Port<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AttributeControllerRegisters {
|
||||||
|
pub fn new() -> AttributeControllerRegisters {
|
||||||
|
AttributeControllerRegisters {
|
||||||
|
arx_index: Port::new(ARX_INDEX_ADDRESS),
|
||||||
|
arx_data: Port::new(ARX_DATA_ADDRESS),
|
||||||
|
st01_read_cga: Port::new(ST01_READ_CGA_ADDRESS),
|
||||||
|
st01_read_mda: Port::new(ST01_READ_MDA_ADDRESS),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(
|
||||||
|
&mut self,
|
||||||
|
emulation_mode: EmulationMode,
|
||||||
|
index: AttributeControllerIndex,
|
||||||
|
value: u8,
|
||||||
|
) {
|
||||||
|
self.toggle_index(emulation_mode);
|
||||||
|
self.set_index(index);
|
||||||
|
unsafe {
|
||||||
|
self.arx_index.write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_index(&mut self, index: AttributeControllerIndex) {
|
||||||
|
unsafe {
|
||||||
|
self.arx_index.write(u8::from(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toggle_index(&mut self, emulation_mode: EmulationMode) {
|
||||||
|
let st01_read = match emulation_mode {
|
||||||
|
EmulationMode::Cga => &mut self.st01_read_cga,
|
||||||
|
EmulationMode::Mda => &mut self.st01_read_mda,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
st01_read.read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Video Enable. Note that In the VGA standard, this is called the "Palette Address Source" bit.
|
||||||
|
/// Clearing this bit will cause the VGA display data to become all 00 index values. For the default
|
||||||
|
/// palette, this will cause a black screen. The video timing signals continue. Another control bit will
|
||||||
|
/// turn video off and stop the data fetches.
|
||||||
|
///
|
||||||
|
/// 0 = Disable. Attribute controller color registers (AR[00:0F]) can be accessed by the CPU.
|
||||||
|
///
|
||||||
|
/// 1 = Enable. Attribute controller color registers (AR[00:0F]) are inaccessible by the CPU.
|
||||||
|
pub fn blank_screen(&mut self, emulation_mode: EmulationMode) {
|
||||||
|
self.toggle_index(emulation_mode);
|
||||||
|
let arx_index_value = unsafe { self.arx_index.read() };
|
||||||
|
unsafe {
|
||||||
|
self.arx_index.write(arx_index_value & 0xDF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Video Enable. Note that In the VGA standard, this is called the "Palette Address Source" bit.
|
||||||
|
/// Clearing this bit will cause the VGA display data to become all 00 index values. For the default
|
||||||
|
/// palette, this will cause a black screen. The video timing signals continue. Another control bit will
|
||||||
|
/// turn video off and stop the data fetches.
|
||||||
|
///
|
||||||
|
/// 0 = Disable. Attribute controller color registers (AR[00:0F]) can be accessed by the CPU.
|
||||||
|
///
|
||||||
|
/// 1 = Enable. Attribute controller color registers (AR[00:0F]) are inaccessible by the CPU.
|
||||||
|
pub fn unblank_screen(&mut self, emulation_mode: EmulationMode) {
|
||||||
|
self.toggle_index(emulation_mode);
|
||||||
|
let arx_index_value = unsafe { self.arx_index.read() };
|
||||||
|
unsafe {
|
||||||
|
self.arx_index.write(arx_index_value | 0x20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CrtcControllerRegisters {
|
||||||
|
crx_index_cga: Port<u8>,
|
||||||
|
crx_index_mda: Port<u8>,
|
||||||
|
crx_data_cga: Port<u8>,
|
||||||
|
crx_data_mda: Port<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CrtcControllerRegisters {
|
||||||
|
pub fn new() -> CrtcControllerRegisters {
|
||||||
|
CrtcControllerRegisters {
|
||||||
|
crx_index_cga: Port::new(CRX_INDEX_CGA_ADDRESS),
|
||||||
|
crx_index_mda: Port::new(CRX_INDEX_MDA_ADDRESS),
|
||||||
|
crx_data_cga: Port::new(CRX_DATA_CGA_ADDRESS),
|
||||||
|
crx_data_mda: Port::new(CRX_DATA_MDA_ADDRESS),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&mut self, emulation_mode: EmulationMode, index: CrtcControllerIndex) -> u8 {
|
||||||
|
self.set_index(emulation_mode, index);
|
||||||
|
unsafe { self.get_data_port(emulation_mode).read() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(&mut self, emulation_mode: EmulationMode, index: CrtcControllerIndex, value: u8) {
|
||||||
|
self.set_index(emulation_mode, index);
|
||||||
|
unsafe {
|
||||||
|
self.get_data_port(emulation_mode).write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_index(&mut self, emulation_mode: EmulationMode, index: CrtcControllerIndex) {
|
||||||
|
unsafe {
|
||||||
|
self.get_index_port(emulation_mode).write(u8::from(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_data_port(&mut self, emulation_mode: EmulationMode) -> &mut Port<u8> {
|
||||||
|
match emulation_mode {
|
||||||
|
EmulationMode::Cga => &mut self.crx_data_cga,
|
||||||
|
EmulationMode::Mda => &mut self.crx_data_mda,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_index_port(&mut self, emulation_mode: EmulationMode) -> &mut Port<u8> {
|
||||||
|
match emulation_mode {
|
||||||
|
EmulationMode::Cga => &mut self.crx_index_cga,
|
||||||
|
EmulationMode::Mda => &mut self.crx_index_mda,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue