4 HANDLING THE OBJECT PROGRAM
4.0 The Object Program
This Section describes the way in which the object program
being compiled is stored by GIN, and how it can be put onto
magnetic tape or entered for execution.
GIN does not provide any facilities for dumping programs to
cards or paper tape. The user who wants a dump in this form
can either write his own interlude, copy the one given in
Section 10.6.2, or take the output from GIN and use the
facilities of other software to produce it; for example, he
can load a dump from magnetic tape, make the program halt and
use Executive's DUMP or GEORGE's SAVE command.
GIN can output a program either in a FINDable form or in a
subfile from which it can be loaded by #XKOF or any similar
program. At the end of a compilation to drum or direct access,
the program file is available in a file on backing store.
It is also possible to dump a compilation using the #DUMP
directive and restart it at a later date. The program file in
such a dump or as held on backing store is not in a format in
which it can be loaded directly by normal programs. However,
GEORGE differs from other programs in this respect; GELL can
either load GEORGE directly from a program file set up by GIN,
or load a loader-allocator program produced by the GEORGE
source DUMP macro which in its turn finds the program file
dumped on tape by GIN and loads that.
Each of these methods of loading GEORGE is thus dependent on
the way GIN organises things, and so other users are strongly
recommended not to attempt to imitate them.
In addition (or as an alternative) to obtaining a permanent
record of his program on magnetic tape, the user can enter the
program by #GO, either giving GIN a request slip with full
details of the program or accepting GIN's default options.
It is of course possible to make the program halt at an early
stage and then use operating system facilities to dump it in a
manner that GIN cannot.
4.1 The Program File
The area in core or on backing store where GIN keeps the
program being compiled is referred to as the program file.
If it is on backing store, a single drum or direct access
file is used; if in core, a single area of store is reserved
for this purpose. A direct access file should only have one
file area if it is to be used for GEORGE 3 or 4. 11?
holds the device type as given in the #PROGRAM directive.
The device type specified in #PROGRAM may be any of those listed below. The original formats used in core and on drum were incompatible with those on disc, and you are recommended to use the new compatible device types 1 and 10.
Device Types | Meaning | |
---|---|---|
In #PRO:11? | Actual:5? | |
0 | 0 | Core - incompatible with disc |
1 | 0 | Core |
6 | 6 | EDS or UDAS |
9 | 9 | Drum - incompatible with disc |
10 | 9 | Drum |
13 | 13 | FDS (should not be used under UDAS) |
Each segment has its own address in the program file (in earlier
documentation often referred to as its drum address). This
address, which is allocated when the segment is reached during
compilation, is a number giving the address where the segment
would be if the compilation were restored to drum; the user can
refer to it as Dsegment. When the program file is on disc, the
segment will begin at word (Dsegment & #177) of bucket
(Dsegment /128+1); when the program file is in core the segment is
stored beginning at word Dsegment+74? The first segment compiled
will have program file address 0; the program file address of the
current segment is kept in the compiler variable 2?, which is
updated by #END.
When the program file is on drum or in core, the pseudo-types
10 and 1 respectively should now be used. When the former device
types 9 and 0 were used, the program file address of any segment
was always that of the word immediately after the last word of the
previous segment. However, compilations in this format could not
be restored to disc, and although the device types 9 and 0 can still
be used you are strongly advised not to do so. Eventually they will
be redefined to give the new format described below.
With this exception, the following rule now applies :
The program file address of the first segment of any overlay (including
that of any single-segment overlay or chapter) is the next multiple of
128 after the end of the previous segment.
The program file address of any segment which is not the first segment in
its overlay is the word following the end of the previous segment.
Normally the user will leave the compiler variable 2? unaltered. However, it may be desired:
- to increase it and so provide an unused space within the program file which will be dumped with the program.
- to decrease it for the purpose of overwriting a previously-compiled segment or a gap provided by (1) above.
It is permissible to increase 2? outside an overlay. Inside an overlay 2? should be increased only if the difference between 2? and 37? (which is described below) is the same at the end of the overlay as it was at the beginning. This can be achieved by coding like :
#BASE OVERLAY BASEADDRESS ... #DEF GAP=37?-2? #DEF 2?=2?+CHANGE ... #END [OF LAST SEGMENT IN OVERLAY #DEF 37?=2?+GAP #OVE
It is only permissible to reduce 2? outside an overlay.
The segment currently being compiled or mended is kept in an area known as the segment buffer. The compiler variable 34?, which may never be altered, points to that buffer. The first word of the segment is not necessarily in the first word of the segment buffer; it will be if the segment is the first in its overlay or is a chapter, or if the obsolete program file device types 0 or 9 are in use, but where the device type is 1, 6, 10 or 13 and the segment is not the first in its overlay the address of the first word is Dsegment±+34?. The reason for this is that in these cases the last (Dsegment±) words of the preceding segment are in the same (real or simulated) disc bucket as the beginning of the segment being compiled or mended, and so must be read down and written back with it. The explanation:
11?-9*11?<1*Dsegment±+34?
will always give the position in GIN where the first word of the segment
is stored.
The user variable 0? is the address (relative to the beginning of the segment) of the next word to be compiled. It is reset to 0 by #SEGMENT or #MEND. 0? may be altered; the effect of :
#DEF 0?=X
is equivalent to :
#TRA X+37?
The user variable 37? contains the address where the first word of the
current segment is expected to be when the program is loaded. It is set
by,#BASE (to the value of the second parameter) or by #SEGMENT outside
an overlay (to zero); #END adds into 37? the length of the segment. The
program address of the next word to be compiled is 37?+0?
The effect of altering 37? is to produce code to operate with a different datum from that of the rest of the overlay; for example, this could be done when compiling a PUC as part of a trusted program, or GELL as part of a GEORGE Executive. As mentioned above in respect of 2?, the value of 37?-2? must be the same at the end of an overlay as it was at the beginning.
PURPOSE OF DIRECTIVES
#SEGMENT will prepare the segment buffer to receive a new segment, and
#MEND will cause the current version of the segment to be read into the
segment buffer. During compilation of the segment all the local forward
references are filled in as the identifiers become set, so that the
segment is complete apart from any universal forward references. #END
causes the segment to be written away to the program file, assigns the value
of Lsegment, updates 37? and 2?, and lists the local identifiers used
(flagging any which remain unset - these will probably need mending).
When #DELETE, #MEND, #DUMP, #BIP, #RESTORE or #GO is read, all the
universal forward references are filled in which can be, irrespective
of which segment they may be in. #UNIVERSALS does not do this.
It is possible to list a segment at any listing level: 1? contains the current listing level, which can if required be recorded and reinstated after a temporary change :
FILE DETAILS
The program file is always unit 0 of its device type. Under GEORGE, the
following commands can be used to connect a file to GIN :
Device type 6 :
ONLINE *DAO(OVERLAY), (usn, filename)
or if the file is less than 245K words long
CREATE filename (*DA, BUCK1, KWORsize) ASSIGN *DA0, filename (OVERLAY)
Device type 9 or 10 (only if the file is less than 245K words long):
CREATE filename (*DR, KWORsize) ASSIGN *DR0, filename (WRITE)
CHECKSUMMING SEGMENTS
The facility described here can be suppressed by inserting the directive:
#CHECKSUM OFF
anywhere, but preferably before the first #SEGMENT directive.
Once this has been done, checksumming cannot be restarted later.
When the checksum facility is in use, the maximum number of words which the
user may compile in a segment is reduced to 1023. The compiler will insert
one extra word at the end of each segment, whose contents at the end of
compilation will be a negative checksum of the whole segment as it was
compiled. The purpose of this is to allow the user to check that segments
have not been corrupted, provided that he does not himself alter their
contents. A segment containing no words has no checksum; consequently
it is possible to have segments of length 0 or 2, but not of length 1.
It is guaranteed that the checksum of every segment is correct after the
implementation of the directives #DUMP, #DELETE, #RESTORE, #BIP
and #GO, and also after the directive :
#CHECKSUM NOW
76? is zero if the directive #CHECKSUM OFF has been read.
In GIN 514 onwards it will be possible to change the definition of the
checksum by the directive.
#CHECKSUM ADDR
before any segment is compiled. I.f this is done, the checksum of each segment will be such that the sum of the entire segment is equal to its program file address, and 76? will contain the value 2.
4.2 The Workfile
The workfile is where GIN stores the information it collects
in the course of a compilation which is of more than temporary
use. It may be a scratch file on drum or direct access, or
it may be an area of core. 13? holds its device type.
As a general rule, the mechanisms by which information is
transferred between the work file and core do not concern
the user. All that he is likely to need to know is that some
information will be in core (and thus directly accessible
to GIN) at any moment, and the rest (if any) will be on backing
store. Interludes which access the workfile have to obey GIN's
internal rules about how it can be accessed and altered, but no
one else needs to worry.
At any time 18?+0]+26] is the current size of the workfile.
When a compilation is dumped by #DUM, the workfile is dumped with it. The information in the workfile concerns:
- The names, sizes, positions etcetera of segments included.
- Information about the overlays in the program.
- The expansions of all the macros.
- The values of identifiers, and the means by which they can be inserted when they become known.
The workfile is always unit 1 of its device type. Under GEORGE, the following commands can be used to connect files to GIN (remembering that if the workfile exceeds 245K the ONLINE command is necessary):
Type 6:
ONLINE *DA1(SCRATCH), (blocks,1,#usn,#usn,.,..#usn) or CREATE filename (*DA,BUCK1,KWOR size) ASSIGN *DA1, filename (SCRATCH)
Type 9:
CREATE filename (*DR,KWOR size) ASSIGN *DR1, filename (SCRATCH)
In the ONLINE command, blocks is the size of the workfile in words divided by 128. In the CREATE commands, size in the size of the workfile in words divided by 1024.
4.3 Dumping the Compilation
There are two ways of dumping compilations to magnetic tape:
- The #BIP directive writes a dump of the program file only in a form such that the program can be loaded from it.
- The #DUMP directive writes a dump of GIN, the program file and the workfile in a form such that the compilation can be restored from it and continued.
In each case the dump can be in one of two forms:
- Enclosed in a subfile on tape such that the program can be loaded by #XKOF, GEORGE's macro FIND, or a similar process. (Several programs, or several versions of a program, or #BIPped and #DUMPed copies of the same program can be kept on one tape in this format).
- At the beginning of a tape such that it can be loaded by the Executive directive FIND #prog.
There are no built-in facilities for outputting to any device
other than magnetic tape. The user can of course write his
own interlude to do so, or use the one given in Section 10.6.2.
Dumping a compilation in any form does not prevent the user
from continuing the compilation immediately afterwards,
as long as #JUMP is used to exit from interlude compilation mode.
For example, it is common practice in long compilations to
dump at intervals so that in the event of any failure all
is not lost. Alternatively, it would be possible with some
care to devise a series of programs each of which contained
the preceding one as a subset. However, users will normally
wish to end up with a dumped copy of the compilation whatever
else they may do.
To dump a compilation GIN requires certain information to be
provided. For this purpose, the #BIP or #DUMP directive follows
an interlude in which the information has been stored, and some
of the parameters to the directives give pointers to the blocks
of information stored. The interlude begins with a #INTERLUDE
directive which must be accompanied by a #ORDINARY directive;
it will end with an EXIT 0 0 labelled by a local, and be followed
by a #JUMP directive to enter it at that label. (This is to
switch GIN from interlude compilation mode to program compilation
mode). This is followed by a #EXTENDED directive if required
and the #BIP or #DUMP.
The tape to be used for output must have been opened by #OFW, and the
user may wish to use #POSITION either to overwrite an existing subfile
or to position at the trailer label.
The information required to be given in the interlude is as follows:
- A request slip whose address is given as %B of the dumping directive. This is mandatory; the 14 or 16 words of the slip are dumped at the beginning of the program. GIN will calculate the checksum of the slip. In the case of #DUMP only, the peripheral and core requests will be altered by GIN for its own needs.
- Optionally, a subfile sentinel giving the name of the subfile containing the dump. If %C of the dumping directive is null the dump will be FINDable: the output tape will be relabelled PROGRAM name where name was given in the request slip and the dump will follow immediately. If present, %C is a pointer to a subfile sentinel.
- In the case of #BIP, optionally, a supplementary request slip giving the operating modes of the program. GIN will checksum the supplementary request slip.
Full details of the formats of these blocks can be found in the 1900 Programmers' Reference Manual; the brief information below should serve as a guide.
REQUEST SLIPS
A request slip consists of either 14 or 16 words as specified in Word 0.
Its purpose is to inform Executive about the program.
Word 0 If the slip is 14 words long: #73160001 If it is 16 words long: #73200001 Word 1 The name of the program as four characters Word 2 Bits 0 and 1: Retain load peripheral bits Bits 2 to 5: Trusted status bits Bits 6 to 8: Number of type 0 peripherals required on loading Bits 9 to 11: " 1 " " " Bits 12 to 14: " 2 " " " Bits 15 to 17: " 3 " " " Bits 18 to 20: " 4 " " " Bits 21 to 23: Reserved Word 3 Bits 0 to 8: Core request of the program in units of 64 words Bits 9 to 16: Reserved Bits 17 to 23: Core request of the program in units of 32K words For example, 32896 words could be requested by +2:1 Word 4 Reserved Word 5 Overlay directory word or zero (Note 1) Word 6 Address for entry to own-monitoring Word 7 Bits 0 to 11 As two characters the priority of Member 0 Bits 12 to 17 #77 Bits 18 to 23 The member number, i.e. 0 Words 8 to 12 In the same format as word 7 for members 3, 1, 4, 2, 5 respectively, or zero if the member concerned is absent (Note 2) Word 13 Will hold the checksum: the user should leave it zero. Words 14, 15 If word 0 contained #73200001, these contain additional program name characters
Notes:
1. It is not likely that any GIN program will need to set this word non-zero.
2. The setting-up of these words in the request slip is all that is required by GIN to make a program multi-member; the code
of such a program is compiled as one unit, and GIN needs to
make no assumptions as to which members can obey any given
part of the code.
SUBFILE SENTINELS
Word 0 +6 Word 1 Bit 0 = 0 since subfile is not checksummed Bits 1 to 23: Reserved Words 2 to 4 Subfile name Word 5 Zero for initial sentinel of this subfile Word 6 Subfile generation number Words 7 to 19 May be left zero, or may be set up as described in the 1900 PRM (in which case word 12 should contain A1G5) or may contain other information as required. GIN programs often use word 7 to contain the binary date (4?) and words 8 and 9 to contain the date in characters (47?, 48?).
SUPPLEMENTARY REQUEST SLIPS (#BIP only)
Word 0 #73100006 Word 1 B21=0 for direct branch mode =1 for extended branch mode B23=0 for 15 bit address mode =1 for 22 bit address mode . Words 2 to 6 Reserved Word 7 Negative checksum inserted by GIN; the user should set it up as zero.
EXAMPLE
The following example shows how an extended branch mode program can
be #BIPped into a subfile at the beginning of a tape.
Example of #BIP
#ORDINARY #INTERLUDE REQUEST #73160001, 4HFRED #1000 [ONE LINE PRINTER +END+63/64:0 [END POINTS TO LAST WORD OF PROGRAM 0,0,+ILLEGAL [ENTRY FOR OWN-MONITORING 4H70←0 [PRIORITY 70 #REPEAT 6 0 SENTINEL 6,0,12HSUBFILE NAME 0,0,4?,47?,48? #REPEAT 10 0 SUPPREQUEST #73160006,5 [EBM AND 22AM #REPEAT 6 0 NTRY EXIT 0 0 #JUMP NTRY #EXTENDED #OFW MT1 USERTAPE #BIP MT1 REQUEST,SENTINEL,SUPPREQUEST
In the case of #DUMP, words 3 and 4 of the request slip can be left zero, and the supplementary request slip will be absent.
FORMATS ON MAGNETIC TAPE
Full details of the formats produced on magnetic tape can be found in Section 11.2.
4.4 Mending the Compilation
There are invariably times when the user wishes to alter his
program in some way, either because he has discovered an error
or because he wishes to enter certain parameters in his program.
Many systems have no simple way of doing this without
recompiling the program, but it is possible with GIN.
The facility which GIN provides to do this is the mend. A
mend is a sequence of coding starting with a #MEND directive
and ending with #END. It amounts to re-opening for compilation
a segment which has already been compiled. The compiled segment
is brought down from backing store, changes are made, and the #END
causes the altered segment to be put back in its place in the
program file.
The directive #TRANSFER is used to specify the address within
a segment where the next word is to be put; the parameter
(any expression without forward references) specifies the destination
address of the word concerned, i.e. the sum of the segment
base address and the displacement of the word from the start
of the segment. The #TRANSFERs do not have to move sequentially
up the segment.
If the parameter of #TRANSFER would be a decimal number, a
numerical label may be used; the number concerned is written
starting in column 1. GIN will at present error-flag a numerical
label which is not followed by a data constant, instruction or
macro call, but such a usage will in fact give the expected
result.
At the beginning of a mend, GIN will not know of the existence of any local identifiers (and specifically you cannot refer to those in the original segment), but universals can be used (and if necessary defined) and locals can be set up and referred to. The only restriction on what may appear in a mend are:
- The mend cannot change the length of the segment.
- An interlude within a mend is liable to corrupt the segment, and should only be used if the subsequent contents of the area concerned are immaterial.
In order to allow for corrections to segments, it is normal
practice to leave an area in each overlay which can be used to
contain any extra code necessary. A similar area below 4096
is also useful for extra data constants. The #GAP directive
is useful for this purpose, and normally a universal should be
used to label each gap area.
The decision on whether to use the #TRANSFER directive or numeric labels
is purely a matter of convenience. A source record on cards or paper
tape with no numeric label on it could be used for editing the main source
later, but takes more punching.
It is permissible to give a version number as well as a segment name in the #MEND directive In this case if a different version was in fact compiled the #MEND directive will be in error.
#MEN SEGNAME #TRA ALABEL+17 PETE LDN 2 4 ORS 2 ADATA #TRA APATCHAREA LDX 2 GSBA BNG 2 PETEB [or BNG 2 37?+2 - in either case branches #DEF PETEB=37?+2 [to the 2nd word of the segment BRN PETE #TRA 37?+20 BRN APATCHAREA 130 [THIS WILL BE FLAGGED J LDN 2 9 306 CALL 4 ASUBROUTINE #END
THE MEND STATUS SYSTEM
The system described below will be provided in GIN 511. It is intended
for the needs of GEORGE, and non-GEORGE users can ignore it completely if they wish.
In this system, it is possible (but not obligatory) for the segment name (and if present the version number) in a #MEND directive to be followed by a comma and a positive decimal number identifying the mend. If a mend number is present in a #MEND directive, the action taken depends on two numerical quantities which will previously have been provided:
- The testing level currently in use
- The status associated with the particular mend number.
The testing level is provided by the #TEST directive. It is a non-negative integer, and if no #TEST directive has been compiled it is zero.
Each #TEST directive resets the testing level, overriding the effect of
any previous ones; the testing level can be obtained from 75?
The status of an individual mend is set by the #STATUS directive, and is
assumed to be zero if no #STATUS directive has been read for the mend.
It may be positive, negative or zero. In the #STATUS directive the first
parameter is the mend number, and the second is the status which is to be
assigned to that mend. This status replaces any previous status the mend
may have had.
A #MEND directive which has a mend number parameter will be compiled
only if the status of the mend is strictly greater than the testing level.
In particular, since the testing level is non-negative a mend cannot be
compiled if its status is negative or zero. If a mend is compiled, its
status is thereby changed to #40000000 (thus preventing compilation of
any other mends having the same number). If not, the next source line
compiled will be that immediately following the next #END directive.
A mend having a mend number for which no status has been given is not
compiled. A mend having no mend number will be compiled.
The way this system is intended to be used is a result of certain practical
details of the development of GEORGE. At any time a very large number
of mends to the system will be in existence, some of them totally untried,
others apparently tolerable but not fully tested, others believed to be
correct, and others known to be unsatisfactory. It is much more convenient
to hold all these mends on a magnetic tape and cause the compiler to
select those which are to be compiled than to spend time on the risky
practice of selecting and combining card packs. Each correction is
identified by a number, and the number is associated with a status
by #STATUS. Completely untested mends will have status zero, and those
which have been tested to various extents will be assigned a status which
is increased as confidence in their correctness increases. Bad mends have
a negative status. By changing the testing level the reliability of a
compilation can be adjusted; a high testing level produces a compilation
in which some known bugs will be uncorrected but doubtful mends are
excluded, while a low level gives one where mends which are thought
tolerable can undergo further general testing. At the same time it is
possible to adjust the status of selected mends in order to test them in
particular.
It will occasionally be necessary to find out the status of a particular mend. The term n! (where n is the mend number) may be used in expressions alone or in combination with any other permitted term; its value is the status of the mend n. If the status is not set, the value zero is inserted and the line is error-flagged with a C; evaluation of the expression continues.
THE MEND NUMBER SEGMENT
When the above system is in use, it is convenient to be able to communicate
to the program under compilation the numbers of all mends actually incorporated.
The mend number segment is a means for doing this.
In any compilation in which the top 12 bits of the compiler variable
28? are non-zero the mend number segment can be compiled. In GEORGE
these bits contain the mark of GEORGE being compiled, and in what follows
“the mark of GEORGE” is to be taken to mean this number.
To use the code which sets up the mend numbers segment, it is necessary
to #INCLUDE and compile a segment named PMENDNOS whose length is at least
417 words, and to ensure that the mark of GEORGE is non-zero. If this
has been done, the contents of the first 417 words will be set up as
described below when any of the directives #DUMP, #DELETE, #RESTORE,
#BIP or #GO is read; following words will not be changed by the compiler,
and can contain whatever the user requires.
It is assumed that all mend numbers will be five or more digit decimal
numbers, starting with the mark of GEORGE; that is, mends for Mark 7
are in the range 70000 to 79999, for Mark 8 in the range 80000 to
89999, and so on. The lists of mend statuses held within GIN are
examined and for each mend number in the range described above whose
status is #40000000 (indicating that the mend has been compiled) a bit
corresponding to the last four decimal digits is set in PMENDNOS. Thus
if the last four digits are 0000, bit 0 of word 0 is set; if they are 0023,
bit 23 of word 0; if they are 0024, bit 0 of word 1; if they are 9999,
bit 15 of word 416.
If a mend number outside the permitted range is discovered, a line will be printed reading
MEND NUMBER OUT OF RANGE: mend number
If several are discovered, the order of printing them is undefined.
MEND CHECKSUMS
The system described below is available in GINS12 on, and was also
mended into the version of GIN510 used to compile GEORGE 3 and GEORGE 4
Mark 6.5 onwards.
Whenever a mend is compiled GIN keeps a running check-quantity (colloquially but inaccurately called a checksum) which depends on the source in the mend. The lines included are all the lines read from cards, paper tape or magnetic tape which occur between #MEND and #END. If the #MEND directive occurs in a macro expansion, that line is not included in the checksum, otherwise it is. The #END line is not included in the checksum, and if #END occurs in a macro expansion the macro call is not included either. Thus if MEND is any macro containing #MEND and END is any macro containing SEND the lines taken into account are:
a. | MEND | |
code | the lines in “code” only - not END itself | |
END | ||
b. | #MEND segment | |
code | “code” and the #MEND directive | |
#END | ||
c. | MEND | |
code | the lines in “code” only | |
#END | ||
d. | #MEND segment | |
code | “code” and the #MEND directive | |
#END |
To calculate the checksum, each line in the mend is first converted into
a canonical form in which each series of consecutive space characters
is converted into one space, and “[” and any characters after it are
omitted. 'If the canonical form consists entirely of spaces or starts with
“# ” it is ignored. Otherwise
- if it is less than 72 characters long it is extended to 72 characters with spaces and summed as 18 words by a SUM instruction
- if it is more than 72 characters long it is extended to the original length of the line (before comment and extra spaces were removed) and that number of words is summed.
This gives the checksum of a single line. There will already be stored the
check-quantity for the lines up to and including the last line; this is
of course zero initially. It is shifted left circularly one place and the
checksum of the present line is exclusive-OR'd into it. The checksum
of the entire mend is the sum of all lines except the last read from
cards, paper tape or magnetic tape.
In the #END directive the user may specify an octal number as a parameter.
If it is present, this number must equal the check-quantity of the mend;
if not, GIN will halt “MEND CKECKSUM ERROR” or (if the mend has a number]
“MEND NO. nnnnn CHECKSUM ERROR.” In any case, the actual checksum of the
mend is printed out on the right-hand side of the listing.
Thus normally when a mend is first compiled no parameter to #END will be
given; when it has been compiled once the checksum will be copied from
the listing to the #END directive, thus protecting the user against miscopying of the mend or the loss, insertion or interchanging of cards.
In the following cases, GIN will notice a checksum error even though the difference in the source does not cause a difference in the compiled code:
- Alternative forms of the same directive, e.g. #MEND for #MEN
- The presence of one or more spaces where all spaces are ignored, e.g. on either side of the comma separating macro parameters
- The internal re-arrangement of expressions where the order is not significant
- The inclusion or exclusion of code which is skipped.
Where a text preceded by nH contains spaces, a change in the number of
spaces at any point within the text will not cause the checksum to be
affected.
Blank lines, lines consisting entirely of comment, lines within a macro expansion and the last line of the mend (i.e. #END or the macro call which includes it) are not included in the checksum. It is possible to compile a mend which is terminated by a macro containing #END, and insert the checksum printed out as a parameter to the macro in such a way that the checksum is passed on as a parameter to #END.
4.5 Entering the Object Program
It is possible to run GIN in a “compile-and-go” mode, entering the compiled program as soon as compilation is complete. The user will probably have secured a permanent copy of the program by #BIP and/or #DUMP, but this does not affect entry. The directive used is #GO, and there are two ways of using it.
ENTERING WITHOUT A REQUEST SLIP
This is the simplest way of using #G0. All that is required is to complete the compilation (including, for example, a #OVERLAY directive) and write
#GO address
where address is any GIN expression giving a value between 20 and
29 or within Overlay 0 of the program. Overlay 0 will be brought
into core and entered at the appropriate point.
The program will be in the same state as GIN in respect of:
- Core size and program name.
- Operating modes: the address mode may be either 15 bit or 22 bit address mode, the branch mode will be direct.
- Trusted status: normally, none.
- Self-monitoring: at present none, but this is liable to alteration.
- Which peripherals and files are connected to the program, except that the workfile is closed.
ENTERING WITH A REQUEST SLIP
If this form of the directive is Used, #GO must be within an
interlude,(that is, no #JUMP since the last #INTERLUDE) and outside
a segment. The request slip must be at the beginning of the
interlude, and the word following it (the 15th or 17th word according
to the length of the request slip) must contain the operating modes
of the program, B21 indicating the branch mode and B23 the address
mode. If this word is invalid 15AM and DBM are assumed. As with
#BIP and #DUMP, GIN will fill in the checksum word. An alteration
may be made in future so that a standard supplementary request
slip is an acceptable alternative.
GIN will arrange to have the amount of core needed to hold the program, and will reserve the peripherals requested by word 2 of the request slip. Where possible GIN uses the same peripherals as it had before. After this the request slip will be implemented in other ways by issuing a RRQ instruction. This instruction can go illegal in at least two ways.
- The name in the request slip may be the same as that of one already in the machine; the operators should remove the other program and type GO, or cause GIN to continue from the next instruction but one.
- The request slip may ask for the trusted status to be increased; in this case it will need to be altered.
ENVIRONMENT ON ENTRY
The main overlay will be in core and will be entered at the specified address. In some GIN versions, the program will halt: LD before entry if the #OVERLAY directive had H specified. The accumulators are set up as follows:
X0: | Should contain the program file device type (i.e. the value of 117 at the time of entry) but may be wrong. |
X1: | Bits 0 to 8 Device type of the slow input peripheral |
Bits 9 to 23 Base address of Overlay 0 | |
X2: | Core address of the bootstrap. |
X3: | Either: |
-1 if no request slip was supplied. | |
0 if a request slip was supplied and accepted. | |
Positive non zero if the request slip was rejected. | |
X4: | The actual operating modes (reply from GIVE/9). |
X5: | The current core size (reply from GIVE/4). |
X6: | Either: 0 if no peripheral request or the number of each slow peripheral type obtained in the format of word 2 of the request slip. |
X7: | The object program entry point address. |
THE LOADING BOOTSTRAP
The bootstrap used to load the program is about 55 words long, and its
exact length is available in 71? This bootstrap loads the program from
its initial position in core or on backing store, checking if necessary
for transfer failures. At the end of the loading process GIN branches to
word 16, where it has previously put the instructions required to alter the
core-size and enter the program. Thus no program which will use #GO may
preset words 16 to 19.
If the program requests more core than is needed for its main overlay,
or does not submit a request slip, the core not defined will contain
whatever GIN put there. In particular, if the compilation took place in
core the area above 74? will contain the program file, unless it has been
overwritten.
If the bootstrap can fit between word 31 of the program and the base of Overlay 0, it will be put there. In any other case it will be put higher up in core, wherever it will be out of the way of the loading process. In extreme cases this can lead to more core being required, in which case GIN will try to obtain it.
ERROR CASES
If there is any error in the compilation of #GO, GIN will halt: GE.
The operators may type GO and cause the next source record to be read,
or GO at the next word but one to enter the compiled program anyway.
(This may have unpredictable results). If any included segment has not
been compiled GIN will halt: GS. Restarting GIN will force entry.
Versions of GIN up to GIN510 may halt: GB if there is nowhere to put the
bootstrap. It is not possible to recover, and GIN's entry points will
have been overwritten so that a GIN postmortem cannot be obtained.
GIN511 onwards may halt: GC if there is insufficient core for the loading
process. If more core can be provided this should be done.
If a peripheral requested is unavailable, GIN will halt: GP. If GIN is restarted in the ordinary way it tries to re-allocate the peripheral, if at the next word but one it abandons attempts to get peripherals of that type.
#GO WITH OVERLAID PROGRAMS
An overlaid program which has been compiled to backing store can read its overlays from the program file as and when required. A program compiled in core can, unless it submitted a request slip reducing its core size, read each overlay from upper core; the address where a segment x can be found is 74?+Dx. This address can be above 32K. In the highly unusual case of the length of Overlay 0 exceeding 74?, the beginning of that overlay will have been overwritten by its own end. This should not worry any program.
4.6 Special Facilities for Executive Compilations
The facilities described in this Section are available only in
special versions of GIN produced for the compilation of Executives.
These versions are normally issued directly to the Executive
writers at West Gorton. GEORGE Executives to the New Interface
are written in GIN.
The problem which Executive compilation needs to surmount is the fact of the existence of areas (known as “forbidden areas”) defined relative to Executive's datum in which no code or data may be stored. The position and length of these areas is declared to GIN by the #FRB directive. If in the course of compilation the next word to be compiled would fall in a forbidden area, a branch is compiled and put in the place of the word now being compiled, and this branch transfers control to the next location not in a forbidden area. The word originally compiled (adjusted if required to allow for its changed position) is placed in this location. For example, if a forbidden area exists of length 40 words starting at word 256, the relevant code might read:
#FRB 256,40 #TRA 254 LDX 6 BILL NGX 5 FRED ADX 5 6
and the code actually compiled is
254 LDX 6 BILL 255 BRN 296 296 NGX 5 FRED 297 ADX 5 6
If the NGX instruction had been labelled, the fact that it would
need moving would be detected when the label was compiled, and
the value of the label would be 296.
As it stands, this arrangement would entail the possibility of
splitting up areas (such as tables) which need to be in consecutive
words. To prevent this, the #LENGTH directive will ensure that
the next n words are consecutive and do not overlap any forbidden
area.
If it is required to cancel the #FRB directives already issued, the user should insert
#DEF 31?+0=0
This will zeroize a count which GIN keeps of forbidden areas.
Further such areas c8# be defined thereafter in the usual way.
A forbidden area may be up to 2048 words long. For this reason, the
maximum length of a segment in Executive GIN is increased to 4096 words.
Version 510 onwards of Executive GIN will not dump (by #BIP or #DUMP
directives) any block of 512 words which is entirely zero.
Version 511 onwards of Executive GIN will zeroize the entire program file
before compilation starts.
Except for Version 512, Executive Gin does not contain the segment checksum facility.