DataMuseum.dk

Presents historical artifacts from the history of:

CR80 Wang WCS documentation floppies

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CR80 Wang WCS documentation floppies

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦53cb1ed8f⟧ Wang Wps File

    Length: 21611 (0x546b)
    Types: Wang Wps File
    Notes: DELCO ADA (058)           
    Names: »4484A «

Derivation

└─⟦57fb8c09c⟧ Bits:30006028 8" Wang WCS floppy, CR 0392A
    └─ ⟦this⟧ »4484A « 

WangText

…00……00……00……00……00…G…0a……00……00…G…0b……86…1         …02…   …02…   …02…   …02…                                           



DELCO ADA                                          SYS/84-01-16

                                                   Page # 











                    T̲A̲B̲L̲E̲ ̲O̲F̲ ̲C̲O̲N̲T̲E̲N̲T̲S̲


                                                           Page


         1.  THE CHRISTIAN ROVSING A/S ADA PROJECT ......  
               

         2.  TECHNICAL APPROACH TO THE INTEL 8086 
             ADA SYSTEM .................................  
               

         3.  SYSTEM COMPONENTS ..........................  
               
             3.1 COMPILER ...............................  
                   
             3.2 LINKER .................................  
                   
             3.3 DOMAIN UTILITY .........................  
                   
             3.4 RUN TIME SYSTEM ........................  
                  
             3.5 IO SYSTEM ..............................  
                   


1        T̲H̲E̲ ̲C̲H̲R̲I̲S̲T̲I̲A̲N̲ ̲R̲O̲V̲S̲I̲N̲G̲ ̲A̲/̲S̲ ̲A̲D̲A̲ ̲P̲R̲O̲J̲E̲C̲T̲


         In December 1980 a consortium consisting of Christian
         Rovsing A/S, Danish Datamatics Centre (DDC) and Olivetti
         (Italy) was awarded a contract from the Commission
         of the European Communities (CEC) to produce a Portable
         Ada Programming System (PAPS). The system was to be
         implemented on the Christian Rovsing A/S CR80 computer
         and the Olivetti M40 computer.

         The division of work between the three partners is
         as follows:

         Compiler:         DDC and Christian Rovsing A/S

         CR80 RTS:         Christian Rovsing A/S

         MAPSE + M40 RTS:  Olivetti

         The technical approach taken in the project has been
         to define a virtual stack machine - called the A-machine
         - for which the compiler generates code. An interpreter
         for the A-machine has been implemented in firmware
         and software on the CR80.

         The compiler has been hosted on the CR80 itself as
         well as on the VAX11. Both compilers will be completed
         within the next 4 months and DOD validation will then
         be initiated.



2        T̲E̲C̲H̲N̲I̲C̲A̲L̲ ̲A̲P̲P̲R̲O̲A̲C̲H̲ ̲T̲O̲ ̲T̲H̲E̲ ̲I̲N̲T̲E̲L̲ ̲8̲0̲8̲6̲ ̲A̲D̲A̲ ̲S̲Y̲S̲T̲E̲M̲

         
         The basic idea is to take the VAX hosted compiler and
         retarget it for the 8086 (really, 80186 code will be
         generated but we will continue to use the term "8086").

         The compiler will be used in connection with the Intel
         iAPX-86/88/186 software development package hosted
         on the VAX. The iAPX development package is not included
         in this proposal. The program development scenario
         is sketched below:

















































         Ada source programs are compiled into object modules.
         One object module is specified to the Ada linker as
         being the main program. The Ada linker will then link
         this object module together with all dependent modules
         to form one link module in the format required by the
         VAX-LINK-86 linker. The VAX linker will then perform
         the final linking where the output from the Ada linker
         is linked together with the run time system.



         It is possible to write an Ada subprogram body, an
         Ada task body or an Ada package body in assembly language
         if this is necessary f.ex. to obtain better efficiency
         or to utilize special hardware features. Such assembly
         language modules are included in the final VAX linking.
         Certain rules relating to the transfer of subprogram
         parameters and results must be obeyed by the assembly
         language programmer. These rules are defined by the
         run time system and documented in the run time system
         documentation.



3        S̲Y̲S̲T̲E̲M̲ ̲C̲O̲M̲P̲O̲N̲E̲N̲T̲S̲



3.1      C̲O̲M̲P̲I̲L̲E̲R̲

         The Ada Compiler System offered consists of a number
         of logical passes, which are supplemented by an Initialization
         Component, an Error Display Component, three listing
         components, a Termination Component, and a Fatal-Component.
         The passes and the components mentioned above are called
         the "logical components" of the compiler.

         The logical passes perform the proper compilation,
         whereas the Error Display Component displays the errors
         that were found in the previous logical pass, if any.
         The Initialization Component interprets the user-specified
         parameters and initializes common data structures,
         whereas the Termination Component removes temporary
         files. The three listing components create the source
         listing, the cross-reference listing, and the object
         code listing. The Fatal-Component is only activated
         if the compilation is aborted.

         As many of the components perform identical tasks,
         e.g. store information for a diagnostic message, about
         12 supporting packages have been implemented. Any component
         may freely include the packages from which it can take
         advantage.

         The compiler has been divided into a number of separate
         programs, which are called the "physical components"
         of the compiler. A physical component may contain one
         or more logical components, whereas a logical component
         must be contained entirely in one physical component.
         The design of the physical component ensures that it
         is straightforward to gather two or more logical components
         into one physical component, or to split a physical
         component containing two or more logical components
         into separate physical components.

         The physical components are activated by a separate
         program called the Multipass Administrator, usually
         abbreviated MPA. The resulting structure of the Ada
         compiler is shown in Figure 1.:


















        Figure 1.: The structure of the compiler.


         The handling of separate compilation requires a separate
         program, which is described below.

         From the point of view of the compiler, the supporting
         package named the Separate Compilation Handler (SCH)
         constitutes the interface between the compiler and
         the program library. The program library is contained
         in the domain, which is administered by a realtime
         program called the domain manager. The domain manager
         is used not only by the compiler but also by the linker
         and other utility programs that need access to the
         domain. The interfaces are sketched below.

















    Figure 2.: Interfaces between a pass, the domain,
                      and the native file system.



         F̲r̲o̲n̲t̲ ̲E̲n̲d̲

         The first six passes of the Ada Compiler constitute
         the Front End, which as its main task accepts ANSI
         Ada source statements and produces an intermediate
         language, which is input to the Back End. The Front
         End is target-independent except for some target-dependent
         constants. The Front End produces:

         -   A tree-structured intermediate language called
             IML…0f…7…0e…, which is input to the target-dependent Back
             End.

         -   Various tables, such as the symbol table, which
             are used by the Back End.

         -   Diagnostic messages if any syntactic or semantic
             errors were found during the analysis.


         B̲a̲c̲k̲ ̲E̲n̲d̲

         The proposed Back End of the Ada Compiler for the 8086
         consists of the Middle Component and the Final Code
         Generator. The purpose of the Middle Component is to
         accept the IML…0f…7…0e… generated by the Front End and generate
         an Abstract A-code, whereas the Final Code Generator
         accepts the Abstract A-code and generates the final
         code. The Back End is shown in Figure 3 below:







       Figure 3.: The Back End of the Ada Compiler.


         O̲p̲t̲i̲m̲i̲z̲a̲t̲i̲o̲n̲

         One optimization carried out by the Front End is folding
         of constants, but additionally the Front End performs
         an extensive evaluation of the intermediate text, which
         also includes taking full advantage of the symbol table.
         The evaluation yields truth values, so-called predicates,
         describing properties of the intermediate text. The
         predicates are a part of the output (IML…0f…7…0e…) from the
         Front End. The predicates are aimed at guiding the
         code generator towards good code quality with respect
         to code memory space and execution time efficiency.



         The areas in which the predicates in particular aid
         the code generation are:

         -   elimination of range checks

         -   reduction of range checks to only check against
             either a lower or an upper bound

         -   elimination of length checks

         -   elimination of discriminant checks

         -   elimination of record field existence checks

         -   relocation of composite static expressions to constant
             areas

         -   elimination of unnecessarily repeated evaluations
             of expressions

         -   subprogram calls (avoid general parameter set-up)

         -   allocation of temporary storage in connection with
             expression evaluation

         -   elimination of dead code in connection with if
             and for loop statements.


         P̲r̲e̲d̲e̲f̲i̲n̲e̲d̲ ̲T̲y̲p̲e̲s̲

         The compiler will support the types BOOLEAN, INTEGER,
         LONG INTEGER, FLOAT, LONG FLOAT, CHARACTER, STRING,
         and DURATION, and one other fixed-point type as predefined
         types.


         Type BOOLEAN

         Array of BOOLEAN will represent each element with a
         single bit provided that pragma PACK is applied. Variables
         of type BOOLEAN will be stored in (16-bit) word.

         Type INTEGER

         Variables of type INTEGER will be represented by a
         single word. Operations on INTEGER variables will use
         16-bit twos-
         complement arithmetic.



         Type LONG ̲INTEGER

         Type LONG ̲INTEGER will be represented by a double-word
         value. Operations on LONG ̲INTEGER variables will use
         32-bit twos-complement arithmetic.

         Type FLOAT

         Type FLOAT will be represented by the 32-bit floating-point
         arithmetic hardware format. This has a eight-bit exponent,
         a sign bit, and a 23-bit mantissa.

         Type LONG ̲FLOAT

         Type LONG ̲FLOAT will use the 64-bit hardware floating
         point format. This is similar to the 32-bit format,
         except that it has a 52-bit mantissa and an eleven-bit
         exponent.

         Type CHARACTER

         The type CHARACTER will be represented in one word.

         Type STRING

         The representation of strings will have one character
         per byte.

         Type DURATION

         The representation of DURATION will be a double-word
         integer with an implicit divisor of one thousand.

         Additional Predefined Types

         There will be at least one predefined fixed point type
         in addition to DURATION.



3.2      L̲I̲N̲K̲E̲R̲

         In order to utilize the native linker of a computer
         system, an Ada Linker Front End will be provided. The
         front end performs the Ada-specific parts of the linking,
         and in this way the cost of the complete Ada Linker
         will be reduced significantly.

         Based upon a user-specified "main program" the Ada
         Linker Front End checks all units for compliance to
         the Ada Reference Manual with respect to compilation
         and elaboration order.



         The linker then determines an elaboration order and
         according to this order, it generates a small object
         code initialization program, which is the entry point
         of the entire program. The purpose of the initialization
         program is to call the elaboration routines of all
         compilation units in an appropriate order and finally
         call the compilation unit specified as the main program.
         In addition, a command file for the native linker is
         generated.

         The linking is illustrated in figure 4 below:

















           Figure 4.: Linking of Ada programs.



3.3      D̲O̲M̲A̲I̲N̲ ̲U̲T̲I̲L̲I̲T̲Y̲

         A so-called Domain Utility will be provided, which
         is able to initialize a program library and which can
         be used to inspect library units in the program library.

         The package STANDARD is inserted in the program library
         by means of a separate tool. The packages SYSTEM, UNCHECKED
         ̲DEALLOCATION, and UNCHECKED ̲CONVERSION are simply compiled
         into the domain.

         The Domain Utility is able to list various information
         about all library units in a program library including
         the date of the latest modification.



3.4      R̲U̲N̲ ̲T̲I̲M̲E̲ ̲S̲Y̲S̲T̲E̲M̲

         The run time system supports a target configuration
         consisting of one or more 80186 CPU's sharing a common
         memory. Interrupt driven communication to the external
         world is also supported.
















                     Target Computer


         The entire application software in the target computer
         comprises one Ada program. If it is desirable to divide
         the application into - possibly logically unrelated
         - parallel parts, this is done by using the tasking
         facility in Ada.

         Even though the application software is an Ada program
         this does not mean that all of the software must be
         written in Ada. As has been mentioned earlier a separately
         compiled subprogram body, task body or package body
         may be written in assembly language as long as the
         programmer obeys the parameter passing rules that are
         set forth by the Ada run time system.

         The application program is separated into a code part
         and a data part. The code size of a separately compiled
         module cannot exceed 64KB. However, the code size for
         the entire program is not limited to this value. The
         size of the data part of the program is limited to
         64KB because of the addressing constraints in the 80186.

         It is convenient to divide the run time system into
         three parts which are described separately below.





3.4.1    N̲o̲n̲-̲t̲a̲s̲k̲i̲n̲g̲ ̲S̲u̲p̲p̲o̲r̲t̲ ̲R̲o̲u̲t̲i̲n̲e̲s̲

         This set of routines implements functionality which
         it would be inconvenient to obtain by generating in-line
         code. The following functionality is included:



3.4.1.1  H̲e̲a̲p̲ ̲M̲a̲n̲a̲g̲e̲m̲e̲n̲t̲

         The heap management contains routines for allocating
         and releasing memory objects of a given size from a
         heap.

         The run time system contains one permanent heap called
         the system heap. Apart from the system heap other heaps
         may be allocated in a stack frame when a block is entered
         that contained a length clause of the form

                  for T use  expression

         where T is some access type. Such a heap will have
         the size  expression  and objects allocated by an allocator
         of the form n̲e̲w̲ T will be allocated on this heap. When
         the block is exited the entire heap dissappears together
         with the stack frame. Apart from this no automatic
         garbage collection is performed. Heap objects allocated
         by the run time system itself, such as task control
         blocks are of course released when no longer needed.



3.4.1.2  S̲u̲b̲p̲r̲o̲g̲r̲a̲m̲s̲ ̲a̲n̲d̲ ̲B̲l̲o̲c̲k̲s̲

         When a subprogram or block is entered a routine is
         called to set up a new stack frame. The routine establishes
         addressing of the new block and marks it as not having
         an associated exception handler. The run time system
         distinguishes two kinds of blocks, task-blocks which
         can potentially have dependent tasks and nontask-blocks
         which cannot have dependent tasks. When a block is
         left, a clean up routine is called and only when leaving
         a task-block is the tasking kernel called to await
         termination of dependent tasks. In this way the overhead
         involved in searching for dependent tasks is avoided
         in the majority of cases where there cannot be any
         dependent tasks.

         …86…1         …02…   …02…   …02…   …02…                               
                        
         A function subprogram may be left in two ways. Either
         the "normal" way where a function result is taken from
         the top of the stack and copied to the stack top of
         the calling environment, or a return may be made to
         the calling environment without changing the stackpointer.
         The latter case is used when the function returns on
         object, the size of which is unknown of compile time,
         e.g. an array with dynamic bounds. In this case the
         function result is left on the top of the stack together
         with information about its size and the caller must
         then decide how to use it.



3.4.1.3  E̲x̲c̲e̲p̲t̲i̲o̲n̲ ̲H̲a̲n̲d̲l̲i̲n̲g̲

         An Ada exception handler is translated to a case-like
         construct containing pieces of code corresponding to
         individual exceptions to be handled. These code pieces
         are preceded by a table, which contains the identification
         of each exception in the handler together with the
         address of the code for this exception.

         The exception handling module contains a routine that
         associates an exception handler (i.e. a code address)
         with the current block/subprogram. This routine is
         called at the end of the declarative part of a block/subprogram
         which contains an exception handler.

         When an exception occurs, the exception handler searches
         the stack backwards for a handler that will handle
         the exception.



3.4.1.4  F̲l̲o̲a̲t̲i̲n̲g̲ ̲P̲o̲i̲n̲t̲ ̲A̲r̲i̲t̲h̲m̲e̲t̲i̲c̲

         This module implements floating point arithmetic on
         32 bit and 64 bit floating point numbers in the format
         used by the Intel 8087 numeric processor extension.

         If there is a requirement for using the Intel 8087
         to obtain faster floating point arithmetic the compiler
         could be modified to generate instructions for the
         8087 instead of using this run time system module.
         However, this option is not moduled in the present
         proposal.



3.4.1.5  F̲i̲e̲l̲d̲ ̲H̲a̲n̲d̲l̲i̲n̲g̲

         This module manipulates bit fields of width 1, 2, 4,
         8 or 16 bits. It is used to move values between packed
         arrays (e.g. of booleans) and unpacked variables. It
         is also used to handle some compiler generated packed
         datastructures.



3.4.2    T̲A̲S̲K̲I̲N̲G̲ ̲K̲E̲R̲N̲E̲L̲

         The tasking kernel which implements Ada tasking concepts
         relies on the existence of a very simple process concept
         on which to build on. This process concept is described
         in the next section.

         The concepts in the tasking kernel are very close to
         those of Ada implying a very straight forward code
         generation as regards tasking.

         The tasking kernel contains the following functions:


         C̲r̲e̲a̲t̲e̲ ̲T̲a̲s̲k̲

         Creates a new task and returns its identification (=
         its task control block address). A task control block
         is created on the system heap and initialized. The
         new task remains unactivated. The stack space for the
         new task is also allocated on the system heap. The
         size of the stack is either some default value or it
         may be specified by the programmer by using a length
         clause (cf. LRM section 13.2).

         It may be specified whether one or more entries in
         the task corresponds to external interrupts. 


         A̲c̲t̲i̲v̲a̲t̲e̲ ̲T̲a̲s̲k̲s̲

         Activates a number of tasks and blocks the calling
         task until activation is completed.


         A̲c̲t̲i̲v̲a̲t̲e̲d̲

         Signals that the calling task has completed its activation.


         A̲b̲o̲r̲t̲ ̲T̲a̲s̲k̲s̲

         Aborts a number of tasks.




         D̲e̲l̲a̲y̲

         Delays the calling task for a specified duration.
  

         C̲a̲l̲l̲ ̲E̲n̲t̲r̲y̲

         Performs an entry call to a specified entry and blocks
         the calling task until a rendezvous has been completed.


         C̲a̲l̲l̲ ̲E̲n̲t̲r̲y̲ ̲T̲i̲m̲e̲d̲

         Same function as Call Entry except that a time out
         value is specified.


         S̲e̲l̲e̲c̲t̲ ̲E̲n̲t̲r̲y̲

         Performs all the functionality of Ada's s̲e̲l̲e̲c̲t̲ statement
         including d̲e̲l̲a̲y̲ and t̲e̲r̲m̲i̲n̲a̲t̲e̲ alternatives.


         R̲e̲n̲d̲e̲z̲v̲o̲u̲s̲ ̲C̲o̲m̲p̲l̲e̲t̲e̲

         Signals that a rendezvous has been completed.


         R̲e̲n̲d̲e̲z̲v̲o̲u̲s̲ ̲F̲a̲i̲l̲u̲r̲e̲

         Signals that a rendezvous has been completed and that
         a specified exception shall be propagated to the caller.


         A̲t̲t̲r̲i̲b̲u̲t̲e̲s̲

         Returns one of the attributes 'callable', 'teminated'
         and 'storage size'.


         E̲n̲t̲r̲y̲ ̲C̲o̲u̲n̲t̲

         Returns the number of callers queued for a certain
         entry.

         The tasking kernel operates on a set of task control
         blocks which are allocated on the system heap. The
         task control blocks are protected by a semaphore so
         that only one task at a time has access to the task
         control blocks.




3.4.3    P̲r̲o̲c̲e̲s̲s̲ ̲a̲n̲d̲ ̲I̲n̲t̲e̲r̲r̲u̲p̲t̲ ̲K̲e̲r̲n̲e̲l̲

         The purpose of the process and interrupt kernel is
         to provide a foundation on which the tasking kernel
         may be implemented.

         It is convenient to distinguish between processes which
         is a concept of the target computer and tasks which
         is an Ada concept. In this run time system there is
         a one-to-one correspondance between these concepts
         in that each Ada task is mapped onto a process.

         The process and interrupt module contains the following
         functionality:

         -   creation and removal of processes

         -   distribution of CPU's to processes; each process
             has a priority which is the same as the corresponding
             task priority. CPU's are delegated to those processes
             with highest priority. In case there are more such
             processes than CPU's, the CPU's are time sliced
             evenly among the processes

         -   reception of interrupts. If a task entry has been
             designated as the receiver of a certain interrupt,
             an entry call to this entry will be generated when
             the interrupt occurs. Interrupts not corresponding
             to any task entry are lost

         -   implementation of a semaphore concept. It is used
             by the tasking kernel to protect the task control
             blocks

         -   a debug interface to the external world. This interface
             allows an external debugger to be connected (f.ex.
             via an RS232 line) to the target program. The debug
             interface allows the external debugger (which is
             itself not included in this proposal) to

             -   read and write memory and registers
             -   insert breakpoints
             -   receive notification when certain events, such
                 as exceptions and rendezvous happens.

         It may be that use of the debugging facility restricts
         the number of CPU's that can be utilized in a system
         to one. However, this issue requires further analysis.





3.5      I̲O̲ ̲S̲Y̲S̲T̲E̲M̲

         A 'real' Ada IO system is not provided. However, in
         order to adhere to Ada in a formal way, a dummy IO
         system will be provided. This dummy system will raise
         the 'use-error' exception each time an attempt is made
         to open or create a file. Output to the standard output
         file is disposed of and a call to read from the standard
         input file never returns.