KAL4 Assembly Language
If you do not know KDF9 Usercode
The KAL4 assembly language originated as a project for
an MSc student at Leeds University, and was so successful
that it became the systems programming language of choice,
and the target language for the FORTRAN compiler (written
The language took mnemonics from Usercode, memory addressing from PAL III (PDP-8 Assembly
Language number 3), and scope rules from Algol 60.
Memory locations are labelled by identifiers followed by a colon.
The scope of identifiers is controlled by begin and end,
just as in Algol, Ada or Pascal, c.f. curly brackets in C, C++ or Java.
Additionally a block may export internal labels. offering a faciity
somewhat like the Ada package.
An instruction takes one of 5 syntactic forms:
It is a good idea to read some real KAL4 code to get a feel for the language.
The only surviving KAL4 program is the KAL4 assembler itself,
and it does contain one or two tricks which are shameful in the light
of a few decades worth of hindsight.
Here you can browse a newly written small piece
of code that takes a paper tape image of a magnetic tape and copies it to a magnetic tape,
ready for input to the Kidsgrove Algol compiler.
This is a listing produced by a modern assembler, and shows the machine code at the left,
and the source code on the right.
The raw source code is here.
e.g. DUP; CAB; +; MULT; ×+F; OUT; EXITH;
Semi-colons come at the ends of instructions just as in Usercode.
Note: the non-ASCII symbol × which occurs in many Usercode mnemonics can always be replaced by MULT.
÷ can be replaced by DIV.
- <mnemonic> <number>;
e.g. PARQ12; SET5; SHL16; FM15;
Note: All fetch instructions start with F, so the last instruction does a fetch of M15 into N1.
All store instructions start with S.
e.g. F.radix; SET.buff; S.error; J.fail
Here radix, buff, error and fail will
be defined by placing them in the code at the desired memory location, and terminated by a colon:
e.g. loop: F.count; NEG; NOT; JGEZ.loop;
- <mnemonic> <number> / <number>;
e.g. CIFRQ3/4; SMM5/7; FMMQ7/0; FMMQHN7/5;
The mnemonics here mostly differ from Usercode.
The first instruction above, copies Counter and Increment of Q3 into Q4.
The second instruction stores N1 into the word whose address is obtained
by adding the contents of M5 and M7.
In the third instruction the letter Q has the effect of
counting on Q7.
In the fourth instruction the address is the contents of M5
plus half the contents of M7 plus 1 because of the N.
Note: the effect of Q and/or H acts on the Q-store
whose number is closest.
- <mnemonic> <number> . <address>;
e.g. F11.radix; SM3.error;
Here the contents of the modifier register are added to the address of the label.
In this example each element of an array called count will be decremented by 1:
e.g. loop: FM15.count; NEG; NOT; SMQ15.count; JCNZ15.loop;
There is a faciity for defining the value of an identifier to be something other
that the current code location, such as Z0 = 11103:.
Note the colon terminator, not semi-colon.
The special identifier prog always has the value
of the location at which the next instruction (or data) will be placed.
The code prog=1600: causes assembly to contine from address 1600.
An item starting with an equals sign, defines a preset value.
=H defines a half-word value.
Octal values are prefixe with a hash.
The KDF9 EXIT has an address part, which is added to the address
in the SJNS.
So EXIT will jump to the address in the SJNS, whereas
EXIT.1 will jump to 1 word after the address in the SJNS.
In Usercode this would be EXIT2.
The machine really has two instructions, EXIT and EXITH.
The second instruction adds an extra half word,
The Usercode EXIT1 becomes EXITH in KAL4.
A single slash character introduces a comment, which extends to the end of the line.
The listing of the genuine assembler is
Also the KAL4 user manual may well help.
It is online as scanned images
Usercode was the official English Electric assembly language for KDF9.
A programming manual is