summaryrefslogtreecommitdiff
path: root/doc/icws94.txt
blob: 3643e3e680660fcd8732c042685303f4d4273546 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
Annotated Draft of the Proposed 1994 Core War Standard.

Version 3.3
Annotated Draft Last Modified: November 8, 1995
Last modified by: Damien Doligez
Base draft by: Mark Durham

[Planar's intro to ver. 3.3]

This is a list of what I've changed from version 3.2:

+ Changed "pointer counter" to "program counter" in Mark's intro.
+ Changed "A-pointer" and "B-pointer" to "A-number" and "B-number" in
  Mark's intro
+ Added A-number indirect, A-number predecrement, and A-number
  postincrement to the description of addressing modes.  Changed
  "indirect", "predecrement", and "postincrement" to "B-number indirect",
  etc.
+ Clarified the fact that newlines are not considered whitespace.
+ Added the SEQ, SNE, and NOP opcodes
+ Changed a reference to "load file" into "assembly file" in section 2.3
+ Simplified the grammar entries for label_list and newline.
+ Removed the grammar entries for list, simplified those for files.
+ Stop parsing (not simply assembling) after the END.
+ Added predefined labels.
+ Added ";assert" comment convention.
+ Specified the behaviour of {DIV,MOD}.{I,F,X} when a component of the
  A-value is 0.
+ Fixed a discrepancy between the text and the sample code on the
  behavior of JMN and DJN, >>>BY CHANGING THE TEXT<<<.  The old version
  would not jump (for JMN.F and DJN.F) if either field of the target
  was zero.
+ Added SEQ as a synonym to CMP (in description and code)
+ Added SNE (in description and code)
+ Added NOP (in description and code)
+ Specified the behavior of SLT.F
+ Fixed the bug with label "noqueue" in the ARITH_DIV macro.
+ Updated the conversion tables.
+ Updated the list of new opcodes and addressing modes.

This is a list of things to do:

+ Decide on whether to remove read/write distance.
+ Add ROUNDS and PSPACE and LDP and STP.
+ Define "battle" and "rounds" in the glossary.
+ The assembler and run-time environment must agree on the value of
  predefined labels.  Make this fact explicit.
+ Add CURLINE and VERSION.
+ Decide which one takes precedence if the description and code
  disagree and write this decision explicitely in the standard.
+ Add the comparison and logical operators to the description and
  to the grammar of expressions.
+ Specify the operator precedence for expressions (if only by saying
  it's the same as in the C language).
+ Add multi-line EQUs and FOR/ROF macros.

[Stefan's intro to ver. 3.2]

The sample simulator was rewritten extensively based on suggestions by Damien
Doligez ("Planar") and on our experience implemementing the pMARS, the first
ICWS'94 simulator. Thanks to Planar and also Steven Morrell for pointing out
many omission and ambiguities in the previous revision. Other readers of
rec.games.corewar have also provided many helpful comments.

Changes incorporated since last revision:
    Text:
        - corrected various typos
        - clarified behaviour of JMN, JMZ and DJN with .F modifier
        - defined behavior for division by zero
        - incorporated EOF in grammar, eliminated "empty" expression
        - limited definition of whitespace to <space> and <tab>
        - labels are case sensitive
        - "pointer counter" -> "program counter"
        - added default modifier rules (A.2.1.1-2)
    Sample code:
        - macro'ized ADD/SUB/MUL/DIV code
        - test for division by zero
        - .AB in JMZ, JMN, DJN works now like .B; .BA like .A
        - fixed DJN.F, JMN.F

To do for next revision:
        - fix formal grammar (still flaky)
        - exclude/redefine read/write limits, add jump limit?

[Mark's intro to ver. 3.1]

The information presented here is not part of the Draft proper.  The Draft
proper immediately follows these annotations, beginning with the line
"0001 Draft of Proposed 1994 Core War Standard".  The content lines of the
Draft proper are numbered for easy reference.  The numbers may or may not
be included in the final Draft.

Internal annotations were removed to clean-up the draft for presentation to
the ICWS for comment.  These annotations which precede the draft take their
place.

Open-ended references were removed to clean-up the draft for presentation
to the ICWS for comment.  The question of the inclusion or exclusion of
various opcodes, modes, etc. has not been closed as of yet.  Such additions
or deletions should be finalized by the next draft however.

Previously speculative references were either included or removed to
clean-up the draft for presentation to the ICWS for comment.  See above.

The Load File section was rewritten to aid in the readability of load
files.  It was deemed best that Load Files be a subset of Assembly Files;
therefore Load Files should logically follow the Assembly File section.
For that reason, the two sections have been swapped.

Example MARS code is now included.  Other parts of the standard, such as
validation, remain incomplete.  The remaining incomplete sections do not
impact on the other sections of the standard and so can be completed even
after consideration of the rest of the draft by the ICWS.  Alternatively,
they could be issued as separate documents.

The MARS code is specifically designed to mirror the draft as closely as
possible.  There is a multitude of optimizations which could have been
made but were not in order that the example code could serve as a
possible clarification of obscure parts of the draft.  Do not suggest
changes to the example code which speed up processing at the expense of
mirroring the draft.

Several changes have been made with the goal of expanding the flexibility
of Core War without compromising backwards compatibility and without
seriously altering the nature of the game.  In that vein:

The modulus '%' operator was added to the Assembly File section.

Read and Write limitations with folding have been clarified.  These limits
allow the possibility of warriors essentially running in a mini-core inside
core, folding out-of-bounds access attempts back into accessible memory.
The main advantages to folding are: old-style bombers like Dwarf do not
unfairly and unknowingly spend cycles doing nothing, and movement to seek
and destroy enemy warriors is still encouraged by the limits.  The main
disadvantage is that limits which are not factors of the size of core lead
to unexpected results.  Example: a reference to address location -1 is
adjusted to M-1 when loaded into core and will not fold to R-1 and/or W-1
if R or W are not factors of M (M is size of core, R is the read limit, and
W is the write limit).  Of course, if R = W = M, then play is equivalent
to ICWS'88 without limits.


In the 5.MARS section of the draft, many of the terms such as A-operand
were used both as containers ("Writes to the A-operand") and the contents
of those containers ("Compare the A-operand to ...").  Such ambiguous terms
and references have hopefully been eradicated.

Although such eradication eliminates ambiguity, it encourages obfuscation
and/or the proliferation of terms.  A delicate balance has, perhaps, been
struck between the two.

The following are terms which are new or may be used differently than in
the past.  All terms are contents (not containers).

opcode modifier : Removes mode-specific behaviour from opcodes by
        explicitly stating whether an instruction uses just one number,
        two numbers, or a whole instruction.
A-number : Replaces A-field/A-value/A-term, etc.  A general term, not tied
        to any specific instruction.
B-number : Replaces B-field/B-value/B-term, etc.  A general term, not tied
        to any specific instruction.
current instruction : Specifically means the instruction in the instruction
        register.  Does NOT mean the instruction in core pointed to by the
        program counter.  (That instruction may have changed since the
        current instruction was copied from there).
A-instruction : Specifically means the copy of the instruction in core (at
        the time of A-operand evaluation) pointed to by the A-number.
B-instruction : Specifically means the copy of the instruction in core (at
        the time of B-operand evaluation) pointed to by the B-number.
A-value : Now refers to the object(s) (A/B-number(s) of the A-instruction
        or the A-instruction) referenced by the A-operand (as selected by
        the opcode modifier).
B-value : Now refers to the object(s) (A/B-number(s) of the B-instruction
        or the B-instruction) referenced by the B-operand (as selected by
        the opcode modifier).
B-target: The object(s) (A/B-number(s) of the instruction in core [at the
        time of opcode execution] or the instruction) pointed to by the
        B-number.


Six opcode modifiers have been added to the Draft.  Modifiers are appended
to the opcodes with a dot.  Example: "MOV.A".  The modifiers are:

.A      Instructions use and write A-numbers.
.B      Instructions use and write B-numbers.
.AB     Instructions use the A-numbers of the A-instructions and the
                B-numbers of the B-instructions and write B-numbers.
.BA     Instructions use the B-numbers of the A-instructions and the
                A-numbers of the B-instructions and write A-numbers.
.F      Instructions use both the A-numbers and the B-numbers, using and
                writing A-to-A, B-to-B.
.X      Instructions use both the A-numbers and the B-numbers, using and
                writing A-to-B, B-to-A.
.I      Instructions use and write entire instructions.

See Section 5.4 for more information (especially the examples).

There could be modifiers (other than .I) which take the modes into account,
but their utility may not warrant their inclusion.

The advantages of opcode modifiers include: greatly expanding the function
of opcodes without greatly expanding the number of opcodes, separating
opcode evaluation from operand evaluation (i.e. the behaviours of the
opcodes no longer depend on the modes), rendering moot questions about
whether ADD, SUB, etc. should use one or two fields (and if one field,
whether to use the A-field or the B-field), adding versatility to the order
of task splitting, and providing a "Skip if greater than" equivalent to
SLT.

In addition, backwards compatibility with ICWS'88 (and even ICWS'86) is
easily accomplished at the assembly level.  Any instructions with opcodes
without modifiers would be translated to the appropriate opcode.modifier
pair.  Examples:

"MOV #a, B", which only moves the A-field of the current instruction to the
B-field of the instruction pointed to by B, would be translated to
"MOV.AB #a, B".  Similarly, "MOV a, b", which moves an entire instruction
from A to B, becomes "MOV.I a, b".  Instructions which were previously
impossible, such as moving a B-field to an A-field, are now very
simple and intuitive with "MOV.BA A, B".  Another example,
"MOV.X target, target" takes the place of "XCH target", exchanging fields.
Finally, "ADD a, b" would translate to "ADD.F a, b" for ICWS'88 and
"ADD.B a, b" for ICWS'86.

There is one negative to one opcode modifier.  ".I" only really makes sense
for MOV and CMP.  It would be possible to define results for arithmetic
manipulation and ordinal comparison of opcodes and modes, but it would be
very artificial.  As an alternative, .I falls back to .F functionality (for
opcodes other than MOV and CMP) in this document.


Things which absolutely must be done before final consideration for
adoption by the ICWS:

        1. Complete incomplete sections or remove references to them
        2. Add typographic distinctions to grammars

To aid in completion of the draft, all suggested revisions of the draft
should consist of explicit remarks such as:

        Delete lines xxxx to yyyy
        Add the following after line zzzz ....
        Replace lines vvvv to wwww with ....

Please individually explain why each revision is necessary.


The maximal verbosity of the draft is intentional.  Each sentence either
presents a new item, a clarification of an item, or an old item in a new
context.  The goal is that no two reasonable people could arrive at
two different interpretations of the draft.

\start numbering
0001 Draft of Proposed 1994 Core War Standard

0002 Version 3.3
0003 Draft Last Modified: November 8, 1995
0004 Last modified by: Damien Doligez
0005 Base draft by: Mark Durham


0006 i. Contents

0007         1. Introduction
0008                 1. Purpose
0009                 2. Overview
0010                 3. Acknowledgements
0011         2. Redcode Assembly File Format
0012                 1. Purpose
0013                 2. Description
0014                 3. Grammar
0015                 4. Assembly To Object Code Conversion
0016                 5. Pseudo-instructions
0017                 6. Comment Conventions
0018                 7. Example Assembly File
0019         3. Load File Format
0020                 1. Purpose
0021                 2. Description
0022                 3. Grammar
0023                 4. Comment Conventions
0024                 5. Example Load File
0025         4. Run-time Variables
0026                 1. Purpose
0027                 2. Predefined Labels
0028                 3. Variables
0029                 4. Standard Variable Sets
0030         5. MARS
0031                 1. Purpose
0032                 2. Description
0033                 3. Address Modes
0034                         1. Immediate
0035                         2. Direct
0036                         3. A-number Indirect
0037                         4. B-number Indirect
0038                         5. A-number Predecrement Indirect
0039                         6. B-number Predecrement Indirect
0040                         7. A-number Postincrement Indirect
0041                         8. B-number Postincrement Indirect
0042                 4. Modifiers
0043                         1. A
0044                         2. B
0045                         3. AB
0046                         4. BA
0047                         5. F
0048                         6. X
0049                         7. I
0050                 5. Instruction Set
0051                          1. DAT
0052                          2. MOV
0053                          3. ADD
0054                          4. SUB
0055                          5. MUL
0056                          6. DIV
0057                          7. MOD
0058                          8. JMP
0059                          9. JMZ
0060                         10. JMN
0061                         11. DJN
0062                         12. SEQ and CMP
0063                         13. SNE
0064                         14. SLT
0065                         15. SPL
0066                         16. NOP
0067                 6. Example MARS interpreter
0068         6. Validation Suite
0069                 1. Purpose and Requirements
0070                 2. Tests
0071                         1. Assembly to Load File Test
0072                         2. MARS Tests
0073                                  1. DAT Tests
0074                                  2. MOV Tests
0075                                  3. ADD Tests
0076                                  4. SUB Tests
0077                                  5. MUL Tests
0078                                  6. DIV Tests
0079                                  7. MOD Tests
0080                                  8. JMP Tests
0081                                  9. JMZ Tests
0082                                 10. JMN Tests
0083                                 11. DJN Tests
0084                                 12. SEQ/CMP Tests
0085                                 13. SNE Tests
0086                                 14. SLT Tests
0087                                 15. SPL Tests
0088                                 16. NOP Tests
0089         7. Glossary and Index

0090         A. Differences Between Standards
0091                 1. Purpose
0092                 2. Changes
0093                         1. Assembly Files
0094                                 1. ICWS'88 conversion
0095                                 2. ICWS'86 conversion
0096                         2. Load Files
0097                         3. MARS


0098 1. Introduction

0099 1.1 Purpose
0100 This standard seeks to fully define and describe the game of Core War.

0101 1.2 Overview
0102 Core War is a game in which programs compete for control of a computer
0103 called MARS (for Memory Array Redcode Simulator).  Redcode is the name
0104 of the assembly language in which Core War programs, called warriors,
0105 are written.

0106 In order to play Core Wars, access to a Core War system is required.
0107 A Core War system at a minimum must have a MARS executive function
0108 (interpreter) and a way to load warriors into core (the MARS memory).
0109 Most systems include a Redcode assembler, either separately or as part
0110 of the loader.  Also, many systems include a graphical interface and
0111 code debugging features.  Some systems have the ability to run
0112 automated tournaments.

0113 1.3 Acknowledgements
0114 This document is the fourth standard for Core War, the first three
0115 being "Core War Guidelines" (March 1984) by D. G. Jones and
0116 A. K. Dewdney, the International Core War Society standard of 1986 -
0117 "Core Wars" (May 1986), principally authored by Graeme McRae and the
0118 "Core Wars Standard of 1988" (Summer 1988), principally authored by
0119 Thomas Gettys.  The latter two standards are often referred to as
0120 ICWS'86 and ICWS'88, respectively.

0121 People who contributed to this document (in alphabetical order):
0122         Scott W. Adkins
0123         Mark A. Durham
0124         Anders Ivner
0125         Morten Due Joergensen
0126         Paul Kline
0127         Scott Nelson
0128         Jon Newman
0129         John Perry
0130         Andy Pierce
0131         Planar
0132         Wayne Sheppard
0133         William Shubert
0134         Nandor Sieben
0135         Stefan Strack
0136         Mintardjo Wangsaw
0137         Kevin Whyte


0138 2. Redcode Assembly File Format

0139 2.1 Purpose
0140 A Redcode assembly file consists of the information necessary for a
0141 Redcode assembler to produce a load file.  A standard assembly file
0142 format allows programmers to exchange warriors in a more meaningful
0143 format than load files.  An assembly file, through the use of labels,
0144 arithmetic expressions, and macros can also greatly reduce the work
0145 necessary to produce a particular warrior while enhancing code
0146 readability.

0147 2.2 Description
0148 Each Redcode warrior consists of one or more lines of Redcode.  Each
0149 line of Redcode consists of a string of alphanumerals and special
0150 characters.  Special characters in Redcode are the addressing mode
0151 indicators for immediate '#', direct '$', A-number indirect '*',
0152 B-number indirect '@', A-number predecrement indirect '{', B-number
0153 predecrement indirect '<', A-number postincrement indirect '}', and
0154 B-number postincrement indirect '>' modes, the field separator
0155 (comma) ',', the comment indicator (semicolon) ';', the arithmetic
0156 operators for addition '+', subtraction '-', multiplication '*',
0157 division '/', and  modulus '%', and opening '(' and closing ')'
0158 parentheses for precedence grouping.

0159 A line may be blank or consist of an instruction, a
0160 pseudo-instruction, a comment, or an instruction or
0161 pseudo-instruction followed by a comment.  Each line is terminated
0162 with a newline.  All comments begin with a semicolon.  Each
0163 instruction consists of these elements in the following order: a
0164 label, an opcode, an A-operand, a comma, and a B-operand.  Each
0165 element may be preceded and/or followed by whitespace (newline is
0166 not considered whitespace).  The label is optional.  If either
0167 operand is blank, the comma may be omitted.  The operands may not
0168 be both blank.

0169 Pseudo-instructions appear just like instructions but are directives
0170 to the assembler and do not result in object code as an instruction
0171 would.  Each pseudo-instruction has a pseudo-opcode which appears
0172 where an opcode would appear in an instruction.  The format of the
0173 remainder of the pseudo-instruction depends on which pseudo-opcode is
0174 used.  For the remainder of this section (2.2) and the next (2.3),
0175 references to "opcode" include "pseudo-opcode" assembler directives.

0176 A label is any alphanumeric string other than those reserved for
0177 opcodes.  Labels are case sensitive, i.e. "start" is different from
0178 "Start".  An opcode is any of the following: DAT, MOV, ADD, SUB, MUL,
0179 DIV, MOD, JMP, JMZ, JMN, DJN, CMP, SEQ, SNE, SLT, SPL, and NOP.
0180 Opcodes may be in upper or lower case or any combination.  An opcode
0181 may be followed by a modifier.  A modifier always begins with a dot.
0182 A modifier is any of the following: .A, .B, .AB, .BA, .F, .X, or .I.
0183 Modifiers may be in upper or lower case or any combination.

0184 Each operand is blank, contains an address, or contains an addressing
0185 mode indicator and an address.  An address consists of any number of
0186 labels and numbers separated by arithmetic operators and possibly
0187 grouped with parentheses.  All elements of an address may be separated
0188 by whitespace.

0189 2.3 Grammar
0190 Tokens are separated by whitespace (space and tab) exclusive of
0191 newline characters, which are used for line termination.  End-of-file
0192 should occur only where newline could logically occur, otherwise the
0193 assembly file is invalid.

0194 In the following, 'e' is the "empty" element, meaning the token may be
0195 omitted, a caret '^' means NOT, an asterisk '*' immediately adjacent
0196 means zero or more occurrences of the previous token, and a plus '+'
0197 immediately adjacent means one or more occurrences of the previous
0198 token.  The vertical bar '|' means OR.

0199         assembly_file:
0200                 line+ EOF
0201         line:
0202                 comment | instruction
0203         comment:
0204                 ; v* newline | newline
0205         instruction:
0206                 label_list operation mode expr comment |
0207                 label_list operation mode expr , mode expr comment
0208         label_list:
0209                 label newline* label_list | e
0210         label:
0211                 alpha alphanumeral*
0212         operation:
0213                 opcode | opcode.modifier
0214         opcode:
0215                 DAT | MOV | ADD | SUB | MUL | DIV | MOD |
0216                 JMP | JMZ | JMN | DJN | CMP | SEQ | SNE |
0217                 SLT | SPL | NOP | ORG | EQU | END
0218         modifier:
0219                 A | B | AB | BA | F | X | I
0220         mode:
0221                 # | $ | * | @ | { | < | } | > | e
0222         expr:
0223                 term |
0224                 term + expr | term - expr |
0225                 term * expr | term / expr |
0226                 term % expr
0227         term:
0228                 label | number | ( expression )
0229         number:
0230                 whole_number | signed_integer
0231         signed_integer:
0232                 +whole_number | -whole_number
0233         whole_number:
0234                 numeral+
0235         alpha:
0236                 A-Z | a-z | _
0237         numeral:
0238                 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
0239         alphanumeral:
0240                 alpha | numeral
0241         v:
0242                 ^newline
0243         newline:
0244                 LF | CR | LF CR | CR LF
0245         e:


0246 2.4 Assembly To Load File Conversion
0247 A Redcode program can be assembled into a list of MARS instructions.
0248 (When assembled to a file instead of directly to core, the list is
0249 called a load file.  See Section 3).  Each Redcode instruction
0250 assembles into a MARS instruction of five fields: an opcode.modifier
0251 field, the A-mode field, the A-address field, the B-mode field, and
0252 the B-address field.  A missing (null or blank) mode assembles as '$'
0253 does.

0254 If no modifier is present in the assembly instruction, the appropriate
0255 modifier is appended to the opcode.  The appropriate modifier depends
0256 upon the opcode, the modes, and which standard (ICWS'86 or ICWS'88) to
0257 consider (ICWS'88 by default).  See Appendix A for the appropriate
0258 translations.

0259 The address field values are derived from the numbers, labels, and
0260 arithmetic operators contained in the addresses.  Labels are
0261 converted to an address relative to the current instruction.  Then
0262 the arithmetic operations are carried out according to the
0263 appropriate operator and parenthetical precedence to determine the
0264 final value.  If there is only one operand associated with a DAT
0265 instruction, this operand is assembled into the B-mode and B-address
0266 fields, while #0 is assembled into the A-mode and A-address fields.
0267 For all other instructions with only one operand, this operand is
0268 assembled into the A-mode and A-address fields and #0 is assembled
0269 into the B-mode and B-address fields.

0270 2.5 Pseudo-instructions
0271 Pseudo-opcodes are "ORG", "EQU", and "END".

0272 "ORG" ("ORiGin") is a way for the assembly file to indicate the
0273 logical origin of the warrior.  The A-operand contains an offset to
0274 the logical first instruction.  Thus "ORG 0" means execution should
0275 start with the first instruction (the default) whereas "ORG 6" means
0276 execution should start with the seventh instruction. Although multiple
0277 ORG instructions are of no additional benefit to the programmer, they
0278 are allowed. When there is more than one ORG instruction in a file,
0279 the last ORG instruction encountered will be the one that takes
0280 effect.

0281 "EQU" ("EQUate") is a simple text substitution utility.  Instructions
0282 of the form "label EQU text" will replace all occurrences of "label"
0283 with the (probably longer and more complicated) "text" before any
0284 actual assembly takes place on the file.  Some labels are predefined
0285 with the value of run-time variables as if they were defined with
0286 EQU at the start of the program (see section 4.2 for the list of
0287 predefined labels).

0288 "END" indicates the logical end of the assembly file.  If END has an
0289 A-operand, then the A-operand indicates the logical origin of the
0290 warrior in the same manner as ORG does.  The rest of the file (after
0291 the end of the line containing END) is ignored.


0292 2.6 Comment Conventions
0293 ";redcode<switch>" as a first line identifies the file as a Redcode
0294 assembly file.  The "<switch>" is optional and implementation
0295 dependent.

0296 ";strategy <text>" indicates a comment for "public" consumption.

0297 ";name <program name>", ";author <name of author(s)>",
0298 ";version <version number>", and ";date <date of last revision>"
0299 offer uniform ways of presenting this information.

0300 ";kill <program name>" is for removing warriors from ongoing
0301 tournaments.  If no <program name> is supplied, all of the author's
0302 previous submissions will be removed.

0303 ";assert <expression>" will evaluate the expression and trigger
0304 an error if it is 0.  In conjunction with predefined labels (see
0305 section 4.2), this provides a way of specifying the conditions under
0306 which a warrior is supposed to run.


0307 2.7 Example Assembly File

0308 ;redcode

0309 ;name          Dwarf
0310 ;author        A. K. Dewdney
0311 ;version       94.1
0312 ;date          April 29, 1993

0313 ;strategy      Bombs every fourth instruction.
0314 ;assert        CORESIZE % 4 == 0

0315         ORG     start              ; Indicates the instruction with
0316                                    ; the label "start" should be the
0317                                    ; first to execute.

0318 step    EQU      4                 ; Replaces all occurrences of "step"
0319                                    ; with the character "4".

0320 target  DAT.F   #0,     #0         ; Pointer to target instruction.
0321 start   ADD.AB  #step,   target    ; Increments pointer by step.
0322         MOV.AB  #0,     @target    ; Bombs target instruction.
0323         JMP.A    start             ; Same as JMP.A -2.  Loops back to
0324                                    ; the instruction labelled "start".
0325         END


0326 3. Load File Format

0327 3.1 Purpose
0328 A load file represents the minimum amount of information necessary for
0329 a warrior to execute properly and is presented in a very simple format
0330 which is a subset of the assembly file format presented in Section 2.
0331 A standard load file format allows programmers to choose assemblers
0332 and MARS programs separately and to verify assembler performance and
0333 MARS performance separately.  Not all Core War systems will necessarily
0334 write load files (for example, those which assemble directly to core),
0335 but all systems should support reading load files.

0336 3.2 Description

0337 Each load file will consist of one or more lines of MARS
0338 instructions or comments.  Each line is terminated with a newline.
0339 All comments start with with a semicolon.  Each MARS instruction
0340 consists of five fields: an opcode.modifier pair, an A-mode, an
0341 A-field, a B-mode, and a B-field.  The A-mode is separated from the
0342 opcode.modifier pair by whitespace and the B-mode is separated from
0343 the A-field by a comma and additional whitespace.  Each MARS
0344 instruction may be followed by extraneous information, which is
0345 ignored.  Note that the instruction format for load files is more
0346 rigid than for assembly files to simplify parsing. No blank modes or
0347 operands are allowed.


0348 3.3 Grammar
0349 Tokens are separated by whitespace (non-marking characters such as
0350 SPACE and TAB) exclusive of newline characters, which are used for
0351 line termination.  End-of-file should occur only where newline could
0352 logically occur, otherwise the load file is invalid.

0353         load_file:
0354                 line+ EOF
0355         line:
0356                 comment | instruction
0357         comment:
0358                 ; v* newline | newline
0359         instruction:
0360                 opcode.modifier mode number , mode number comment
0361         opcode:
0362                 DAT | MOV | ADD | SUB | MUL | DIV | MOD |
0363                 JMP | JMZ | JMN | DJN | CMP | SEQ | SNE |
0364                 SLT | SPL | NOP | ORG
0365         modifier:
0366                 A | B | AB | BA | F | X | I
0367         mode:
0368                 # | $ | @ | * | < | { | > | }
0369         number:
0370                 whole_number | signed_integer
0371         signed_integer:
0372                 +whole_number | -whole_number
0373         whole_number:
0374                 numeral+
0375         numeral:
0376                 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
0377         v:
0378                 ^newline
0379         newline:
0380            LF | CR | LF CR | CR LF


0381 3.4 Comment Conventions
0382 Comment conventions for load files are the same as for assembly files.
0383 Of particular note are the "; name <program name>" and "; author
0384 <author(s)>" comments.  These comments provide a more suitable
0385 identification of programs to the MARS than "Warrior #1", "Warrior #2",
0386 etc.  It also allows for less cryptic identification than by filename.


0387 3.5 Example Load File
0388 ;redcode

0389 ;name          Dwarf
0390 ;author        A. K. Dewdney
0391 ;version       94.1
0392 ;date          April 29, 1993

0393 ;strategy      Bombs every fourth instruction.
0394 ;assert        CORESIZE % 4 == 0

0395 ORG     1          ; Indicates execution begins with the second
0396                    ; instruction (ORG is not actually loaded, and is
0397                    ; therefore not counted as an instruction).

0398 DAT.F   #0, #0     ; Pointer to target instruction.
0399 ADD.AB  #4, $-1    ; Increments pointer by step.
0400 MOV.AB  #0, @-2    ; Bombs target instruction.
0401 JMP.A   $-2, #0    ; Loops back two instructions.


0402 4. Run-time Variables

0403 4.1 Purpose
0404 This section describes those variables which are determined just prior
0405 to running a battle by the person running the battle.  It also
0406 enumerates some of the standardized sets of variables used for
0407 tournaments.

0408 4.2 Predefined Labels
0409 Most of the run-time variables are available to the programmer as
0410 predefined labels.  The purpose of these labels is twofold: first,
0411 to parameterize the warriors with the characteristics of their
0412 run-time environment; second, to check (with the ";assert" comment)
0413 that the warrior is run in an environment that makes sense for it.

0414 The next section gives a list of the run-time variables.  When
0415 a predefined label takes the value of the variable, the label is
0416 given between parentheses after the name of the variable.

0417 4.2 Variables
0418 Run-time variables consist of the following:

0419 Core Size: (CORESIZE)
0420         Core size is the number of instructions which make up core
0421         during the battle.

0422 Cycles Before Tie: (MAXCYCLES)
0423         In each cycle, one instruction from each warrior is executed.
0424         This variable determines how many cycles without a winner
0425         should be executed before declaring a tie.

0426 Initial Instruction:
0427         The initial instruction is that instruction which is preloaded
0428         into core prior to loading warriors.  In addition to loading
0429         an instruction such as "DAT #0, #0" into all of core, the
0430         initial instruction could be set to "NONE", meaning core should
0431         not be cleared between battles, or "RANDOM", meaning core
0432         instructions are filled with randomly generated instructions.

0433 Instruction Limit: (MAXLENGTH)
0434         The maximum number of instructions allowed per load file.

0435 Maximum Number of Tasks: (MAXPROCESSES)
0436         Each warrior can spawn multiple additional tasks.  This
0437         variable sets the maximum number of tasks allowed per warrior.
0438         In other words, this is the size of each warrior's task queue.

0439 Minimum Separation: (MINDISTANCE)
0440         The minimum number of instructions from the first instruction
0441         of one warrior to the first instruction of the next warrior.

0442 Read Distance:
0443         This is the range available for warriors to read information
0444         from core.  Attempts to read outside the limits of this range
0445         result in reading within the local readable range.  The range
0446         is centered on the current instruction.  Thus, a range of
0447         500 limits reading to offsets of (-249 -> +250) from the
0448         currently executing instruction.  The read limit can therefore
0449         be considered a mini-core within core.  An attempt to read
0450         location PC+251 reads location PC-249 instead.  An attempt to
0451         read location PC+500 reads location PC instead.

0452         Read distance must be a factor of core size, otherwise the
0453         above defined behaviour is not guaranteed.

0454 Separation:
0455         The number of instructions from the first instruction of one
0456         warrior to the first instruction of the next warrior.
0457         Separation can be set to "RANDOM", meaning separations will be
0458         chosen randomly from those larger than the minimum separation.

0459 Warriors:
0460         The initial number of warriors to battle simultaneously in
0461         core.

0462 Write Distance:
0463         This is the range available for warriors to write information
0464         to core.  Attempts to write outside the limits of this range
0465         result in writing within the local writable range.  The range
0466         is centered on the current instruction.  Thus, a range of 500
0467         limits writing to offsets of (-249 -> +250) from the
0468         currently executing instruction.  The write limit can
0469         therefore be considered a mini-core within core.  An attempt
0470         to write location PC+251 writes to location PC-249 instead.
0471         An attempt to write to location PC+500 writes to location PC
0472         instead.

0473         Write distance must be a factor of core size, otherwise the
0474         above defined behaviour is not guaranteed.


0475 4.3 Standard Variable Sets
0476 ICWS86:
0477         Core Size:                      8192
0478         Cycles Before Tie:              100000
0479         Initial Instruction:            DAT.F #0, #0
0480         Instruction Limit:              300
0481         Maximum Number of Tasks:        64
0482         Minimum Separation:             300
0483         Read Distance:                  8192
0484         Separation:                     RANDOM
0485         Warriors:                       2
0486         Write Distance:                 8192

0487 KOTH:
0488         Core Size:                      8000
0489         Cycles Before Tie:              80000
0490         Initial Instruction:            DAT.F $0, $0
0491         Instruction Limit:              100
0492         Maximum Number of Tasks:        8000
0493         Minimum Separation:             100
0494         Read Distance:                  8000
0495         Separation:                     RANDOM
0496         Warriors:                       2
0497         Write Distance:                 8000


0498 5. MARS

0499 5.1 Purpose
0500 The Memory Array Redcode Simulator (MARS) is the computer in which
0501 Core War warriors do combat.

0502 5.2 Description
0503 A minimally-complete MARS consists of a core, a loader, task queues,
0504 the MARS executive function, and a way to present the final results of
0505 a battle.  Additionally, many MARS provide a "real-time" battle
0506 display and various debugging tools.

0507 The core consists of a cyclic list (0, 1, 2, ..., M-2, M-1, 0, 1, ...)
0508 of M MARS instructions.  The integer M is referred to as "core size".
0509 All operations are performed modulo M.  Core initialization (the
0510 initial instructions placed in core before loading warriors) is a
0511 run-time variable (see Section 4).

0512 The loader loads warriors into core, converting each negative field
0513 value N to the positive field value P such that 0 <= P < M and P = kM
0514 + N where k is a positive integer (P = N modulo M).  Each field value
0515 G greater than or equal to M is converted to the field values L such
0516 that 0 <= L < M and L = kM + G where k is a negative integer (L = G
0517 modulo M).  The loader also initializes each warrior's task queue with
0518 the appropriate task pointer.

0519 There is a task queue for each warrior loaded into core.  Each task
0520 queue can hold a limited number of task pointers.  The "task limit"
0521 (number of tasks an individual warrior's task queue can hold) is a
0522 run-time variable.  The task queues are FIFOs (First In, First Out).

0523 Each warrior consists of one task initially.  Subsequent tasks are
0524 added to the warrior's task queue using the SPL instruction. Attempted
0525 execution of a DAT instruction by a task effectively removes that task
0526 from the warrior's task queue.

0527 Warriors execute for a specified number of cycles ("time limit", see
0528 Section 4) or until only one warrior is still executing, whichever
0529 occurs first.  Each cycle, one instruction from each warrior is
0530 executed.  The instruction to execute is the instruction pointed to by
0531 the next task pointer in the warrior's task queue.  A warrior is no
0532 longer executing when its task queue is empty.

0533 The following expressions are used in describing the MARS executive
0534 function's operation.

0535 General Definitions:
0536    An instruction consists of an opcode, a modifier, an A-operand,
0537            and a B-operand.
0538    An A-operand consists of an A-mode and an A-number.
0539    An A-mode is the addressing mode of an A-operand.
0540    An A-number is an integer between 0 and M-1, inclusive.
0541    A B-operand consists of a B-mode and a B-number.
0542    A B-mode is the addressing mode of a B-operand.
0543    A B-number is an integer between 0 and M-1, inclusive.

0544 Specific Definitions:
0545    The program counter (PC) is the pointer to the location in core of
0546            the instruction fetched from core to execute.
0547    The current instruction is the instruction in the instruction
0548            register, as copied (prior to execution) from the PC
0549            location of core.
0550    The A-pointer points to the instruction the A-operand of the
0551            current instruction references in core.
0552    The A-instruction is a copy of the instruction the A-pointer
0553            points to in core (as it was during operand evaluation).
0554    The A-value is the A-number and/or the B-number of the
0555            A-instruction or the A-instruction itself, whichever are/is
0556            selected by the opcode modifier.
0557    The B-pointer points to the instruction the B-operand of the
0558            current instruction references in core.
0559    The B-instruction is a copy of the instruction the B-pointer
0560            points to in core (as it was during operand evaluation).
0561    The B-value is the A-number and/or the B-number of the
0562            B-instruction or the B-instruction itself, whichever are/is
0563            selected by the opcode modifier.
0564    The B-target is the A-number and/or the B-number of the instruction
0565            pointed to by the B-pointer or the instruction itself,
0566            whichever are/is selected by the opcode modifier.

0567 All MARS instructions are executed following the same procedure:
0568 1. The currently executing warrior's current task pointer is
0569    extracted from the warrior's task queue and assigned to the
0570    program counter.
0571 2. The corresponding instruction is fetched from core and stored in
0572    the instruction register as the current instruction.
0573 3. The A-operand of the current instruction is evaluated.
0574 4. The results of A-operand evaluation, the A-pointer and the
0575    A-instruction, are stored in the appropriate registers.
0576 5. The B-operand of the current instruction is evaluated.
0577 6. The results of B-operand evaluation, the B-pointer and the
0578    B-instruction, are stored in the appropriate registers.
0579 7. Operations appropriate to the opcode.modifier pair in the
0580    instruction register are executed.  With the exception of DAT
0581    instructions, all operations queue an updated task pointer.
0582    (How the task pointer is updated and when it is queued depend on
0583    instruction execution).

0584 All pointers are PC-relative, indicating the offset from the source of
0585 the current instruction to the desired location.  All arithmetic is to
0586 be done modulo M, with negative values converted in the same manner as
0587 during loading as discussed above (P = M + N).  Additionally, all
0588 reads of core are done modulo the read limit (R) and all writes of
0589 core are done modulo the write limit (W).  Read offsets O greater than
0590 R/2 from the current instruction are converted to backwards offsets of
0591 O = O - R.  A comparable conversion occurs for write offsets greater
0592 than W/2.


0593 5.3 Address Modes

0594 5.3.1 Immediate
0595 An immediate mode operand merely serves as storage for data.  An
0596 immediate A/B-mode in the current instruction sets the A/B-pointer to
0597 zero.

0598 5.3.2 Direct
0599 A direct mode operand indicates the offset from the program counter.
0600 A direct A/B-mode in the current instruction means the A/B-pointer is
0601 a copy of the offset, the A/B-number of the current instruction.

0602 5.3.3 A-number Indirect
0603 An A-number indirect mode operand indicates the primary offset
0604 (relative to the program counter) to the secondary offset (relative to
0605 the location of the instruction in which the secondary offset is
0606 contained).  An A-number indirect A/B-mode indicates that the
0607 A/B-pointer is the sum of the A/B-number of the current instruction
0608 (the primary offset) and the A-number of the instruction pointed to by
0609 the A/B-number of the current instruction (the secondary offset).

0610 5.3.4 B-number Indirect
0611 A B-number indirect mode operand indicates the primary offset
0612 (relative to the program counter) to the secondary offset (relative to
0613 the location of the instruction in which the secondary offset is
0614 contained).  A B-number indirect A/B-mode indicates that the
0615 A/B-pointer is the sum of the A/B-number of the current instruction
0616 (the primary offset) and the B-number of the instruction pointed to by
0617 the A/B-number of the current instruction (the secondary offset).

0618 5.3.5 A-number Predecrement Indirect
0619 An A-number predecrement indirect mode operand indicates the primary
0620 offset (relative to the program counter) to the secondary offset
0621 (relative to the location of the instruction in which the secondary
0622 offset is contained) which is decremented prior to use.  An A-number
0623 predecrement indirect A/B-mode indicates that the A/B-pointer is the
0624 sum of the A/B-number of the current instruction (the primary offset)
0625 and the decremented A-number of the instruction pointed to by the
0626 A/B-number of the current instruction (the secondary offset).

0627 5.3.6 B-number Predecrement Indirect
0628 A B-number predecrement indirect mode operand indicates the primary
0629 offset (relative to the program counter) to the secondary offset
0630 (relative to the location of the instruction in which the secondary
0631 offset is contained) which is decremented prior to use.  A B-number
0632 predecrement indirect A/B-mode indicates that the A/B-pointer is the
0633 sum of the A/B-number of the current instruction (the primary offset)
0634 and the decremented B-number of the instruction pointed to by the
0635 A/B-number of the current instruction (the secondary offset).

0636 5.3.7 A-number Postincrement Indirect
0637 An A-number postincrement indirect mode operand indicates the primary
0638 offset (relative to the program counter) to the secondary offset
0639 (relative to the location of the instruction in which the secondary
0640 offset is contained) which is incremented after the results of the
0641 operand evaluation are stored.  An A-number postincrement indirect
0642 A/B-mode indicates that the A/B-pointer is the sum of the A/B-number of
0643 the current instruction (the primary offset) and the A-number of the
0644 instruction pointed to by the A/B-number of the current instruction
0645 (the secondary offset).  The A-number of the instruction pointed to by
0646 the A/B-number of the current instruction is incremented after the
0647 A/B-instruction is stored, but before the B-operand is evaluated (for
0648 A-number postincrement indirect A-mode), or the operation is executed
0649 (for A-number postincrement indirect B-mode).

0650 5.3.8 B-number Postincrement Indirect
0651 A B-number postincrement indirect mode operand indicates the primary
0652 offset (relative to the program counter) to the secondary offset
0653 (relative to the location of the instruction in which the secondary
0654 offset is contained) which is incremented after the results of the
0655 operand evaluation are stored.  A B-number postincrement indirect
0656 A/B-mode indicates that the A/B-pointer is the sum of the A/B-number of
0657 the current instruction (the primary offset) and the B-number of the
0658 instruction pointed to by the A/B-number of the current instruction
0659 (the secondary offset).  The B-number of the instruction pointed to by
0660 the A/B-number of the current instruction is incremented after the
0661 A/B-instruction is stored, but before the B-operand is evaluated (for
0662 B-number postincrement indirect A-mode), or the operation is executed
0663 (for B-number postincrement indirect B-mode).


0664 5.4 Modifiers

0665 5.4.1 A
0666 Instruction execution proceeds with the A-value set to the A-number of
0667 the A-instruction and the B-value set to the A-number of the
0668 B-instruction.  A write to core replaces the A-number of the
0669 instruction pointed to by the B-pointer.

0670 For example, a CMP.A instruction would compare the A-number of the
0671 A-instruction with the A-number of the B-instruction.  A MOV.A
0672 instruction would replace the A-number of the instruction pointed to
0673 by the B-pointer with the A-number of the A-instruction.

0674 5.4.2 B
0675 Instruction execution proceeds with the A-value set to the B-number of
0676 the A-instruction and the B-value set to the B-number of the
0677 B-instruction.  A write to core replaces the B-number of the
0678 instruction pointed to by the B-pointer.

0679 For example, a CMP.B instruction would compare the B-number of the
0680 A-instruction with the B-number of the B-instruction.  A MOV.B
0681 instruction would replace the B-number of the instruction pointed to
0682 by the B-pointer with the B-number of the A-instruction.

0683 5.4.3 AB
0684 Instruction execution proceeds with the A-value set to the A-number of
0685 the A-instruction and the B-value set to the B-number of the
0686 B-instruction.  A write to core replaces the B-number of the
0687 instruction pointed to by the B-pointer.

0688 For example, a CMP.AB instruction would compare the A-number of the
0689 A-instruction with the B-number of the B-instruction.  A MOV.AB
0690 instruction would replace the B-number of the instruction pointed to
0691 by the B-pointer with the A-number of the A-instruction.

0692 5.4.4 BA
0693 Instruction execution proceeds with the A-value set to the B-number of
0694 the A-instruction and the B-value set to the A-number of the
0695 B-instruction.  A write to core replaces the A-number of the
0696 instruction pointed to by the B-pointer.

0697 For example, a CMP.BA instruction would compare the B-number of the
0698 A-instruction with the A-number of the B-instruction.  A MOV.BA
0699 instruction would replace the A-number of the instruction pointed to
0700 by the B-pointer with the B-number of the A-instruction.

0701 5.4.5 F
0702 Instruction execution proceeds with the A-value set to both the
0703 A-number and B-number of the A-instruction (in that order) and the
0704 B-value set to both the A-number and B-number of the B-instruction
0705 (also in that order).  A write to core replaces both the A-number and
0706 the B-number of the instruction pointed to by the B-pointer (in that
0707 order).

0708 For example, a CMP.F instruction would compare the A-number of the
0709 A-instruction to the A-number of the B-instruction and the B-number of
0710 the A-instruction to B-number of the B-instruction.  A MOV.F
0711 instruction would replace the A-number of the instruction pointed to by
0712 the B-pointer with the A-number of the A-instruction and would also
0713 replace the B-number of the instruction pointed to by the B-pointer
0714 with the B-number of the A-instruction.

0715 5.4.6 X
0716 Instruction execution proceeds with the A-value set to both the
0717 A-number and B-number of the A-instruction (in that order) and the
0718 B-value set to both the B-number and A-number of the B-instruction
0719 (in that order).  A write to to core replaces both the B-number and
0720 the A-number of the instruction pointed to by the B-pointer (in that
0721 order).

0722 For example, a CMP.X instruction would compare the A-number of the
0723 A-instruction to the B-number of the B-instruction and the B-number of the
0724 A-instruction to A-number of the B-instruction.  A MOV.X instruction
0725 would replace the B-number of the instruction pointed to by the
0726 B-pointer with the A-number of the A-instruction and would also replace
0727 the A-number of the instruction pointed to by the B-pointer with the
0728 B-number of the A-instruction.

0729 5.4.7 I
0730 Instruction execution proceeds with the A-value set to the
0731 A-instruction and the B-value set to the B-instruction.  A write to
0732 core replaces the entire instruction pointed to by the B-pointer.

0733 For example, a CMP.I instruction would compare the A-instruction to
0734 the B-instruction.  A MOV.I instruction would replace the instruction
0735 pointed to by the B-pointer with the A-instruction.


0736 5.5 Instruction Set

0737 5.5.1 DAT
0738 No additional processing takes place.  This effectively removes the
0739 current task from the current warrior's task queue.

0740 5.5.2 MOV
0741 Move replaces the B-target with the A-value and queues the next
0742 instruction (PC + 1).

0743 5.5.3 ADD
0744 ADD replaces the B-target with the sum of the A-value and the B-value
0745 (A-value + B-value) and queues the next instruction (PC + 1).  ADD.I
0746 functions as ADD.F would.

0747 5.5.4 SUB
0748 SUB replaces the B-target with the difference of the B-value and the
0749 A-value (B-value - A-value) and queues the next instruction (PC + 1).
0750 SUB.I functions as SUB.F would.

0751 5.5.5 MUL
0752 MUL replaces the B-target with the product of the A-value and the
0753 B-value (A-value * B-value) and queues the next instruction (PC + 1).
0754 MUL.I functions as MUL.F would.

0755 5.5.6 DIV
0756 DIV replaces the B-target with the integral result of dividing the
0757 B-value by the A-value (B-value / A-value) and queues the next
0758 instruction (PC + 1).  DIV.I functions as DIV.F would. If the
0759 A-value is zero, the B-value is unchanged and the current task is
0760 removed from the warrior's task queue.  DIV.I, DIV.F, and DIV.X
0761 operate on pairs of operands.  If either component of the A-value
0762 is zero, the corresponding component of the B-value is unchanged
0763 (the other component is divided normally), and the current task is
0764 removed from the warrior queue.

0765 5.5.7 MOD
0766 MOD replaces the B-target with the integral remainder of dividing the
0767 B-value by the A-value (B-value % A-value) and queues the next
0768 instruction (PC + 1).  MOD.I functions as MOD.F would. If the
0769 A-value is zero, the B-value is unchanged and the current task is
0770 removed from the warrior's task queue.  MOD.I, MOD.F, and MOD.X
0771 operate on pairs of operands.  If either component of the A-value
0772 is zero, the corresponding component of the B-value is unchanged
0773 (the other component is divided normally), and the current task is
0774 removed from the warrior queue.

0775 5.5.8 JMP
0776 JMP queues the sum of the program counter and the A-pointer.

0777 5.5.9 JMZ
0778 JMZ tests the B-value to determine if it is zero.  If the B-value is
0779 zero, the sum of the program counter and the A-pointer is queued.
0780 Otherwise, the next instruction is queued (PC + 1).  JMZ.I functions
0781 as JMZ.F would, i.e. it jumps if both the A-number and the B-number
0782 of the B-instruction are zero.

0783 5.5.10 JMN
0784 JMN tests the B-value to determine if it is zero.  If the B-value is
0785 not zero, the sum of the program counter and the A-pointer is queued.
0786 Otherwise, the next instruction is queued (PC + 1).  JMN.I functions
0787 as JMN.F would, i.e. it jumps if the A-number or the B-number of the
0788 B-instruction (or both) is non-zero. This is the negation of the
0789 condition for JMZ.F.

0790 5.5.11 DJN
0791 DJN decrements the B-value and the B-target, then tests the B-value
0792 to determine if it is zero.  If the decremented B-value is not zero,
0793 the sum of the program counter and the A-pointer is queued.
0794 Otherwise, the next instruction is queued (PC + 1).  DJN.I functions
0795 as DJN.F would, i.e. it decrements both both A/B-numbers of the B-value
0796 and the B-target, and jumps if one (or both) of the A/B-numbers of the
0797 B-value is non-zero.

0798 5.5.12 SEQ and CMP
0799 SEQ and CMP are synonymous opcodes.  SEQ is provided as an
0800 easy-to-remember mnemonic, and CMP is provided for backward
0801 compatibility.  They are completely equivalent.  SEQ (or CMP) compares
0802 the A-value to the B-value.  If the result of the comparison is equal,
0803 the instruction after the next instruction (PC + 2) is queued (skipping
0804 the next instruction).  Otherwise, the next instruction is queued
0805 (PC + 1).

0806 5.5.13 SNE
0807 SNE compares the A-value to the B-value.  If the result of the
0808 comparison is not equal, the instruction after the next instruction
0809 (PC + 2) is queued (skipping the next instruction).  Otherwise, the
0810 next instruction is queued (PC + 1).

0811 5.5.14 SLT
0812 SLT compares the A-value to the B-value.  If the A-value is less than
0813 the B-value, the instruction after the next instruction (PC + 2) is
0814 queued (skipping the next instruction).  Otherwise, the next
0815 instruction is queued (PC + 1).  SLT.I functions as SLT.F would, i.e.
0816 the next instruction is skipped only if each of the A/B-numbers of the
0817 A-value is less than its B-value counterpart.

0818 5.5.15 SPL
0819 SPL queues the next instruction (PC + 1) and then queues the sum of
0820 the program counter and the A-pointer. If the queue is full, only the
0821 next instruction is queued.

0822 5.5.16 NOP
0823 NOP queues the next instruction (PC + 1).


0824 5.6 Example MARS Interpreter

0825 /************************************/
0826 /*                                  */
0827 /*            EMI94.c               */
0828 /*                                  */
0829 /* Execute MARS Instruction ala     */
0830 /* ICWS'94 Draft Standard.          */
0831 /*                                  */
0832 /* Last Update: November 8, 1995    */
0833 /*                                  */
0834 /************************************/

0835 /* This ANSI C function is the benchmark MARS instruction   */
0836 /* interpreter for the ICWS'94 Draft Standard.              */


0837 /* The design philosophy of this function is to mirror the  */
0838 /* standard as closely as possible, illuminate the meaning  */
0839 /* of the standard, and provide the definitive answers to   */
0840 /* questions of the "well, does the standard mean this or   */
0841 /* that?" variety.  Although other, different implemen-     */
0842 /* tations are definitely possible and encouraged; those    */
0843 /* implementations should produce the same results as this  */
0844 /* one does.                                                */


0845 /* The function returns the state of the system.  What the  */
0846 /* main program does with this information is not defined   */
0847 /* by the standard.                                         */

0848 enum SystemState {
0849    UNDEFINED,
0850    SUCCESS
0851 };


0852 /* Any number of warriors may be executing in core at one   */
0853 /* time, depending on the run-time variable set and how     */
0854 /* many warriors have failed during execution.  For this    */
0855 /* implementation, warriors are identified by the order in  */
0856 /* which they were loaded into core.                        */

0857 typedef unsigned int Warrior;


0858 /* An Address in Core War can be any number from 0 to the   */
0859 /* size of core minus one, relative to the current          */
0860 /* instruction.  In this implementation, core is an array   */
0861 /* of instructions; therefore any variable types which      */
0862 /* contain an Address can be considered to be of type       */
0863 /* unsigned int.  One caveat: for the purposes of this      */
0864 /* standard, unsigned int must be considered to have no     */
0865 /* upper limit.  Depending on the size of core, it may be   */
0866 /* necessary to take precautions against overflow.          */

0867 typedef unsigned int Address;


0868 /* The FIFO task queues and supporting functions are not    */
0869 /* presented.   The function Queue() attempts to add a task */
0870 /* pointer to the back of the currently executing warrior's */
0871 /* task queue.  No special actions are to be taken if       */
0872 /* Queue() is unsuccessful, which it will be if the warrior */
0873 /* has already reached the task limit (maximum allowable    */
0874 /* number of tasks).                                        */

0875 extern void Queue(
0876    Warrior  W,
0877    Address  TaskPointer
0878 );


0879 /* There is one support function used to limit the range of */
0880 /* reading from Core and writing to Core relative to the    */
0881 /* current instruction.  Behaviour is as expected (a small  */
0882 /* core within Core) only if the limits are factors of the  */
0883 /* size of Core.                                            */

0884 static Address Fold(
0885    Address  pointer,    /* The pointer to fold into the desired range.  */
0886    Address  limit,      /* The range limit.                             */
0887    Address  M           /* The size of Core.                            */
0888 ) {
0889    Address  result;

0890    result = pointer % limit;
0891    if ( result > (limit/2) ) {
0892       result += M - limit;
0893    };
0894    return(result);
0895 }


0896 /* Instructions are the principle data type.  Core is an    */
0897 /* array of instructions, and there are three instruction   */
0898 /* registers used by the MARS executive.                    */

0899 enum Opcode {
0900    DAT,
0901    MOV,
0902    ADD,
0903    SUB,
0904    MUL,
0905    DIV,
0906    MOD,
0907    JMP,
0908    JMZ,
0909    JMN,
0910    DJN,
0911    CMP, /* aka SEQ */
0912    SNE,
0913    SLT,
0914    SPL,
0915    NOP,
0916 };

0917 enum Modifier {
0918    A,
0919    B,
0920    AB,
0921    BA,
0922    F,
0923    X,
0924    I
0925 };

0926 enum Mode {
0927    IMMEDIATE,
0928    DIRECT,
0929    A_INDIRECT,
0930    B_INDIRECT,
0931    A_DECREMENT,
0932    B_DECREMENT,
0933    A_INCREMENT,
0934    B_INCREMENT,
0935 };

0936 typedef struct Instruction {
0937    enum Opcode    Opcode;
0938    enum Modifier  Modifier;
0939    enum Mode      AMode;
0940    Address        ANumber;
0941    enum Mode      BMode;
0942    Address        BNumber;
0943 } Instruction;


0944 /* The function is passed which warrior is currently        */
0945 /* executing, the address of the warrior's current task's   */
0946 /* current instruction, a pointer to the Core, the size of  */
0947 /* the Core, and the read and write limits.  It returns the */
0948 /* system's state after attempting instruction execution.   */

0949 enum SystemState EMI94(

0950 /* W indicates which warrior's code is executing.           */

0951    Warrior  W,

0952 /* PC is the address of this warrior's current task's       */
0953 /* current instruction.                                     */

0954    Address  PC,

0955 /* Core is just an array of Instructions.  Core has been    */
0956 /* initialized and the warriors have been loaded before     */
0957 /* calling this function.                                   */

0958    Instruction Core[],

0959 /* M is the size of Core.                                   */

0960    Address     M,

0961 /* ReadLimit is the limitation on read distances.           */

0962    Address     ReadLimit,

0963 /* WriteLimit is the limitation on write distances.         */

0964    Address     WriteLimit


0965 ) {


0966 /* This MARS stores the currently executing instruction in  */
0967 /* the instruction register IR.                             */

0968    Instruction IR;

0969 /* This MARS stores the instruction referenced by the       */
0970 /* A-operand in the instruction register IRA.               */

0971    Instruction IRA;

0972 /* This MARS stores the instruction referenced by the       */
0973 /* B-operand in the instruction Register IRB.               */

0974    Instruction IRB;

0975 /* All four of the following pointers are PC-relative       */
0976 /* (relative to the Program Counter).  Actual access of     */
0977 /* core must add-in the Program Counter (mod core size).    */

0978 /* The offset to the instruction referred to by the         */
0979 /* A-operand for reading is Read Pointer A (RPA).           */

0980    Address     RPA;

0981 /* The offset to the instruction referred to by the         */
0982 /* A-operand for writing is Write Pointer A (WPA).          */

0983    Address     WPA;

0984 /* The offset to the instruction referred to by the         */
0985 /* B-operand for reading is Read Pointer B (RPB).           */

0986    Address     RPB;

0987 /* The offset to the instruction referred to by the         */
0988 /* A-operand for writing is Write Pointer B (WPB).          */

0989    Address     WPB;

0990 /* Post-increment operands need to keep track of which      */
0991 /* instruction to increment.                                */

0992    Address     PIP;

0993 /* Before execution begins, the current instruction is      */
0994 /* copied into the Instruction Register.                    */

0995    IR = Core[PC];


0996 /* Next, the A-operand is completely evaluated.             */

0997 /* For instructions with an Immediate A-mode, the Pointer A */
0998 /* points to the source of the current instruction.         */

0999    if (IR.AMode == IMMEDIATE) {
1000       RPA = WPA = 0;
1001    } else {

1002 /* For instructions with a Direct A-mode, the Pointer A     */
1003 /* points to the instruction IR.ANumber away, relative to   */
1004 /* the Program Counter.                                     */
1005 /* Note that implementing Core as an array necessitates     */
1006 /* doing all Address arithmetic modulus the size of Core.   */

1007       RPA = Fold(IR.ANumber, ReadLimit, M);
1008       WPA = Fold(IR.ANumber, WriteLimit, M);

1009 /* For instructions with A-indirection in the A-operand     */
1010 /* (A-number Indirect, A-number Predecrement,               */
1011 /* and A-number Postincrement A-modes):                     */

1012       if (IR.AMode == A_INDIRECT
1013           || IR.AMode == A_DECREMENT
1014           || IR.AMode == A_INCREMENT) {

1015 /* For instructions with Predecrement A-mode, the A-Field   */
1016 /* of the instruction in Core currently pointed to by the   */
1017 /* Pointer A is decremented (M - 1 is added).               */

1018          if (IR.AMode == A_DECREMENT) {
1019             Core[((PC + WPA) % M)].ANumber =
1020                (Core[((PC + WPA) % M)].ANumber + M - 1) % M;
1021          };

1022 /* For instructions with Postincrement A-mode, the A-Field  */
1023 /* of the instruction in Core currently pointed to by the   */
1024 /* Pointer A will be incremented.                           */

1025          if (IR.AMode == A_INCREMENT) {
1026             PIP = (PC + WPA) % M;
1027          };

1028 /* For instructions with A-indirection in the A-operand,    */
1029 /* Pointer A ultimately points to the instruction           */
1030 /* Core[((PC + PCA) % M)].ANumber away, relative to the     */
1031 /* instruction pointed to by Pointer A.                     */

1032          RPA = Fold(
1033             (RPA + Core[((PC + RPA) % M)].ANumber), ReadLimit, M
1034          );
1035          WPA = Fold(
1036             (WPA + Core[((PC + WPA) % M)].ANumber), WriteLimit, M
1037          );

1038       };

1039 /* For instructions with B-indirection in the A-operand     */
1040 /* (B-number Indirect, B-number Predecrement,               */
1041 /* and B-number Postincrement A-modes):                     */

1042       if (IR.AMode == B_INDIRECT
1043           || IR.AMode == B_DECREMENT
1044           || IR.AMode == B_INCREMENT) {

1045 /* For instructions with Predecrement A-mode, the B-Field   */
1046 /* of the instruction in Core currently pointed to by the   */
1047 /* Pointer A is decremented (M - 1 is added).               */

1048          if (IR.AMode == DECREMENT) {
1049             Core[((PC + WPA) % M)].BNumber =
1050                (Core[((PC + WPA) % M)].BNumber + M - 1) % M;
1051          };

1052 /* For instructions with Postincrement A-mode, the B-Field  */
1053 /* of the instruction in Core currently pointed to by the   */
1054 /* Pointer A will be incremented.                           */

1055          if (IR.AMode == INCREMENT) {
1056             PIP = (PC + WPA) % M;
1057          };

1058 /* For instructions with B-indirection in the A-operand,    */
1059 /* Pointer A ultimately points to the instruction           */
1060 /* Core[((PC + PCA) % M)].BNumber away, relative to the     */
1061 /* instruction pointed to by Pointer A.                     */

1062          RPA = Fold(
1063             (RPA + Core[((PC + RPA) % M)].BNumber), ReadLimit, M
1064          );
1065          WPA = Fold(
1066             (WPA + Core[((PC + WPA) % M)].BNumber), WriteLimit, M
1067          );

1068       };
1069    };

1070 /* The Instruction Register A is a copy of the instruction  */
1071 /* pointed to by Pointer A.                                 */

1072    IRA = Core[((PC + RPA) % M)];

1073 /* If the A-mode was post-increment, now is the time to     */
1074 /* increment the instruction in core.                       */

1075    if (IR.AMode == A_INCREMENT) {
1076            Core[PIP].ANumber = (Core[PIP].ANumber + 1) % M;
1077            }
1078    else if (IR.AMode == B_INCREMENT) {
1079            Core[PIP].BNumber = (Core[PIP].BNumber + 1) % M;
1080            };

1081 /* The Pointer B and the Instruction Register B are         */
1082 /* evaluated in the same manner as their A counterparts.    */

1083    if (IR.BMode == IMMEDIATE) {
1084       RPB = WPB = 0;
1085    } else {
1086       RPB = Fold(IR.BNumber, ReadLimit, M);
1087       WPB = Fold(IR.BNumber, WriteLimit, M);
1088       if (IR.BMode == A_INDIRECT
1089           || IR.BMode == A_DECREMENT
1090           || IR.BMode == A_INCREMENT) {
1091          if (IR.BMode == A_DECREMENT) {
1092             Core[((PC + WPB) % M)].ANumber =
1093                (Core[((PC + WPB) % M)].ANumber + M - 1) % M
1094             ;
1095          } else if (IR.BMode == A_INCREMENT) {
1096             PIP = (PC + WPB) % M;
1097          };
1098          RPB = Fold(
1099             (RPB + Core[((PC + RPB) % M)].ANumber), ReadLimit, M
1100          );
1101          WPB = Fold(
1102             (WPB + Core[((PC + WPB) % M)].ANumber), WriteLimit, M
1103          );
1104       };
1105       if (IR.BMode == B_INDIRECT
1106           || IR.BMode == B_DECREMENT
1107           || IR.BMode == B_INCREMENT) {
1108          if (IR.BMode == B_DECREMENT) {
1109             Core[((PC + WPB) % M)].BNumber =
1110                (Core[((PC + WPB) % M)].BNumber + M - 1) % M
1111             ;
1112          } else if (IR.BMode == B_INCREMENT) {
1113             PIP = (PC + WPB) % M;
1114          };
1115          RPB = Fold(
1116             (RPB + Core[((PC + RPB) % M)].BNumber), ReadLimit, M
1117          );
1118          WPB = Fold(
1119             (WPB + Core[((PC + WPB) % M)].BNumber), WriteLimit, M
1120          );
1121       };
1122    };
1123    IRB = Core[((PC + RPB) % M)];

1124    if (IR.BMode == A_INCREMENT) {
1125            Core[PIP].ANumber = (Core[PIP].ANumber + 1) % M;
1126            }
1127    else if (IR.BMode == INCREMENT) {
1128            Core[PIP].BNumber = (Core[PIP].BNumber + 1) % M;
1129            };

1130 /* Execution of the instruction can now proceed.            */

1131    switch (IR.Opcode) {

1132 /* Instructions with a DAT opcode have no further function. */
1133 /* The current task's Program Counter is not updated and is */
1134 /* not returned to the task queue, effectively removing the */
1135 /* task.                                                    */

1136    case DAT: noqueue:
1137       break;


1138 /* MOV replaces the B-target with the A-value and queues    */
1139 /* the next instruction.                                    */

1140    case MOV:
1141       switch (IR.Modifier) {

1142 /* Replaces A-number with A-number.                         */

1143       case A:
1144          Core[((PC + WPB) % M)].ANumber = IRA.ANumber;
1145          break;

1146 /* Replaces B-number with B-number.                         */

1147       case B:
1148          Core[((PC + WPB) % M)].BNumber = IRA.BNumber;
1149          break;

1150 /* Replaces B-number with A-number.                         */

1151       case AB:
1152          Core[((PC + WPB) % M)].BNumber = IRA.ANumber;
1153          break;

1154 /* Replaces A-number with B-number.                         */

1155       case BA:
1156          Core[((PC + WPB) % M)].ANumber = IRA.BNumber;
1157          break;

1158 /* Replaces A-number with A-number and B-number with        */
1159 /* B-number.                                                */

1160       case F:
1161          Core[((PC + WPB) % M)].ANumber = IRA.ANumber;
1162          Core[((PC + WPB) % M)].BNumber = IRA.BNumber;
1163          break;

1164 /* Replaces B-number with A-number and A-number with        */
1165 /* B-number.                                                */

1166       case X:
1167          Core[((PC + WPB) % M)].BNumber = IRA.ANumber;
1168          Core[((PC + WPB) % M)].ANumber = IRA.BNumber;
1169          break;

1170 /* Copies entire instruction.                               */

1171       case I:
1172          Core[((PC + WPB) % M)] = IRA;
1173          break;

1174       default:
1175          return(UNDEFINED);
1176          break;
1177       };

1178 /* Queue up next instruction.                               */
1179       Queue(W, ((PC + 1) % M));
1180       break;

1181 /* Arithmetic instructions replace the B-target with the    */
1182 /* "op" of the A-value and B-value, and queue the next      */
1183 /* instruction.  "op" can be the sum, the difference, or    */
1184 /* the product.                                             */

1185 #define ARITH(op) \
1186       switch (IR.Modifier) { \
1187       case A: \
1188          Core[((PC + WPB) % M)].ANumber = \
1189             (IRB.ANumber op IRA.ANumber) % M \
1190          ; \
1191          break; \
1192       case B: \
1193          Core[((PC + WPB) % M)].BNumber = \
1194             (IRB.BNumber op IRA.BNumber) % M \
1195          ; \
1196          break; \
1197       case AB: \
1198          Core[((PC + WPB) % M)].BNumber = \
1199             (IRB.ANumber op IRA.BNumber) % M \
1200          ; \
1201          break; \
1202       case BA: \
1203          Core[((PC + WPB) % M)].ANumber = \
1204             (IRB.BNumber op IRA.ANumber) % M \
1205          ; \
1206          break; \
1207       case F: \
1208       case I: \
1209          Core[((PC + WPB) % M)].ANumber = \
1210             (IRB.ANumber op IRA.ANumber) % M \
1211          ; \
1212          Core[((PC + WPB) % M)].BNumber = \
1213             (IRB.BNumber op IRA.BNumber) % M \
1214          ; \
1215          break; \
1216       case X: \
1217          Core[((PC + WPB) % M)].BNumber = \
1218             (IRB.ANumber op IRA.BNumber) % M \
1219          ; \
1220          Core[((PC + WPB) % M)].ANumber = \
1221             (IRB.BNumber op IRA.ANumber) % M \
1222          ; \
1223          break; \
1224       default: \
1225          return(UNDEFINED); \
1226          break; \
1227       }; \
1228       Queue(W, ((PC + 1) % M)); \
1229       break;

1230    case ADD: ARITH(+)
1231    case SUB: ARITH(+ M -)
1232    case MUL: ARITH(*)

1233 /* DIV and MOD replace the B-target with the integral       */
1234 /* quotient (for DIV) or remainder (for MOD) of the B-value */
1235 /* by the A-value, and queues the next instruction.         */
1236 /* Process is removed from task queue if A-value is zero.   */

1237 #define ARITH_DIV(op) \
1238       switch (IR.Modifier) { \
1239       case A: \
1240          if (IRA.ANumber != 0) \
1241             Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.ANumber; \
1242          break; \
1243       case B: \
1244          if (IRA.BNumber != 0) \
1245             Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.BNumber; \
1246          else goto noqueue; \
1247          break; \
1248       case AB: \
1249          if (IRA.ANumber != 0) \
1250             Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.ANumber; \
1251          else goto noqueue; \
1252          break; \
1253       case BA: \
1254          if (IRA.BNumber != 0) \
1255             Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.BNumber; \
1256          else goto noqueue; \
1257          break; \
1258       case F: \
1259       case I: \
1260          if (IRA.ANumber != 0) \
1261             Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.ANumber; \
1262          if (IRA.BNumber != 0) \
1263             Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.BNumber; \
1264          if ((IRA.ANumber == 0) || (IRA.BNumber == 0)) \
1265             goto noqueue; \
1266          break; \
1267       case X: \
1268          if (IRA.ANumber != 0) \
1269             Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.ANumber; \
1270          if (IRA.BNumber != 0) \
1271             Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.BNumber; \
1272          if ((IRA.ANumber == 0) || (IRA.BNumber == 0)) \
1273             goto noqueue; \
1274          break; \
1275       default: \
1276          return(UNDEFINED); \
1277          break; \
1278       }; \
1279       Queue(W, ((PC + 1) % M)); \
1280       break;

1281    case DIV: ARITH_DIV(/)
1282    case MOD: ARITH_DIV(%)

1283 /* JMP queues the sum of the Program Counter and the        */
1284 /* A-pointer.                                               */

1285    case JMP:
1286       Queue(W, RPA);
1287       break;


1288 /* JMZ queues the sum of the Program Counter and Pointer A  */
1289 /* if the B-value is zero.  Otherwise, it queues the next   */
1290 /* instruction.                                             */

1291    case JMZ:
1292       switch (IR.Modifier) {
1293       case A:
1294       case BA:
1295          if (IRB.ANumber == 0) {
1296             Queue(W, RPA);
1297          } else {
1298             Queue(W, ((PC + 1) % M));
1299          };
1300          break;
1301       case B:
1302       case AB:
1303          if (IRB.BNumber == 0) {
1304             Queue(W, RPA);
1305          } else {
1306             Queue(W, ((PC + 1) % M));
1307          };
1308          break;
1309       case F:
1310       case X:
1311       case I:
1312          if ( (IRB.ANumber == 0) && (IRB.BNumber == 0) ) {
1313             Queue(W, RPA);
1314          } else {
1315             Queue(W, ((PC + 1) % M));
1316          };
1317          break;
1318       default:
1319          return(UNDEFINED);
1320          break;
1321       };
1322       break;


1323 /* JMN queues the sum of the Program Counter and Pointer A  */
1324 /* if the B-value is not zero.  Otherwise, it queues the    */
1325 /* next instruction.                                        */

1326    case JMN:
1327       switch (IR.Modifier) {
1328       case A:
1329       case BA:
1330          if (IRB.ANumber != 0) {
1331             Queue(W, RPA);
1332          } else {
1333             Queue(W, ((PC + 1) % M));
1334          };
1335          break;
1336       case B:
1337       case AB:
1338          if (IRB.BNumber != 0) {
1339             Queue(W, RPA);
1340          } else {
1341             Queue(W, ((PC + 1) % M));
1342          };
1343          break;
1344       case F:
1345       case X:
1346       case I:
1347          if ( (IRB.ANumber != 0) || (IRB.BNumber != 0) ) {
1348             Queue(W, RPA);
1349          } else {
1350             Queue(W, ((PC + 1) % M));
1351          };
1352          break;
1353       default:
1354          return(UNDEFINED);
1355          break;
1356       };
1357       break;


1358 /* DJN (Decrement Jump if Not zero) decrements the B-value  */
1359 /* and the B-target, then tests if the B-value is zero.  If */
1360 /* the result is not zero, the sum of the Program Counter   */
1361 /* and Pointer A is queued.  Otherwise, the next            */
1362 /* instruction is queued.                                   */

1363    case DJN:
1364       switch (IR.Modifier) {
1365       case A:
1366       case BA:
1367          Core[((PC + WPB) % M)].ANumber =
1368             (Core[((PC + WPB) % M)].ANumber + M - 1) % M
1369          ;
1370          IRB.ANumber -= 1;
1371          if (IRB.ANumber != 0) {
1372             Queue(W, RPA);
1373          } else {
1374             Queue(W, ((PC + 1) % M));
1375          };
1376          break;
1377       case B:
1378       case AB:
1379          Core[((PC + WPB) % M)].BNumber =
1380             (Core[((PC + WPB) % M)].BNumber + M - 1) % M
1381          ;
1382          IRB.BNumber -= 1;
1383          if (IRB.BNumber != 0) {
1384             Queue(W, RPA);
1385          } else {
1386             Queue(W, ((PC + 1) % M));
1387          };
1388          break;
1389       case F:
1390       case X:
1391       case I:
1392          Core[((PC + WPB) % M)].ANumber =
1393             (Core[((PC + WPB) % M)].ANumber + M - 1) % M
1394          ;
1395          IRB.ANumber -= 1;
1396          Core[((PC + WPB) % M)].BNumber =
1397             (Core[((PC + WPB) % M)].BNumber + M - 1) % M
1398          ;
1399          IRB.BNumber -= 1;
1400          if ( (IRB.ANumber != 0) || (IRB.BNumber != 0) ) {
1401             Queue(W, RPA);
1402          } else {
1403             Queue(W, ((PC + 1) % M));
1404          };
1405          break;
1406       default:
1407          return(UNDEFINED);
1408          break;
1409       };
1410       break;


1411 /* SEQ/CMP compares the A-value and the B-value. If there   */
1412 /* are no differences, then the instruction after the next  */
1413 /* instruction is queued.  Otherwise, the next instrution   */
1414 /* is queued.                                               */

1415    case CMP:
1416       switch (IR.Modifier) {
1417       case A:
1418          if (IRA.ANumber == IRB.ANumber) {
1419             Queue(W, ((PC + 2) % M));
1420          } else {
1421             Queue(W, ((PC + 1) % M));
1422          };
1423          break;
1424       case B:
1425          if (IRA.BNumber == IRB.BNumber) {
1426             Queue(W, ((PC + 2) % M));
1427          } else {
1428             Queue(W, ((PC + 1) % M));
1429          };
1430          break;
1431       case AB:
1432          if (IRA.ANumber == IRB.BNumber) {
1433             Queue(W, ((PC + 2) % M));
1434          } else {
1435             Queue(W, ((PC + 1) % M));
1436          };
1437          break;
1438       case BA:
1439          if (IRA.BNumber == IRB.ANumber) {
1440             Queue(W, ((PC + 2) % M));
1441          } else {
1442             Queue(W, ((PC + 1) % M));
1443          };
1444          break;
1445       case F:
1446          if ( (IRA.ANumber == IRB.ANumber) &&
1447               (IRA.BNumber == IRB.BNumber)
1448          ) {
1449             Queue(W, ((PC + 2) % M));
1450          } else {
1451             Queue(W, ((PC + 1) % M));
1452          };
1453          break;
1454       case X:
1455          if ( (IRA.ANumber == IRB.BNumber) &&
1456               (IRA.BNumber == IRB.ANumber)
1457          ) {
1458             Queue(W, ((PC + 2) % M));
1459          } else {
1460             Queue(W, ((PC + 1) % M));
1461          };
1462          break;
1463       case I:
1464          if ( (IRA.Opcode == IRB.Opcode) &&
1465               (IRA.Modifier == IRB.Modifier) &&
1466               (IRA.AMode == IRB.AMode) &&
1467               (IRA.ANumber == IRB.ANumber) &&
1468               (IRA.BMode == IRB.BMode) &&
1469               (IRA.BNumber == IRB.BNumber)
1470          ) {
1471             Queue(W, ((PC + 2) % M));
1472          } else {
1473             Queue(W, ((PC + 1) % M));
1474          };
1475          break;
1476       default:
1477          return(UNDEFINED);
1478          break;
1479       };
1480       break;


1481 /* SNE compares the A-value and the B-value. If there       */
1482 /* is a difference, then the instruction after the next     */
1483 /* instruction is queued.  Otherwise, the next instrution   */
1484 /* is queued.                                               */

1485    case SNE:
1486       switch (IR.Modifier) {
1487       case A:
1488          if (IRA.ANumber != IRB.ANumber) {
1489             Queue(W, ((PC + 2) % M));
1490          } else {
1491             Queue(W, ((PC + 1) % M));
1492          };
1493          break;
1494       case B:
1495          if (IRA.BNumber != IRB.BNumber) {
1496             Queue(W, ((PC + 2) % M));
1497          } else {
1498             Queue(W, ((PC + 1) % M));
1499          };
1500          break;
1501       case AB:
1502          if (IRA.ANumber != IRB.BNumber) {
1503             Queue(W, ((PC + 2) % M));
1504          } else {
1505             Queue(W, ((PC + 1) % M));
1506          };
1507          break;
1508       case BA:
1509          if (IRA.BNumber != IRB.ANumber) {
1510             Queue(W, ((PC + 2) % M));
1511          } else {
1512             Queue(W, ((PC + 1) % M));
1513          };
1514          break;
1515       case F:
1516          if ( (IRA.ANumber != IRB.ANumber) ||
1517               (IRA.BNumber != IRB.BNumber)
1518          ) {
1519             Queue(W, ((PC + 2) % M));
1520          } else {
1521             Queue(W, ((PC + 1) % M));
1522          };
1523          break;
1524       case X:
1525          if ( (IRA.ANumber != IRB.BNumber) ||
1526               (IRA.BNumber != IRB.ANumber)
1527          ) {
1528             Queue(W, ((PC + 2) % M));
1529          } else {
1530             Queue(W, ((PC + 1) % M));
1531          };
1532          break;
1533       case I:
1534          if ( (IRA.Opcode != IRB.Opcode) ||
1535               (IRA.Modifier != IRB.Modifier) ||
1536               (IRA.AMode != IRB.AMode) ||
1537               (IRA.ANumber != IRB.ANumber) ||
1538               (IRA.BMode != IRB.BMode) ||
1539               (IRA.BNumber != IRB.BNumber)
1540          ) {
1541             Queue(W, ((PC + 2) % M));
1542          } else {
1543             Queue(W, ((PC + 1) % M));
1544          };
1545          break;
1546       default:
1547          return(UNDEFINED);
1548          break;
1549       };
1550       break;


1551 /* SLT (Skip if Less Than) queues the instruction after the */
1552 /* next instruction if A-value is less than B-value.        */
1553 /* Otherwise, the next instruction is queued.  Note that no */
1554 /* value is less than zero because only positive values can */
1555 /* be represented in core.                                  */

1556    case SLT :
1557       switch (IR.Modifier) {
1558       case A:
1559          if (IRA.ANumber < IRB.ANumber) {
1560             Queue(W, ((PC + 2) % M));
1561          } else {
1562             Queue(W, ((PC + 1) % M));
1563          };
1564          break;
1565       case B:
1566          if (IRA.BNumber < IRB.BNumber) {
1567             Queue(W, ((PC + 2) % M));
1568          } else {
1569             Queue(W, ((PC + 1) % M));
1570          };
1571          break;
1572       case AB:
1573          if (IRA.ANumber < IRB.BNumber) {
1574             Queue(W, ((PC + 2) % M));
1575          } else {
1576             Queue(W, ((PC + 1) % M));
1577          };
1578          break;
1579       case BA:
1580          if (IRA.BNumber < IRB.ANumber) {
1581             Queue(W, ((PC + 2) % M));
1582          } else {
1583             Queue(W, ((PC + 1) % M));
1584          };
1585          break;
1586       case F:
1587       case I:
1588          if ( (IRA.ANumber < IRB.ANumber) &&
1589               (IRA.BNumber < IRB.BNumber)
1590          ) {
1591             Queue(W, ((PC + 2) % M));
1592          } else {
1593             Queue(W, ((PC + 1) % M));
1594          };
1595          break;
1596       case X:
1597          if ( (IRA.ANumber < IRB.BNumber) &&
1598               (IRA.BNumber < IRB.ANumber)
1599          ) {
1600             Queue(W, ((PC + 2) % M));
1601          } else {
1602             Queue(W, ((PC + 1) % M));
1603          };
1604          break;
1605       default:
1606          return(UNDEFINED);
1607          break;
1608       };
1609       break;


1610 /* SPL queues the next instruction and also queues the sum  */
1611 /* of the Program Counter and Pointer A.                    */

1612    case SPL:
1613       Queue(W, ((PC + 1) % M));
1614       Queue(W, RPA);
1615       break;


1616 /* NOP queues the next instruction.                         */

1617    case NOP:
1618       Queue(W, ((PC + 1) % M));
1619       break;


1620 /* Any other opcode is undefined.                           */

1621    default:
1622       return(UNDEFINED);
1623    };


1624 /* We are finished.                                         */

1625    return(SUCCESS);
1626 }

1627 6. Validation Suite

1628 6.1 Purpose and Requirements
1629 This validation suite exists to help developers test the compatibility
1630 of their Core War systems with the requirements set up in this
1631 standard.

1632 6.2 Assembly To Load File Test

1633 6.3 MARS tests

1634 6.3.1   DAT Tests
1635 6.3.2   MOV Tests
1636 6.3.3   ADD Tests
1637 6.3.4   SUB Tests
1638 6.3.5   MUL Tests
1639 6.3.6   DIV Tests
1640 6.3.7   MOD Tests
1641 6.3.8   JMP Tests
1642 6.3.9   JMZ Tests
1643 6.3.10  JMN Tests
1644 6.3.11  DJN Tests
1645 6.3.12  SEQ/CMP Tests
1646 6.3.13  SNE Tests
1647 6.3.14  SLT Tests
1648 6.3.15  SPL Tests
1649 6.3.16  NOP Tests


1650 7. Glossary and Index
1651 alphanumeric    Any of the characters A-Za-z0-9 and the underscore.

1652 assembly file   A file containing Redcode instructions.

1653 battle          A contest between two or more warriors.

1654 core size       See section 4.2

1655 Core War        A game in which programs compete for control of a
1656                 computer called a Memory Array Redcode Simulator.

1657 Core Wars       More than one game of Core War.

1658 cycle           See section 4.2

1659 Dwarf           See sections 2.7 and 3.6

1660 initial instruction
1661                 See section 4.2

1662 instruction     A line of Redcode or object code indicating an action
1663                 for MARS to execute.

1664 instruction limit
1665                 See section 4.2

1666 loader          A program or that part of a program which loads
1667                 warriors into a MARS.

1668 load file       A file containing a warrior's instructions in an
1669                 assembled format.  Any MARS program can be used with
1670                 any and all Redcode assemblers which produce load
1671                 files, allowing customized Core War systems.

1672 MARS            An acronym for Memory Array Redcode Simulator.  The
1673                 computer in which Core War warriors run.

1674 newline         A linefeed, carriage-return, or combination of linefeed
1675                 and carriage-return.  Whichever newline is native to
1676                 the host operating system.

1677 object code     The internal representation of a MARS instruction.

1678 read distance   See section 4.2

1679 Redcode         The assembly language of Core War.

1680 tournament      A series of battles in which points, based upon the
1681                 degree of success, are awarded for each battle and
1682                 accumulated by each warrior (or programmer, depending
1683                 upon the type of tournament).

1684 warrior         A Redcode program.

1685 whitespace      The space and tab characters.

1686 write distance  See section 4.2


1687 A. Differences Between Standards

1688 A.1 Purpose
1689 This appendix lists some of the major differences between this standard
1690 and those standards which preceded it.  The purpose is to help those
1691 who are familiar with a previous standard or standards to quickly
1692 understand those items which are new or have changed.


1693 A.2 Changes

1694 A.2.1 Assembly Files
1695 A comma is required for operand separation.

1696 Parenthetical expressions are allowed.

1697 There is a new pseudo-opcode, ORG, for specifying the first logical
1698 instruction.

1699 There is a new operator, modulus '%', for determining the remainder
1700 of integer division.

1701 A.2.1.1 ICWS'86 to ICWS'94 Conversion
1702 If a modifier is missing, it is assembled according to conversion
1703 rules that depend on whether the ICWS'86 or '88 standard is emulated.
1704 By default, a MARS should use the ICWS'88 conversion rules. Emulation
1705 of ICWS'86 is optional.

1706     Opcode                  A-mode     B-mode     modifier
1707     ---------------------------------------------------------
1708     DAT                        #$@<>*{}   #$@<>*{}   F
1709     MOV,CMP,SEQ,SNE            #          #$@<>*{}   AB
1710                                $@<>*{}    #          B
1711                                $@<>*{}    $@<>*{}    I
1712     ADD,SUB,MUL,DIV,MOD        #          #$@<>*{}   AB
1713                                $@<>*{}    #$@<>*{}   B
1714     SLT                        #          #$@<>*{}   AB
1715                                $@<>*{}    #$@<>*{}   B
1716     JMP,JMZ,JMN,DJN,SPL,NOP    #$@<>*{}   #$@<>*{}   B
1717     ---------------------------------------------------------

1718 A.2.1.2 ICWS'88 to ICWS'94 Conversion
1719 The default modifier for ICWS'88 emulation is determined according
1720 to the table below.

1721     Opcode                     A-mode     B-mode     modifier
1722     ---------------------------------------------------------
1723     DAT                        #$@<>*{}   #$@<>*{}   F
1724     MOV,CMP,SEQ,SNE            #          #$@<>*{}   AB
1725                                $@<>*{}    #          B
1726                                $@<>*{}    $@<>*{}    I
1727     ADD,SUB,MUL,DIV,MOD        #          #$@<>*{}   AB
1728                                $@<>*{}    #          B
1729                                $@<>*{}    $@<>*{}    F
1730     SLT                        #          #$@<>*{}   AB
1731                                $@<>*{}    #$@<>*{}   B
1732     JMP,JMZ,JMN,DJN,SPL,NOP    #$@<>*{}   #$@<>*{}   B
1733     ---------------------------------------------------------

1734 A.2.2 Load Files
1735 A load file format is specified for the first time.  (An object code
1736 did exist for ICWS'86).


1737 A.2.3 MARS
1738 There are no illegal instructions.

1739 The following addressing modes have been added:
1740 A-number indirect, A-number predecrement, A-number postincrement,
1741 and B-number postincrement.

1742 MUL, DIV, MOD, SNE, and NOP have been added.
1743 SEQ is an alias for CMP.

1744 Opcode modifiers have been added.

1745 Read and Write distance limitations have been imposed.