For paper tape and communications a seven bit character set is used, derived from an early version of ASCII, described as the ECMA (European Computer Manufacturers Association) character set in ICL documentation.
For conversion between the internal 6 bit code and ECMA codes a shift system is used. Three 6 bit codes were used as α (alpha), β (beta) and δ (delta) shifts. When a α shift is output all subsequent six bit characters would be output in upper case. When a β shift is output then subsequent six bit characters would be converted to their lower case equivalents. When a δ shift is output then the next character would be a control character.
The exact mapping is:
octal
code
6 bit
α
β
δ
#00 0 0 0 DLE (TC7)
#01 1 1 1 (DC1)
#02 2 2 2 (DC2)
#03 3 3 3 (DC3)
#04 4 4 4 (DC4)
#05 5 5 5 NAK (TC8)
#06 6 6 6 SYN (TC9)
#07 7 7 7 ETB (TC10)
#10 8 8 8 CAN
#11 9 9 9 EM
#12 : : : SUB
#13 ; ; ; ESC
#14 < < < FS (IS1)
#15 = = = GS (IS2)
#16 > > > RS (IS3)
#17 ? ? ? US (IS4)
#20 SP SP SP NUL (TC0)
#21 ! ! ! SOH (TC1)
#22 " " " STX (TC2)
#23 # # # ETX (TC3)
#24 £ £ £ EOT (TC4)
#25 % % % ENQ (TC5)
#26 & & & ACK (TC6)
#27 ' ' ' BEL
#30 ( ( ( BS (FE0)
#31 ) ) ) HT (FE1)
#32 * * * NL (FE2)
#33 + + + LF (FE2)
#34 , , , FF (FE3)
#35 - - - CR (FE4)
#36 . . . SO
#37 / / / SI
#40 @ @ _
#41 A A a
#42 B B b
#43 C C c
#44 D D d
#45 E E e
#46 F F f
#47 G G g
#50 H H h
#51 I I i
#52 J J j
#53 K K k
#54 L L l
#55 M M m
#56 N N n
#57 O O o
#60 P P p
#61 Q Q q
#62 R R r
#63 S S s
#64 T T t $
#65 U U u ]
#66 V V v ↑
#67 W W w ←
#70 X X x |
#71 Y Y y }
#72 Z Z z ~
#73 [ [ { DEL
#74 $ ALPHA ALPHA
#75 ] BETA BETA
#76 ↑ DELTA DELTA
#77 ← FILL FILL
For example, the string "You want $200, are you MAD" would be coded as:
$Y]OU WANT ^T200, ARE YOU $MAD
Where $ is an α shift, ] is a β shift and ^ is a δ shift.
The text "WARNING", CR, LF, BEL would be output by:
$WARNING^-^*^'
Note the following differences between the ICL ECMA character set and ASCII:
7 bit
code
ECMA
ASCII
#012 NL LF
#013 LF VT
#044 £ $
#134 $ \
#136 ↑ ^
#137 ← _
#140 _ `
The NL/LF difference is largely notational, to output a carriage return, linefeed to a terminal the system outputs the ECMA sequence "CR", "NL".
(On some output devices the uparrow and leftarrow were displayed as the newfangled ASCII caret and underline, on some the underline is displayed as the backquote).
Note that the ICL/ECMA character set has no backslash.
In order to allow localisation the "{", "|", "}" and "~" characters could be replaced by national variants, for example "é", "ç", "è" and "à" in France.
Zone 0: // control characters
0x00 .. 0x0f (#000 .. #017, NUL .. SI)
=> DELTA, #20 .. #37
0x10 .. 0x1f (#020 .. #037, DLE .. US)
=> DELTA, #00 .. #17
So 6bit = DELTA, 7bit XOR #20
Zone 1: // characters same in ALPHA and BETA
0x20 .. 0x2f (#040 .. #057, " " .. "/")
=> #20 .. #37
0x30 .. 0x3f (#060 .. #077, "0" .. "?")
=> #00 .. #17
so 6bit = 7bit XOR #60
Zone 2: // ALPHA shift characters
0x40 .. 0x5b (#100 .. #133, "@" .. "[" )
=> ALPHA, #40 .. #73
so 6bit = ALPHA, (7bit OR #40) AND #77
0x5c .. 0x5f (#134 .. #137, "$" .. "<-")
=> DELTA, #64 .. #67
so 6bit = DELTA, (7bit XOR #50) AND #77
Zone 3: // BETA shift characters
0x60 .. 0x7b (#140 .. #173, "ul" .. "lbrace" )
=> BETA, #40 .. #73
so 6bit = BETA, 7bit AND #77
0x7c .. 0x7f (#134 .. #137, "N2" .. "DEL")
=> DELTA, #70 .. #73
so 6bit = DELTA, (7bit XOR #04) AND #77
(* the "zone" is normally the top 3 bits, but two works better for clarity).
init:
if (shifted) {
shift = 0140; # alpha
delta = FALSE;
}
if (!shift) {
switch (ch) {
case 000 ... 037: // '0' ... '?'
return ch ^ 060;
case 040 ... 077;
return ch ^ 0140;
}
}
else {
if (delta) {
switch (ch) {
case 000 ... 037:
output (ch ^ 020); // control characters
break;
case 064 ... 067:
output (ch ^ 0150); // ^T => $
break;
case 070 .. 073:
output (ch + 0104); // ^X => |
break;
}
delta = false;
}
else {
switch (ch) {
case 000 ... 037: // characters same in ALPHA and BETA
output (ch ^ 060);
break;
case 040 ... 073; // upper or lower case
output (ch ^ shift);
break;
case 074:
shift = 0140; /* alpha */;
break;
case 075:
shift = 0100; /* beta */
break;
case 076:
delta = true;
break;
case 077: /* Filler character, ignore */
break;
}
}
}