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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 2002:a05:620a:10a7:: with SMTP id h7mr39333194qkk.423.1579388393356; Sat, 18 Jan 2020 14:59:53 -0800 (PST) X-Received: by 2002:aca:eb8b:: with SMTP id j133mr451841oih.0.1579388392955; Sat, 18 Jan 2020 14:59:52 -0800 (PST) Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!news.gegeweb.eu!gegeweb.org!usenet-fr.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!g89no10774188qtd.0!news-out.google.com!w29ni1698qtc.0!nntp.google.com!g89no10774180qtd.0!postnews.google.com!google-groups.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sat, 18 Jan 2020 14:59:52 -0800 (PST) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: google-groups.googlegroups.com; posting-host=47.136.24.151; posting-account=o_Y23woAAACPYGlDsFV1OivhygPNSoRn NNTP-Posting-Host: 47.136.24.151 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: Creating several types from a base type and conversion From: Ken Roberts Injection-Date: Sat, 18 Jan 2020 22:59:53 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Xref: reader01.eternal-september.org comp.lang.ada:57885 Date: 2020-01-18T14:59:52-08:00 List-Id: On Saturday, January 18, 2020 at 9:57:08 AM UTC-8, Niklas Holsti wrote: > On 2020-01-18 9:32, Ken Roberts wrote: > > New to ada with a question about types. >=20 > Welcome to the language! >=20 > What did you program in before? Sometimes it is easier to give advice if= =20 > one knows the background of the person asking for it. I touched on C way back when (sometime in the 80's) but my day job was not = programming and didn't really dig into it. For the last few years I've been programming Python (again, hobby, not day = job) working on a PJLink control for network-connected projectors in an ope= n source church project. > > The theory is creating an old computer emulator. Memory is an array > > of BaseWord's (Older computer had 32K of memory, so making an array > > on a modern computer is peanuts). >=20 > Yes, but note that in some Ada compilers, the predefined Integer is only= =20 > 16 bits, so some memory address computations (offsets) in a 32K range=20 > might overflow... better define your own "memory address" type with the= =20 > computational range you need (which may be more than 32K, or should=20 > perhaps use modular arithmetic). >=20 > > Creating a base type that is stored into the memory array > >=20 > > > >=20 > > type BaseWord is array (00 .. 29) of Boolean; > > pragma pack (BaseWord); > >=20 > > >=20 > Note that such a definition does not ensure that the Boolean with index= =20 > 0 is the least significant bit, or the most significant bit -- different= =20 > compilers can use different conventions. And there is no way in current= =20 > Ada to specify the indexing order. >=20 > I think the first thing you should consider, and decide, is whether you= =20 > want your emulator to be fully portable to all standard Ada=20 > implementations, or to the commonly available Ada compilers. The main=20 > issues are the endianness and the word length of the computer you want=20 > to emulate: >=20 > - Can the computer to be emulated address only full 30-bit words, or can= =20 > it address also, say, characters (bytes) within a word? The computer is 30-bit and the memory is 30-bit magnetic core. The memory c= ontrol can return either a 30-bit word or 15-bit half-word from upper or lo= wer half of memory address depending on one of the instruction modifiers. >=20 > - Is the computer you intend to emulate big-endian or little-endian?=20 > There are two aspects to this question: first, conventions for numbering= =20 > bits (is bit 0 most significant or least significant?) and second,=20 > addressing sub-word-units like characters (if possible) within a word=20 > (does the lowest sub-word address access the most significant end of the= =20 > addressed word, or the least-significant end?). The memory/computer model is 30-bit words both in computer and memory. No e= ndianness. 32K of directly addressable internal memory. Depending on a modifier field = in the instruction word, either a 30-bit word or 15-bit half word (from eit= her upper 15 bits or lower 15 bits) was returned from memory for operatnds. The addition of 144K of extended memory was provided by an external memory = unit approximately the same physical size, and the memory control chassis o= n the computer was modified at a later date to allow access. Unfortunately,= I can't find the documentation on how the external memory was accessed, so= I'll have to guess until I can find out. The computer was actually built before semiconductors became the norm, so t= he whole computer was built using discreet components on 15-pin circuit car= ds. >=20 > I'll sketch an approach that applies to the commonly available Ada=20 > compilers and makes no a-priori assumptions on the endianness of the=20 > computer to be emulated. >=20 > I recommend starting from the type Interfaces.Unsigned_32. This is a=20 > 32-bit, unsigned, modular integer type, and has predefined shift and=20 > rotate operations as well as bit-wise Boolean operations. The type is=20 > not required to exist in all Ada compilers (for example, the computer=20 > you are emulating would probably instead have had a type=20 > Interfaces.Unsigned_30) but does exist in GNAT and other Ada compilers=20 > for most modern computers which tend to have 32-bit machine integers. >=20 > The 30-bit unsigned integer type is then >=20 > subtype Base_Word is Interfaces.Unsigned_32 range 0 .. 2**30 - 1; >=20 > and the emulated memory is an array of 2**15 Base_Word elements, indexed= =20 > by the memory-address type. >=20 > Note that Base_Word does not wrap around at 30 bits (as the type "mod=20 > 2**30" would) but at 32 bits. But you can emulate 30-bit wrap-around by= =20 > clearing the two high bits after every arithmetic operation. >=20 > I would then define a function to extract any desired bit-field from a=20 > Base_Word, for example >=20 > function Field (Word : Base_Word; Low_Bit, High_Bit : Bit_Number) > return Base_Word >=20 > where Bit_Number is range 0 .. 29. >=20 > The easiest way to implement such a function is by the left-shift and=20 > right-shift operations for Base_Word. In this implementation, you can=20 > decide if you want Bit_Number to work in a little-endian or big-endian wa= y. >=20 > I would also define a procedure Set_Field similarly: >=20 > procedure Set_Field ( > Word : in out Base_Word; > Low_Bit, High_Bit : in Bit_Number; > New_Value : in Base_Word); >=20 > Again, this can be done with the shift operations (or rotate operations)= =20 > and some Boolean operations on Base_Word. >=20 > If the computer to be emulated can access sub-word data, for example=20 > bytes with a byte address, you can now use the above subprograms to=20 > implement operations to read or write such sub-word data, and again you= =20 > can implement either little-endian sub-word order or big-endian sub-word= =20 > order. >=20 As noted above, this was before semiconductors and bytes became a thing. The only memory operations were 30-bit word and upper/lower 15-bit half-wor= d get/put operations. Program accessible registers were 30-bit (with one exception - some operati= ons treated 2 registers as one 60-bit register, but that was for a few sele= cted math functions). > These tools should let you decode instructions and their bit-fields and= =20 > emulate all "logical" (Boolean) instructions and load/store instructions. >=20 > If you prefer to implement the bit-field lay-outs of instruction words=20 > by means of record representation clauses, that is fine too. However,=20 > note that the endianness of the bit numbering in such clauses may be=20 > different in different Ada compilers, so you should also use the=20 > Bit_Order aspect, together with the representation clause, to define the= =20 > order you want to use (which is probably the same as in the=20 > instruction-set manuals for the emulated computer). Also, you then have= =20 > to use Unchecked_Conversion to convert between Base_Word and the=20 > instruction record types, but that is good and safe as long as you have= =20 > taken care of the bit order. >=20 See reply to Simon about my program compile operations - it included the fi= eld breakdown notes. > For the arithmetic instructions, you must of course first consider how=20 > the emulated computer represents negative numbers: two's complement,=20 > one's complement, or sign-magnitude? >=20 The computer is 1's complement subtractive addition, and some instruction m= odifiers allow for circular shift, shift with sign, and sign extension (for= half word operations). > The answer will tell you how to convert, using ordinary type conversions= =20 > and ordinary arithmetic (not Unchecked_Conversion) from Base_Word to the= =20 > corresponding signed type (for use as an operand in the emulation of an= =20 > arithmetic instruction) and from the signed type (as the result of the=20 > arithmetic instruction) back to Base_Type for storing in an emulated=20 > register or in the emulated memory. >=20 > Remember that you may have to use wider types for the results of=20 > arithmetic operations so as to handle and detect overflows. Unsigned_32= =20 > already gives you two more high-end bits, so it can be used for addition= =20 > and subtraction, but for multiplication you may want to use a 64-bit=20 > type, for example. True - noted above there are a couple of multiply/divide instructions that = treat the 30-bit A and Q registers as one 60-bit register. I was thinking a= bout that and concluded that for those specific instructions it would be be= tter to treat the 60-bit AQ register combination in a private variable sinc= e the final operation will still end up being two 30-bit registers. >=20 > (I agree with others that there are some errors in the declarations you= =20 > gave (elided here) which should have made GNAT reject the code.) > > For most stuff, memory will be returning either DataWord or > > InstructionWord for each memory access, but I'm also looking at an=20 > > easier way to manage characters for text display on the emulated=20 > > monitors. > I would assume that in the original system, the diplay of characters on= =20 > the monitors was implemented in the SW programs that ran on the emulated= =20 > processor. Why should the processor emulator do something special for=20 > this? Did the monitors display data directly from "display buffers" in=20 > the 32K memory, using DMA? Nope. There was no "display" on the computer. The closest thing to a displa= y was a bunch of neon buttons that reflected the contents of the registers = on the front panel. The "display" part was either an old-school teletype ma= chine (using 5-bit characters) or a CRT that was a combination radar repeat= er/computer symbology display unit with attached 15 line X 65 character tex= t display using a really interesting 30-bit layout. (reaaalllly long URL from google reposted via bit.ly) http://bit.ly/368sGgl Picture of computer I'm trying to emulate. Worked on it for 15 years in the Navy. >=20 > --=20 > Niklas Holsti > Tidorum Ltd > niklas holsti tidorum fi > . @ .