石原 博の覚書

電子工作に関する日々の覚書を記載します

BCPL intcodeインタプリタのバグ?

2024-10-27 14:16:02 | 日記
CP/M68K で intcodeインタプリタで動いたが、それだけではもったいない。
Martin RichardsのBCPLサイト「https://www.cl.cam.ac.uk/~mr10/index.html」に
bcplで記述されたmlisp.bがある。これを動かすことを考えた。

ところがいろいろな問題が発生(*1)。なんとか回避したが、最後にインタプリタのバグ?が判明し諦めた。
(根本は CP/M68KのCにまで遡る。これを回避するのは難しい)

・バグの発見までの経緯
 さまざまな問題を開始したが、どうしてもmlisp.bが動かない。
 コンパイル途中のTREEを見ると、P_LISTが -0 になっていた? ソースでは $80000000 なのに。
 
  ! *--1
*-OP75
*-OP43
! *-OP43
! ! *-OP43
! ! ! *-NIL
! ! ! *-P_LIST
! ! ! *--0
! ! *-B
! ! *-2
 
 そこでテストコードを作成しコンパイルしてみた
===================
 GET "LIBHDR"

 MANIFEST $(
 X =#X7FFFFFFF
 Y =#X80000000
 Z =#X80000001
 $)

 LET START() BE
 $(
 WRITEF("%X8 %X8 %X8*N", X, Y, Z)
 WRITEF("%N %N %N*N", X, Y, Z)
 $)
===================

 OCODEではなぜか #X80000000が -00 になっている
  STACK 2 JUMP L2 ENTRY 5 L1 83 84 65 82 84 SAVE 2 STACK 4 LSTR
  12 37 88 56 32 37 88 56 32 37 88 56 10 LN 2147483647 LN -00 LN
  -2147483647 LG 76 RTAP 2 STACK 4 LSTR 9 37 78 32 37 78 32 37 78
  10 LN 2147483647 LN -00 LN -2147483647 LG 76 RTAP 2 RTRN ENDPROC
  0 STACK 2 LAB L2 STORE GLOBAL 1 1 L1

INTCODEは 0 になっている
  JL2
$ 1 LL499 SP4 L2147483647 SP5 L0 SP6 L-2147483647 SP7 LIG76 K2 LL498 SP/
4 L2147483647 SP5 L0 SP6 L-2147483647 SP7 LIG76 K2 X4 2
499 C12 C37 C88 C56 C32 C37 C88 C56 C32 C37 C88 C56 C10 498 C9 C37 C78 /
C32 C37 C78 C32 C37 C78 C10
G1L1
Z

 実行してみると 
 ===========================
 C>icint test.int


INTCODE SYSTEM ENTERED

PROGRAM SIZE = 644
7FFFFFFF 00000000 80000001
2147483647 0 -2147483647

EXECUTION CYCLES = 2295, CODE = 0
============================

 どうやら0x80000000を表示できないらしい。
 
 今度はCでテストコードを実行
 ===test2.c======================
#include <stdio.h>

int main()
{
long x = 0x80000000L;
int y = 1;
int z = 0;
printf("%08lx\n", x);
printf("%08lx\n", -x);
printf("%08lx\n", x / y);
printf("%08lx\n", x / z);
printf("%d\n", y / z);
}

C>test2

80000000 ==> わかる
80000000 ==> わからないこともない
00000000 ==> 1で割っているのに? わからない
80000000 ==> 0で割っているのに? わからない

Exception $05 at user address $000082A8. Aborted.  ==> わかる(当然)

===test2.s======
.globl __iob
.globl _main
.text
_main:
~~main:
~_EnD__=8
link R14,#-12
~x=-4
*line 5
move.l #$80000000,-4(R14) long x = 0x80000000L;
~y=-6
*line 6
move #1,-6(R14) int y = 1;
~z=-8
*line 7
clr -8(R14) int z = 0;
*line 8
move.l -4(R14),(sp) printf("%08lx\n", x); ==> 80000000
move.l #L2,-(sp)
jsr _printf
addq.l #4,sp
*line 9
move.l -4(R14),R0 printf("%08lx\n", -x); ==> 80000000
neg.l R0
move.l R0,(sp)
move.l #L3,-(sp)
jsr _printf
addq.l #4,sp
*line 10
move -6(R14),R0 printf("%08lx\n", x / y); ==> 00000000
ext.l R0
move.l R0,-(sp)
move.l -4(R14),-(sp)
jsr ldiv
addq.l #8,sp
move.l R0,(sp)
move.l #L4,-(sp)
jsr _printf
addq.l #4,sp
*line 11
move -8(R14),R0 printf("%08lx\n", x / z); ==> 80000000
ext.l R0
move.l R0,-(sp)
move.l -4(R14),-(sp)
jsr ldiv
addq.l #8,sp
move.l R0,(sp)
move.l #L5,-(sp)
jsr _printf
addq.l #4,sp
*line 12
move -6(R14),R0 printf("%d\n", y / z); ==> Exception $05
ext.l R0
divs -8(R14),R0
move R0,(sp)
move.l #L6,-(sp)
jsr _printf
addq.l #4,sp
L1:
unlk R14
rts
.data
L2:
.dc.b $25,$30,$38,$6C,$78,$A,$0
L3:
.dc.b $25,$30,$38,$6C,$78,$A,$0
L4:
.dc.b $25,$30,$38,$6C,$78,$A,$0
L5:
.dc.b $25,$30,$38,$6C,$78,$A,$0
L6:
.dc.b $25,$64,$A,$0
=================================================


 
 CP/MのDDTで確認したところ、
 CP/M68KのCの32ビットの割り算ルーチン(_ldiv)にいろいろ癖があることが判明。
 除数が0だと(エラーではなく)0x80000000になる。
 被除数が16ビット内だと divuを使うが、それ以上だとソフトウエアでの除算
 被除数が0x80000000の場合への考慮がない。
 (被除数が負の場合はnegしているが0x80000000の場合はnegしても0x80000000)

 
---$4(A7)/$8(A7) -> D1/D3 ----------------------------
---D1が 0x80000000の場合は、neg.l D1によりD1= となる。
 _ldiv:
ldiv:
0000AD7A movea.l D3,A0
0000AD7C move.l $4(A7),D1     被除数をD1へ
0000AD80 bge $AD84 被除数が0または正なら分岐
0000AD82 neg.l D1          負の場合は正の数にする
0000AD84 move.l $8(A7),D3     除数をD3へ
0000AD88 bgt $AD98 除数が正なら分岐
0000AD8A blt $AD96 除数が負なら分岐
0000AD8C move.l #$80000000,D0 ここに来るのは除数が0 返り値が$80000000
0000AD92 move.l D0,D1
0000AD94 bra $ADE4
0000AD96 neg.l D3 除数を正の数にする
0000AD98 moveq.l #$0,D0
0000AD9A cmp.l D1,D3        被除数と除数を比較
0000AD9C blt $ADA6 D1>D3(被除数>除数)なら分岐
0000AD9E bgt $ADD2 D1<D3(被除数<除数)なら分岐
0000ADA0 moveq.l #$1,D0     D1=D3(被除数=除数)なら 商=1 余り=0
0000ADA2 moveq.l #$0,D1
0000ADA4 bra $ADD2 符号調整
0000ADA6 moveq.l #$2,D2
0000ADA8 cmp.l #$10000,D1
0000ADAE bge $ADBC 被除数が>=#$10000なら分岐(ソフトウエアで割り算)
0000ADB0 divu D3,D1 d1.l / d3.w => d1.h ... d1.l
0000ADB2 move.w D1,D0         d0=余り
0000ADB4 clr.w D1
0000ADB6 swap D1 d1=商
0000ADB8 bra $ADD2          符号調整
0000ADBA add.l D2,D2
0000ADBC add.l D3,D3
0000ADBE cmp.l D3,D1
0000ADC0 bcc $ADBA 被除数<除数 になるまで除数を左シフトしながらループ
0000ADC2 bra $ADCC
0000ADC4 cmp.l D3,D1
0000ADC6 bcs $ADCC         D1<D3ならブランチ
0000ADC8 or.l D2,D0 商はD0に出来てくる
0000ADCA sub.l D3,D1 D1=D1-D3
0000ADCC lsr.l #1,D3       除数を右シフト
0000ADCE lsr.l #1,D2
0000ADD0 bne $ADC4
0000ADD2 tst.w $4(A7)       被除数が
0000ADD6 bpl $ADDC         正ならブランチ
0000ADD8 neg.l D0         負の場合は、商も余りも符号反転
0000ADDA neg.l D1
0000ADDC tst.w $8(A7) 除数が
0000ADE0 bpl $ADE4         正ならブランチ
0000ADE2 neg.l D0         負なら商を符号反転
0000ADE4 move.l D1,$B294 ._ldivr
0000ADEA move.l A0,D3
0000ADEC rts

商と余りの符号は以下のようになる
正 / 正 = 正 ... 正
負 / 正 = 負 ... 負
正 / 負 = 負 ... 正
負 / 負 = 正 ... 負


・結論
 コンパイラで0x80000000が表示出来ないのはlongの除算の扱いがおかしなためと思われる。
 (BCPLの印字のライブラリでも以下のようになっており、N=0x80000000では問題が起きる)

=================
AND WRITED(N, D) BE

$(1 LET T = VEC 20
AND I, K = 0, N
TEST N<0 THEN D := D-1 ELSE K := -N
T!I, K, I := K REM 10, K/10, I+1 REPEATUNTIL K=0
FOR J = I+1 TO D DO WRCH('*S')
IF N<0 DO WRCH('-')
FOR J = I-1 TO 0 BY -1 DO WRCH('0'-T!J) $)1

AND WRITEN(N) BE WRITED(N, 0)
=================

では、CP/M68KのCの問題かといえば、(CP/M68KのCはANSIではないけれど)
ANSI Cであっても long は <=−2,147,483,647 とのこと。
なので、−2,147,483,647まで扱えれば、-2,147,483,648が扱えなくても文句は言えない。

・大本の原因
 結局 -2,147,483,648が表示出来ると想定しているインタプリタのバグと言えるかも。。。



(*1)
[1]syntaxエラー
 BCPLは歴史的にuppercaseが使用されるが該当プログラムはlowercaseとなっている。
 ソースを置換することも検討した。(cat mlisp.b | tr [a-z] [A-Z] > mlisp2.b)
 ところがunderscore も使用されている。これを受け入れるようにするためsyn.bの変更が必要となった。
 
[2]%演算子
 元のコンパイラでGETBYTE, PUTBYTEという関数があったが、mlisp.bでは%演算子が使用されている。 
 GETBYTE(x,y) は x%y, PUTBYTE(x,y,z) は x%y = zとなる。

[3]領域不足
 コンパイルすると「PROGRAM TOO LARGE」というエラーが出る。
 OPTIONSでL7500としている(もともと設定されていた)が足らない。L9000まで増加すればエラーは出なくなった。
 コンパイル結果を見ると TREE SIZE 8499 となっていた。
 
[4]領域不足
 コンパイルすると「TOO MANY GLOBALS」というエラーが出る。
 trn.bを見ると100に設定されている。これでは足りないようだ。

[5]ライブラリ関数不足
 NAME NOT DECLAREDが出る。RDARGS, STR2NUMB, GETVEC, FREEVECがない。
 GETVECやFREEVECもCのmallocを使いたいところであるが、
 intcodeインタプリタ方式では簡単に追加出来ない
 X(EXECUTEOPERATIONS)に割り振って、LIBHDRで名前定義して、iclib.iで連携することが必要。
 
 実はINTCODE_documentaion.pdfではX1(A:=loc(A))〜X27(output)なのに、
 icint.cではX1(A:=loc(A))〜X39(output)、さらにiclib.iではX41(REWIND)まである。
 (LIBHDRにはGLOBAL変数としてREWINDが用意されているのだが)
 
 要するにintcodeには共通規格があるわけでなく、それぞれの処理系でインタプリタと一緒に
 提供されるもののようだ。

PCの切り替え

2024-09-08 22:30:06 | 日記
普段遣いのPCではLinuxを使っているが、どうしてもWindowsでないと具合の悪いソフト(TL866のプログラムなど)があるため、ハードディスクをSSDに変え、Windows10とdebianのデユアルブートとしている。
(ハードは2022/5 中古で購入 LifeBook E742F 第3世代core i5)

しかしWindows10のサポート期限が近づきつつあるため、今回再度中古PC(Windows11あり)を購入した。
(LifeBook A577/S 第7世代core i5)

このPCも以前と同様ディスクを入れ替えてデユアルブートとすることを考えていたが、
最近のノートPCは以前ほど簡単にディスクの交換が出来ないようだ。
そもそも購入時点でSSD240GBとなっている。わざわざ大きなSSDに変えてパーティション切ってというのも大変なので、
USB接続のポータブルSSD(500GB)を試してみた。(debian-12.4.0-amd64-netinst.iso)
インストールは思ったより簡単。通常通りのインストールで書き込み先を外部SSDにするだけ。

注意点
 実は旧PCでポータブルSSDにインストールして新PCで使うように考えたが、
 「選択したデバイスから起動出来ませんでした」となり起動出来ない。
 セキュアブートの問題かと思いBIOSでOFFにしたが駄目。
 なぜか新PCでSSDにインストールすると起動出来た。逆にそのSSDを旧PCに持っていっても起動しない。
 よくわからない。

注意点2
インストールの「ソフトウエアの選択」でGNOME Flashbackを入れること。
 (昔ながらのデスクトップが良いので)

注意点3
新PCはUSB3.0であり5Gbps(3.2だと10GHz)。速度が気になったので、
 念のために、UnixBenchで確認すると、以下のようになった。
 USBの速度の問題なのか、旧PCより新PCの方が遅くなってしまった。
 まあ速度を追求しているわけではないので良いか。

   1_parallel_copy_of_tests 4_parallel_copies_of_tests
  -----------------------------------------------------------------------
  i5-3320M@2.60GHz 1153.5 2822.6
  i5-7300U@2.60GHz 1128.3 2461.4

その他
 新PCの内蔵SSDに24個も不良セクタがあった。(使用可能とはなっている)
 そのうち壊れるかも。その際は交換して内蔵USBディスクにインストールすることにしよう。

 内蔵SSDは40℃程度だが、ポータブルSSDは55℃程度。ケースを触っても熱い。
 ファンもなにも無いのだからそんなものか。壊れないかなあ。

DIPメーター

2024-09-01 13:22:25 | 日記
たまたまオークションで安価に真空管式のディップメータ(IDEAL GM-5)を入手
周波数の目盛りはなく、180度で100の目盛りになっており変換テーブルが必要
バリコンは一般的なものと違い、止まらず自由に回転する


Web上で検索したが回路図が無いので、描き起こしてみた。


内部の配線用ビニールが一部溶けていたり、半田付が十分でなかった(温度不足?)り、
ヒーターの一方がアースに落ちてなかったり、コンデンサが入っていたり、
前所有者が手を入れていたような気がする。



それ以外はほぼ標準的な回路構成

付属していたコイルは2本で巻き直した感じだが発振する。周波数は 1.2〜3.2MHz, 9.6〜25MHz
いろいろさわれそう。

テラステーションの復旧(TS3400D)

2024-07-07 16:43:45 | 日記
最近使わないディスクが増えてきた。30数年前にmac plusの外付けのハードディスクを
20MBで30万円を買ったことがある者にとっては信じられないが、最近は2TBのディスクが
1万円しなくなってきている。
サーバのデータ増加に伴いディスクを順次大きなものに交換していくと、
250GBや500GBのディスクが余ってきてしまった。

形あるものはいつかは壊れるわけで、保管しておいてもそのうち故障するのでもったいない。
そこでオークションでディスクなしのテラステーションTS3400Dを安く入手し組み込むことにした。

ありがたいことに、さまざまな人がWeb上に復旧方法を公開している。
acp-commander というものもあるらしいが、
一番簡単な方法は tftpサーバをたててテラステーションの起動時に読み込ませるもののようだ。
テラステーションは 起動時に192.168.11.150になり、192.168.11.1をアクセスしに来るらしい。

・データts3000-v208.exe をBuffaloのサイトからダウンロード
 (https://www.buffalo.jp/support/download/detail/?dl_contents_id=62016)
・tftpサービスインストール
 sudo apt install tftp-hpa
 データを展開してinitrd.buffalo と uImage.buffalo を /srv/tftpに置く。
・PCを /etc/network/interfaces で 192.168.11.1として、テラステーション起動

ところが動かない。
やむなくwiresharkで通信を見ると、どうも最初からDHCPでアドレスを要求している。すこし話が違う?

機種によって違うのかもしれないので、dhcpd導入
・isc-dhcpを導入(リースするアドレスを 192.168.11.16~32)
 sudo apt install isc-dhcp-server
 /etc/default/isc-dhcp-server, /etc/dhcp/dhcpd.conf を編集して
 systemctl restart isc-dhcp-server

テラステーションを起動したところ無事復旧した。

CP/M-68Kでbcpl

2024-06-08 13:09:50 | 日記
CP/M68Kが動き、Cコンパイラが使えるようになったことからなにか動かしたくなった。
Hello, Worldだけではもったいない。

ただこのCコンパイラは少し古い。Web上にCソースが公開されているが、今はansi準拠がほとんど。
簡単にはコンパイル出来ないため書き換える必要があるが、大掛かりなものは面倒なので小物を探す。

そこでbcplkit-0.9.7(https://www.cl.cam.ac.uk/~mr10/)を使用することにした。
これはbpclのコンパイラで、bcplソースをINTCODEと言われるコードにコンパイルし、INTCODEをインタプリタで実行するもの。
コンパイラ自身はbcplで書かれているが、コンパイルした結果のINTCODE(syn.iやtrn.i)は用意されている。

このため、INTCODEインタプリタを用意すればbcplコンパイラが動くようになる。
このINTCODEインタプリタ(icint.c)やライブラリ(blib.c)はCで書かれたものが用意されている。
icint.cは340行程度、blib.cは170行程度であり、68KのCコンパイラで動くようにするのは
比較的容易だと思われた。

ところが簡単には動かない。
とりあえず動かすところまで出来たが、動作させるまでいろいろ注意点が出たのでまとめておく。

なおSKEDエディタには大変お世話になりました。(https://piclabo.blog.ss-blog.jp/CPM68K_SKED)
懐かしいダイヤモンドカーソルのスクリーンエディタで助かりました。
CP/M 68K用のスクリーンエディタを公開したskyriverさんに感謝します。

注意点1
 bcplkit-0.9.7は当然ファイルフォーマットがunix
 改行がLFになっており、cpmtoolsを使用してSDカードに書き込んだ場合CRLFでないため表示が崩れる。
 またEOF(cZ)がないため、ファイルの最後にゴミがふくまれてしまう。
 cpmcp で オプション -t があるが、バイナリとテキストにわけでコピーする必要があるので面倒。
そこで事前にlinux上でテキストファイルだけ nkfでLF -> CRLFにする(nkf -c --overwrite ファイル)。
またファイルの最後にcZを入れた(echo -e $'\x1a' >> ファイル)

  注意 echo -e はbashの機能のようで、最初 #!/bin/sh でスクリプト組んでいたが -e$\x1a という
  文字列が最後に入ってしまった。 #!/bin/bash で意図どおり動いた。

注意点2
 CP/M 68のCコンパイラはKANSIじゃないので引数のタイプに注意。昔懐かしい書き方に変更(icint.c, blib.c)

 int main(int argc, char *argv[])
    ↓
 int main(argc, argv)
 int argc;
 char **argv;
 {

プロトタイプ宣言でも(blib.h)
int getbyte(int, int); -> long getbyte();
void putbyte(int, int, int); -> void putbyte();
void initio(void); -> void initio();

その他不要な宣言#include <stdlib.h> などを削除 (68KのCコンパイラにはない)


注意点3
 68KのCコンパイラはintが16bitだった。
 bcplkitは32bitを想定しているがソースに「#define WORDSIZE 32」とあるので、
 ここを修正すればと思っていたが、簡単ではなかった。

 blib.cの中に以下のように32bitを前提としたコードがあった。
  int
  getbyte(int s, int i)
  {
   int w = M[s + i / 4];
   int m = (i % 4) ^ 3;
   w = w >> (8 * m);
   return w & 255;
  }

 Cのコードだけなら修正すればと思っていたが、bcplで書かれたライブラリblib.bにも
 32bit前提の箇所があった。
  AND PACKSTRING(V, S) = VALOF
   $( LET N = V!0 & 255
   LET I = N/4
   FOR P = 0 TO N DO PUTBYTE(S, P, V!P)
   SWITCHON N&3 INTO
   $( CASE 0: PUTBYTE(S, N+3, 0)
   CASE 1: PUTBYTE(S, N+2, 0)
   CASE 2: PUTBYTE(S, N+1, 0)
   CASE 3: $)
   RESULTIS I $)

 bcplで書かれたライブラリは準備されているINTCODE(blib.i)に含まれているわけで、
 Cのコードだけ変えればOKとはならない。慣れないintcodeを修正も避けたい。
 仕方ないのでicint.c, blib.cのintをlongにして、32ビットで動かすことにした。

なおコンパイル用のバッチファイル c.subでコンパイルした場合、コンパイラの
中間ファイルとして拡張子が i のファイルが生成される。
(blib.cをコンパイルすると、blib.から生成されているblib.iが上書きされる)
これを防ぐため、オリジナルのblib.iはblib.orgとしておいた。
 
注意点4
pipでエラー
添付されていたmakefileを見ながら、intcodeのコンパイラをリンク
(リンカではなく、単にpipで結合するだけ)
pip st0.int=iclib.i,blib.org,syn.i,trn.i

Exception $03 at user address $000063C6. Aborted

Web上で類似の記載もあるが原因がさっぱりわからない。
pipの動作を追いかけるのは大変なので、Cでコピー用のプログラムを作成した。(concat.c)

concat st0.int iclib.i blib.org syn.i trn.i
concat cg0.int iclib.i blib.org cg.i

===concat.c=========================
#include <stdio.h>

int
main(argc, argv)
int argc;
char **argv;
{
FILE *fin, *fout, *fopen();
int i;

if (argc < 3) {
printf("Usage: %s [destfile] [srcfile].. \n", *argv);
return 1;
}

fout = fopen(argv[1], "w");
if (fout == NULL) {
fprintf(stderr, "%s: Can't open\n", argv[1]);
return 1;
}

for (i = 2; argv[i] != NULL; i++) {
fin = fopen(argv[i], "r");
if (fin == NULL) {
fprintf(stderr, "%s: Can't open\n", argv[i]);
return 1;
}
filecopy(fin, fout);
fclose(fin);
}
fclose(fout);
return 0;
}

filecopy(fin, fout)
FILE *fin, *fout;
{
int c;

while ((c = getc(fin)) != EOF)
putc(c, fout);
}
==============

注意点5
 icint.c のコンパイル中に以下の警告が出る
 (warning) more than 32767 bytes of local variables
 ローカルでは駄目みたいなので、pgvec[VSIZE]をグローバルにした。

注意点6
 68KのCコンパイラのバグ
 icint.cインタプリタのデバッグ中に、条件分岐がおかしいことに気づいた

 以下の部分(4の場合はAがtrue(0以外)の場合に分岐、5の場合はAがfalse(0)の場合に分岐)
 case 4: A = !A;
 case 5: if (!A) C = D; goto fetch;

やむなく68K Cで簡単なテストコードをコンパイルし途中のアセンブリコードを見ると以下のとおり。
 「!」ではfalse(0)の場合は1をセットし、それ以外の場合は0をセット(clr)するようなコードであるが、
 <---に示すように、longの場合は clr.l にすべきところが clrになっている。

C>type test.c
main()
{
int x;
long y;

x = 0xffff;
x = !x;
y = 0xffffffff;
y = !y;
}

C>type test.s
.globl _main
.text
_main:
~~main:
~_EnD__=8
link R14,#-10
~x=-2
~y=-6
*line 6
move #-1,-2(R14)
*line 7
move -2(R14),R0
beq L10000
clr R0 <--- 16bitの場合、16bitクリア
bra L10001
L10000:move #1,R0
L10001:move R0,-2(R14)
*line 8
move.l #$ffffffff,-6(R14)
*line 9
move.l -6(R14),R0
beq L10002
clr R0 <--- 32bitの場合も、16bitクリア clr.lにすべき
bra L10003
L10002:move #1,R0
L10003:move.l R0,-6(R14)
L1:
unlk R14
rts
.data

 仕方ないので、cのソースを以下のように変更した。この方がソースも素直だよなあ。
  case 4: if (A) C = D; goto fetch;
  case 5: if (!A) C = D; goto fetch;

以上でcmpltest.bをコンパイルし、エラーなく実行出来た。

C>ICINT ST0.INT <CMPLTEST.B
INTCODE SYSTEM ENTERED

PROGRAM SIZE = 9756

BCPL 2
OPTIONS L7500

TREE SIZE 4772

PHASE 1 COMPLETE

EXECUTION CYCLES = 1264094, CODE = 0

C>ICINT CG0.INT <OCODE
INTCODE SYSTEM ENTERED

PROGRAM SIZE =" "3317

PROGRAM" LENGTH =" "1840

EXECUTION" CYCLES =" "977419," CODE =" "0

C">CONCAT CMPLTEST.INT ICLIB.I BLIB.ORG INTCODE

C>icint cmpltest.int


INTCODE SYSTEM ENTERED

PROGRAM SIZE = 2539

CGTESTER ENTERED

1 33 OK
2 303 OK
3 3 OK
4 44 OK
5 -1 OK
6 0 OK
7 1 OK
8 11 OK
9 101 OK
10 5 OK
11 15 OK
12 105 OK
13 1234 OK
14 5678 OK
15 75 OK
16 433 OK
17 150 OK
18 50 OK
19 3 OK
20 -3 OK
21 -3 OK
22 3 OK
23 2 OK
24 1 OK
25 26 OK
26 1 OK
27 5 OK
28 0 OK
29 -105 OK
30 -1 OK
31 0 OK
32 0 OK
33 -1 OK
34 0 OK
35 -1 OK
36 8168 OK
37 127 OK
38 8168 OK
39 127 OK
40 8 OK
41 14 OK
42 25 OK
43 6 OK
44 0 OK
45 -1 OK
46 -5171 OK
47 -105 OK
48 1000 OK
49 1000 OK
50 1234 OK
51 5678 OK
52 10000 OK
53 10000 OK
54 10000 OK
55 10001 OK
56 10001 OK
57 10200 OK
58 16 OK
59 16 OK
60 11 OK
101 -5 OK
102 -2 OK
103 105 OK
104 11 OK
105 15 OK
106 15 OK
107 16 OK
108 15 OK
109 22 OK
110 0 OK
111 15 OK
112 120 OK
201 0 OK
202 0 OK
203 369528 OK
204 385136 OK
251 21 OK
252 1 OK
253 2 OK
254 3 OK
255 4 OK
256 5 OK
257 6 OK
258 21 OK
259 21 OK
260 21 OK
261 2 OK
262 4 OK
263 6 OK
264 21 OK
265 2 OK
266 5 OK
267 21 OK
268 33400 OK
269 6 OK
270 21 OK
301 116 OK
302 116 OK
303 116 OK
304 1 OK
305 99 OK
306 21 OK
307 32 OK
308 41 OK
309 51 OK
401 0 OK
402 1 OK
403 2 OK
404 1 OK
405 102 OK
406 12 OK
407 11 OK
408 101 OK
409 102 OK
410 103 OK
411 103 OK
412 123 OK
413 123 OK
414 123 OK

119 TESTS COMPLETED, 0 FAILURE(S)

EXECUTION CYCLES = 101599, CODE = 0