From: Ken Roberts <alisonken1@gmail.com>
Subject: Re: Creating several types from a base type and conversion
Date: Sat, 25 Jan 2020 02:37:15 -0800 (PST)
Date: 2020-01-25T02:37:15-08:00 [thread overview]
Message-ID: <01f6b6cc-9ce6-43b8-9c67-5595fa960381@googlegroups.com> (raw)
In-Reply-To: <f531cd40-6734-46cb-967e-638cf1004426@googlegroups.com>
It might be that I can only really concentrate on learning Ada on my weekends (thursday night -> saturday) subject to $HoneyDoList.
Needless to say, I'm not always the brightest nowadays between age and free time without some extra help, so sorry for seeming a little dense right now.
Here's the computer representation as expressed in documentation and how I'm used to working on the hardware:
30-bit words (both memory storage and hardware registers)
Bit Number : 29 28 .. 01 00
MSBit on left, LSBit on right
30-bit words using half-word (memory access only)
Bit number: 29 28 .. 16 15 14 13 .. 01 00
Half word : | Upper | Lower |
Instruction format:
Bit number: | 29 .. 24 | 23 .. 21 | 20 .. 18 | 17 .. 15 | 14 .. 0 |
Field : | Op code | J | K | B | Y |
Op code : Instruction
j : Skip next instruction modification
k : Source or destination of data
b : Index register to use to modify Y
y : Constant or memory address
Sample program 1 (all numbering is octal notation):
<code>
| Address | Contents | Description
| 00600 | 12130 00601 | f = 12 : Opcode (Load A register)
| | | j = 1 : 1 = always skip next instruction
| | | k = 3 : y is memory address, 30 bits
| | | y = 601 : Data
| 00601 | 00005 00001 | Data
| | | A register initial: 00005 00001
| 00602 | 06000 00017 | f = 06 : Opcode (Shift A left circular)
| | | j = 0 : Execute next instruction
| | | k = 0 : Shift count is y
| | | y = 17 : Data (17 octal, 15 decimal)
| | | A register final: 00001 00005
</code>
Sample program using 60-bit register instruction:
60-bit register
Bit number : | 59 .. 30 | 29 .. 00 |
Registers used : | A reg | Q reg |
<code>
| Address | Contents | Description
| 00600 | 10000 00001 | Load Q register
| | | Q register = 00000 00001
| 00601 | 11000 00005 | Load A register
| | | A register = 00000 00005
| 00602 | 07000 00036 | Left shift AQ register circular
| | | Shift count (36 octal, 30 decimal)
| | |
| | | AQ initial : 00000 00005 00000 00001
| | | A register initial = 00000 00005
| | | Q register initial = 00000 00001
| | |
| | | AQ final : 00000 00001 00000 00005
| | | A register final = 00000 00001
| | | Q register final = 00000 00005
</code>
My programming environment is:
Intel-based system
64-bit Fedora based KDE desktop system
Fedora repository has the GNAT compiler suite (GCC Ada - AdaCore?)
With these considerations in mind, I'm trying to figure out the best way to represent the computer hardware (register and memory).
The register and memory base word would be a 30-bit quantity (Interfaces.unsigned_32 possibly?) with 2**30 bit limit, so all register/memory representations would be easily convertible.
Memory representation will be an array (0 .. #8#77777# or 32,768 words) of 30-bit words.
The 60-bit instructions (there's only 2 shift instructions, multiply, which puts answer in QA register(s)) and divide, which uses combined QA register for data, and puts answer in Q and remainder in A))
Based on Niklas Holsti's recommendation, it looks like the following would be what I want to do:
<code>
package core is
with Interfaces;
subtype Word is Interfaces.Unsigned_32 with range 0 .. 2**30 - 1;
subtype D_Word is Interfaces.Unsigned_64 with record
Ru : Word;
Rl : Word;
end record
for D_Word use record
Ru : at 0 use 59 .. 30;
Rl : at 0 use 29 .. 0;
end record
-- NOTE: I_Word is basically read-only
-- The only use is to make it easier to break down Word into
-- the fields to interpret the instruction and will not change
-- during the instruction execution cycle
I_Word is Word with record
-- Not sure how to define this part yet
-- See below for breakdown of bits-to-fields
end record
for I_Word use record
f : at 0 range 29 .. 24;
j : at 0 range 23 .. 21;
k : at 0 range 20 .. 18;
b : at 0 range 17 .. 15;
y : at 0 range 14 .. 00;
end record
end package core;
</code>
With the above representation, I can use a D_Word for shifting
and be able to ignore unused 32/64 bits in hardware
<code>
-- Circular left shift register
procedure shift_left_logical (R : <> Word'Class,
Count : in Integer) is
private
D : D_Word;
-- NOTE: By putting the same contents into both Ru and Rl
-- I don't have to worry about extra bits from Unsigned_32
D.Ru := R;
D.Rl := R;
-- NOTE: Only bits 5 .. 0 are used, the rest are ignored
-- Add option to limit actual shifting to mod 30 since anything
-- over 30 would just wrap around again
-- ex: Count == 31 is equivalent to Count == 1
-- on a 30-bit register
if Count > 8#77# then
C : Integer (Count and 8#77#);
else
C : Integer (Count);
end if Count;
end private;
begin
D.Shift_Left(C);
-- Set the register to new value
R := D.Ru;
end shift_left_logical;
</code>
For the double-register shift
<code>
-- Circular left shift double register
procedure double_shift_left_logical (R1 : <> Word'Class,
R2 : <> Word'Class,
Count : in Integer) is
private
D1 : D_Word;
D2 : D_Word;
-- Normal register order so lower register bits go to upper register
D1.Ru := R1; -- A register
D1.Rl := R2; -- Q register
-- Reverse the register order so high register bits go to low register
D2.Ru := R2; -- Q register
D2.Rl := R1; -- A register
-- NOTE: Only bits 5 .. 0 are used, the rest are ignored
-- Add option to limit actual shifting to mod 60 since anything
-- over 60 would just wrap around again
-- ex: Count == 61 is equivalent to Count == 1
-- on a 60-bit register
if Count > 8#77# then
C : Integer (Count and 8#77#);
else
C : Integer (Count);
end if Count;
end private;
begin
D1.Shift_Left(C); -- AQ register pair
D2.Shift_Left(C); -- QA register pair
-- Set the registers to new values
R1 := D1.Ru; -- A register
R2 := D2.Ru; -- Q Register
end shift_left_logical;
</code>
This is from my limited understanding so far.
Thanks for all of your help - I wish I could catch on a little quicker, but age and $DayJob (plus $HoneyDoList) make learning a new language a little challenging lately.
next prev parent reply other threads:[~2020-01-25 10:37 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-18 7:32 Creating several types from a base type and conversion Ken Roberts
2020-01-18 12:16 ` Simon Wright
2020-01-18 12:49 ` Ken Roberts
2020-01-18 14:56 ` Bill Findlay
2020-01-18 16:13 ` Jeffrey R. Carter
2020-01-18 18:20 ` Bill Findlay
2020-01-18 18:32 ` Jeffrey R. Carter
2020-01-18 20:34 ` Simon Wright
2020-01-20 16:38 ` Bill Findlay
2020-01-18 22:20 ` Ken Roberts
2020-01-18 15:09 ` Simon Wright
2020-01-18 22:16 ` Ken Roberts
2020-01-18 22:35 ` Simon Wright
2020-01-18 23:03 ` Ken Roberts
2020-01-18 23:38 ` Simon Wright
2020-01-19 0:12 ` Ken Roberts
2020-01-19 9:37 ` Simon Wright
2020-01-19 11:48 ` AdaMagica
2020-01-19 14:51 ` Simon Wright
2020-01-19 15:24 ` Niklas Holsti
2020-01-19 16:11 ` Optikos
2020-01-19 0:33 ` Ken Roberts
2020-01-19 0:07 ` Niklas Holsti
2020-01-18 15:47 ` Simon Wright
2020-01-21 21:35 ` Shark8
2020-01-21 23:06 ` Niklas Holsti
2020-01-22 1:08 ` Ken Roberts
2020-01-22 14:18 ` Ken Roberts
2020-01-22 8:37 ` Simon Wright
2020-01-22 14:32 ` Shark8
2020-01-22 15:40 ` Simon Wright
2020-01-18 14:17 ` Optikos
2020-01-18 17:57 ` Niklas Holsti
2020-01-18 22:59 ` Ken Roberts
2020-01-19 0:30 ` Niklas Holsti
2020-01-19 1:07 ` Ken Roberts
2020-01-19 3:37 ` Ken Roberts
2020-01-23 21:39 ` Optikos
2020-01-24 9:35 ` Ken Roberts
2020-01-24 10:04 ` AdaMagica
2020-01-24 12:38 ` Optikos
2020-01-24 15:01 ` Ken Roberts
2020-01-24 15:22 ` Simon Wright
2020-01-24 15:40 ` Ken Roberts
2020-01-24 15:54 ` Simon Wright
2020-01-25 10:37 ` Ken Roberts [this message]
2020-01-25 10:44 ` Ken Roberts
2020-01-25 20:26 ` Shark8
2020-01-27 14:10 ` Ken Roberts
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox