I an trying to learn some operating system development. I have it
booting and printing text to the screen. However, I have an issue with
updating the hardware cursor. It does not update. I can provide the
whole sources if need be, but i believe i am missunderstanding
something in Ada. The tutorial I am learning from is written in C and
for the most part its pretty easy converting it to ada. The code i'm
having an issue with follows. The im****tant parts are out****tb in the
c files and Update_Cursor in the vga package body.
// this is the way the tutorial updated the hardware cursor. My
version is
// in the Vga package called Update_Cursor
// void move_csr(void)
// {
// unsigned temp;
// temp = csr_y * 80 + csr_x; // csr_y and csr_x are global
variables
//
// out****tb(0x3D4, 14);
// out****tb(0x3D5, temp >> 8);
// out****tb(0x3D4, 15);
// out****tb(0x3D5, temp);
// }
// ****t.h
#ifndef __****T_H
#define __****T_H
extern unsigned char in****tb (unsigned short _****t);
extern void out****tb (unsigned short _****t, usigned char _data);
// ****t.c
#include "****t.h"
unsigned char in****tb (unsigned short _****t)
{
unsigned char rv;
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_****t));
return rv;
}
unsigned char out****tb (unsigned short _****t, unsigned char _data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_****t), "a" (_data));
}
-- vga.ads
package Vga is
-----------------------------------------------------------------------------
type Color is (
Black, -- 0000
Blue, -- 0001
Green, -- 0010
Cyan, -- 0011
Red, -- 0100
Magenta, -- 0101
Brown, -- 0110
Light_Grey, -- 0111
Dark_Grey, -- 1000
Light_Blue, -- 1001
Light_Green, -- 1010
Light_Cyan, -- 1011
Light_Red, -- 1100
Light_Magenta, -- 1101
Light_Brown, -- 1110
White); -- 1111
for Color use (
Black => 16#0#,
Blue => 16#1#,
Green => 16#2#,
Cyan => 16#3#,
Red => 16#4#,
Magenta => 16#5#,
Brown => 16#6#,
Light_Grey => 16#7#,
Dark_Grey => 16#8#,
Light_Blue => 16#9#,
Light_Green => 16#A#,
Light_Cyan => 16#B#,
Light_Red => 16#C#,
Light_Magenta => 16#D#,
Light_Brown => 16#E#,
White => 16#F#);
for Color'Size use 4;
-----------------------------------------------------------------------------
subtype Background_Color is Color range Color'First..Light_Grey;
subtype Row is Positive range Positive'First..25;
subtype Column is Positive range Positive'First..80;
-----------------------------------------------------------------------------
type Video_Console is
record
Foreground : Color := White;
Background : Background_Color := Black;
Row : Vga.Row := Vga.Row'First;
Column : Vga.Column := Vga.Column'First;
end record;
procedure Clear(Console : in out Video_Console);
procedure Put(Console : in out Video_Console; S : String);
-----------------------------------------------------------------------------
end Vga;
-- vga.adb
with System;
package body Vga is
-----------------------------------------------------------------------------
type Video_Character is
record
Foreground : Color;
Background : Background_Color;
Glyph : Character;
end record;
for Video_Character use
record
Foreground at 0 range 8..11;
Background at 0 range 12..15;
Glyph at 0 range 0..7;
end record;
for Video_Character'Size use 16;
-----------------------------------------------------------------------------
Video_Memory : array (Row'Range, Column'Range) of Video_Character;
for Video_Memory'Address use System'To_Address (16#000B8000#);
pragma Im****t (Ada, Video_Memory);
-----------------------------------------------------------------------------
procedure Update_Cursor (Console : Video_Console) is
procedure Out****tB (****t : Natural; Data : Natural);
pragma Im****t(C, Out****tB, "out****tB");
Data : Natural := Console.Column * 80 + Console.Row;
begin
Out****tB ( 16#3D4#, 14);
Out****tB ( 16#3D5#, Data / 2 ** 8);
Out****tB ( 16#3D4#, 15);
Out****tB ( 16#3D5#, Data);
end Update_Cursor;
-----------------------------------------------------------------------------
procedure Clear (Console : in out Video_Console) is
Clear_Character : Video_Character := (
Foreground => Console.Foreground,
Background => Console.Background,
Glyph => ' ');
begin
for R in Row'Range loop
for C in Column'Range loop
Video_Memory (R, C) := Clear_Character;
end loop;
end loop;
Console.Row := Row'First;
Console.Column := Column'First;
Update_Cursor(Console);
end Clear;
-----------------------------------------------------------------------------
procedure Put (Console : in out Video_Console;
C : Character) is
V : Video_Character := (
Foreground => Console.Foreground,
Background => Console.Background,
Glyph => C);
Tmp : Positive := Console.Column + 1;
begin
Video_Memory(Console.Row, Console.Column) := V;
if Tmp > Column'Last then
Console.Column := Column'First;
Console.Row := Row'Succ(Console.Row);
else
Console.Column := Column'Succ(Console.Column);
end if;
Update_Cursor(Console);
end Put;
-----------------------------------------------------------------------------
procedure Put (Console : in out Video_Console; S : String) is
begin
for I in S'Range loop
Put (Console, S (I));
end loop;
end Put;
-----------------------------------------------------------------------------
end Vga;


|