From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,19502ac20a7b16de X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-06-19 17:00:07 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!snoopy.risq.qc.ca!newsfeed.news2me.com!elnk-pas-nf2!newsfeed.earthlink.net!stamper.news.pas.earthlink.net!newsread1.prod.itd.earthlink.net.POSTED!not-for-mail Message-ID: <3EF24E74.1080107@spam.com> From: Jeffrey Carter Organization: jrcarter commercial-at acm [period | full stop] org User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.0.0) Gecko/20020530 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Dynamic discrimants in variant records? References: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Date: Thu, 19 Jun 2003 23:57:44 GMT NNTP-Posting-Host: 63.184.0.158 X-Complaints-To: abuse@earthlink.net X-Trace: newsread1.prod.itd.earthlink.net 1056067064 63.184.0.158 (Thu, 19 Jun 2003 16:57:44 PDT) NNTP-Posting-Date: Thu, 19 Jun 2003 16:57:44 PDT Xref: archiver1.google.com comp.lang.ada:39466 Date: 2003-06-19T23:57:44+00:00 List-Id: 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