comp.lang.ada
 help / color / mirror / Atom feed
From: Jeffrey Carter <spam@spam.com>
Subject: Re: Dynamic discrimants in variant records?
Date: Thu, 19 Jun 2003 23:57:44 GMT
Date: 2003-06-19T23:57:44+00:00	[thread overview]
Message-ID: <3EF24E74.1080107@spam.com> (raw)
In-Reply-To: bcrt83$mdpd5$1@ID-175126.news.dfncis.de

Vinzent Hoefler wrote:
> 
> |   --  type for a programmable address region register
> |   type Programmable_Address_Region (
> |       Target : Window_Target := Window_Disabled;
> |       Pg_Sz  : Page_Size     := Four_Ki_Byte) is
> |   record
> |      case Target is
> |         when Window_Disabled =>
> |            null;
> |         when GP_Bus_IO | PCI_Bus =>
> |            IO_Attr       : Chip_Select_Signal;
> |            Sz_St_Addr_IO : IO_Page;
> |         when GP_Bus_Memory | Boot_CS | Rom_CS_1 | Rom_CS_2 | SD_Ram =>
> |            Mem_Attr : Memory_Attribute;
> |
> |            case Pg_Sz is
> |               when Four_Ki_Byte =>
> |                  Sz_St_Addr_4K  : Mem_Page_4K;
> |               when Sixty_Four_Ki_Byte =>
> |                  Sz_St_Addr_64K : Mem_Page_64K;
> |            end case;
> |      end case;
> |   end record;
> 
> As mentioned, the actual (global) variables of this type are memory
> mapped registers, so the problem occurs when I want to change a region
> register dynamically (from a 4K granularity to a 64K for instance). In
> Ada this would be equivalent to just change some of the discrimants
> (those are really some bits in the register) and so changing the
> interpretation of the record.

It works sort of like this:

V : Programmable_Address_Region; -- V is unconstrained
for V'Address use ...;
...
V := (Target => GP_Bus_Memory, Pg_Size => Four_Ki_Byte,
       Mem_Attr => ..., Sz_St_Addr_4K => ...);
...
V := (Target => GP_Bus_Memory, Pg_Size => Sixty_Four_Ki_Byte,
       Mem_Attr => V.Mem_Attr, Sz_St_Addr_64K => ...);

If the object is declared without actual values for the discriminants, 
and the discriminants have default values, then the object is 
unconstrained, and the values of the discriminants can change. With many 
compilers, that results in enough space for the largest variant being 
allocated, but since you're locating the object at a specific address, 
that shouldn't be an issue.

However, the only way to change a discriminant of such an object is by 
assigning an entire new value to it. That's why there are complete 
aggregates in the assignments above. The values supplied for the 
discriminants must be static, which means you can't use "V.Target" in 
the 2nd aggregate.

If you must use a non-static value for the discriminant, there's a way 
to do that, too:

declare
    Temp : Programmable_Address_Region
           (Target => V.Target, Pg_Size => Sixty_Four_Ki_Byte);
begin
    Temp.Mem_Attr := V.Mem_Attr;
    Temp.Sz_St_Addr_64K := ...;
    V := Temp;
end;

Note that none of this code has been compiled.

-- 
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail




  parent reply	other threads:[~2003-06-19 23:57 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-19  8:44 Dynamic discrimants in variant records? Vinzent Hoefler
2003-06-19 10:37 ` John McCabe
2003-06-19 23:57 ` Jeffrey Carter [this message]
2003-06-20  7:44   ` Vinzent Hoefler
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox