パソコン活用研究ラピュタへの道(アセンブラ、DOS、Windows、旧型PCの活用研究)

PClist解説 (CASET-V、Pcreadも含む) 
FM8とPC2001をカセットテープインターフェイスを使ってつなぎデータ通信する
プロジェクトについて
はじめに
  今を去ること15年以上になりますが、FM8という8ビットのパソコンがありました。  
もう、とても現役でつかえるものではありませんが、FM8上で組んだBASIC,アセンブラ
FORTRAN,PASCAL,LISP等のプログラムが結構ありました。せっかくだから、
ソースファイルだけでも参考までに、Windows機に落としておこうか、ということで
RS232Cを介してソースファイルの転送を進めてきました。このたび、大半のソースファイル
を転送終了いたしましたが、その中にPC2001とFM8をカセットインターフェイスを使って
つなぐという、ちょっと世間に例のないレアモノがでてきましたので、まとめてみました。
これは、昭和60年頃、筆者の行った、PC2001−FM8をカセットインターフェイス
でつないでデータ交換をするというかなり珍しいプロジェクトについて、あらためてまとめた
ものです。最終的にPC2001のプログラムをFM8で読み込ませるためのプログラムは
PClist  ですが、それを完成させるその途上で作成したCASET-V、PCread にも必要に応じて
触れます。
  当原稿は昭和60年当時に、パソコン雑誌に投稿していれば、ほんの少しは世間の人々の
お役にたったかもしれませんが、今では、ほとんどの人にとってこの原稿は直接的には、まったく
と言っていいほど役にたたないものであることを、あらかじめお断りしておきます。
自動車に例えてていうならば、今時キャブレターの調整についてうんぬんするぐらい、時代遅れ
の話です。
  本原稿をまとめてみようというのも、ほとんど筆者のノスタルジーによるものです。ただ、   
パソコンのハードウエアの直接制御(とは言ってもごく単純なものですが)、保存デバイスメディア)のフォーマットBASICの中間コード浮動少数点の2進法表記などといった
ことにも軽く平易に触れてみましたので、パソコン内部でなにをやっているのか少し知りたい
という人には、もしかもすると多少面白い個所もあるかもしれません。
(中、上級者にはたいくつな話だとおもいますが。)
なにせ古いマシンなので、今のマシンより単純にできており、パソコン内部の話をするには
分かりやすいと思います。もちろん、今のパソコンのシステムはずっと複雑になっておりますが、
パソコンがブラックボックスの中で何をどんな風処理しているのか、なんとなく分かっていただ
けるものと思います。また、自分で自分専用のプログラムを作ることの面白さに気づく人もある
かもしれません。 筆者としては、これを見てパソコンで自分でプログラムする過程でどんな
ことをするのか少しでも理解していただければと思います。
  なお、FM8以外にPC2001やPC98等でさくせいしてきたプログラムも順次
Windows機に転送中です。それらの、一部はVISUAL BASIC、QBASIC, Windows上
で動くN88互換BASIC用に移植検討中です。Windows上で動くN88互換BASIC(old Basic)に
ついては、最近市販の製品もありますが、潮田氏によるフリーソフトもありますので、
興味ある方はダウンロードしてみて下さい。NIFTYのFGALAPのライブラリー(教育)
に登録されてます。また、ベクターのサイトhttp://www.vector.co.jp/からもダウンロードできます。
  また、最初に述べたRS232Cでのファイル転送については、拙著「RS232Cプロジェクト」
にまとめましたので、シリアルデータ転送について手っ取り早く概要を知りたい人は参考に
して下さい。
1  カセットインターフェイス
  今は昔(今では昔の話となってしまったが)。パソコンでデータの保存、入力というと、
カセットテープ(以下CTと略す)に行っていました。このカセットを使ってのデータの保存、
入力はまったく困た代物でした。何が困ったか、主な点をあげれば以下の通りです。
@スピードがめちゃ遅い。
今時はFD(フロッピーディスク)もめちゃ遅で使えないものの代表になっていますが、当時
CT全盛時にはFDが神様にみえたものです。だいたいCTのアクセススピードは機種により
多少違いはありましたが、1200bps(Bit Per Second)でした。すなわち1秒に1200ビット。
とは、つまりだいたい1秒に120バイト(スタートビット、ストップビットが加わる
ため、大体10ビットで1バイトデータになる)。これがどれくらい遅いか分かるでしょうか。
今は、ちょっとした文書をWORDで作成してもすぐに30Kバイトぐらいになってしまいま
すが、これをCTに保存しようとすると、30000÷120=250。すなわち4分以上も
かかってしまう分けです。では仮にWORDを起動しようとした場合はどうでしょうか。
WORD本体は約4.5Mバイトですから、4500000÷120=38000。これはなん
と630分です。CTの使えなさ加減がおわかりいただけたでしょうか。
  
Aシーケンシャルファイルである。
データをCTから読み込む場合。目的のファイルにたどりつくまで、頭からえんえんと探して
いかねばなりません。仮に60分テープの最後の方に目的のファイルがあり、先頭から探して
いったら、60分まるまる無駄な時間になってしまうわけです。
さて、作成したデータを保存する場合、これも厄介です。既に、他のデータの保存されている
テープを使用する場合、最後のデータがどこまで記録されているかチェックしてからでないと、
前のデータを壊してしまいます。最後のデータの記録位置をしらべるには、結局もう一度テープ
を回してやらねばならないので、この面倒くささといったら筆舌に尽くし難いものがあります。
Bエラーがでやすい。
途中で、データの読み取りにエラーが生じると、パソコンは恐怖の‘Device I/O Error’
(データ入出力のエラー)を表示して止ってしまいます。すると、もう一度テープをまき戻して
最初からやり直しとなるわけです。20分も30分もかけてようやく途中まで読み込んだと思ったら、
くだんのエラー。この ’Device I/O Error’が当時どんなに恐怖であったか、容易に想像
できると思います。それはもう、針が落ちても分かるくらいテープレコーダのモーターの回転音に
全神経を集中させ、息をひそめて手に汗にぎって、パソコンの画面をひたすら祈りながら見ていた
ものです。
  このエラーの原因としては、テープの伸び、テープレコーダーのモーターの回転むら、そして
時には、電子レンジ、エアコンのスイッチオン、冷蔵庫の霜とり開始などによる瞬間的な電圧の
変化などがありますが、かなりの頻度でこのエラーがでたものです。
C機種間のフォーマットがまったく違う
カセットテープのフォーマットには、とくにスタンダードなものがなく機種間でばらばらでした。
従って、他機種でフォーマットしたテープのデータは読めず、この点もまた不便なものでした。
2 超マイナー機種PC2001の悲哀
  NECは時々、従来のラインナップとかけはなれた、(よく言えば)斬新なアイデアを盛り込ん
だ、一般的に言えば超マイナーな製品を出すメーカーです。(そして、マイナー機種は決して
フォローされることがない)PC2001はそんな製品の一つで、当時としては40*2という
表示画面をもった斬新なポケコンでした。斬新なゆえに、その後フォローされることはなく、
CPUやハードウエアについての技術資料が公開されることもなく、各種専用の付属品もすぐに
製造中止となりました。当時は、アマチュアのパソコン専門紙への投稿が盛んであった時代で、
紙面は各機種の内部ROM解析とか、XXXの活用研究とかでにぎわっていました。しかし、
PC2001についての投稿は数えるほどしかなく、日本国民全体から見捨てられたマイナー
機種でした。この時程、マイナー機種の悲哀を感じたことはありません。それ以後、筆者の座右の
銘は、メジャーな機種、世界標準の製品を買うべし、になりました。
  さて、PC2001はポケコンなので、データの保存、入力はカセットインターフェイスしか
使えませんでした(当時としては当然の仕様です)。しかし、1 で書いたようにカセットへの
保存、入力はとてもまとまな神経の持ち主の使用にたえるものではありません。そこで、FM8
とつなげて、FM8のFDにデータの保存、そして入力をさせるというプロジェクトを敢行する
ことにいたしました。FM8とつなげるには、それぞれのシリアルインターフェイスをRS232C
でつなぐというのが、一般的なやり方です。しかし、どちらの機種もシリアルインターフェイス
のコネクタの形状が標準のものとはまったく異なり、市販のケーブルではつなげません。さりとて、
ケーブルを自作して、各インターフェイスの仕様を研究してというのも、なんか面倒だったので、
そして、なによりPC2001ごときに1円たりとも新たに投資をしたくなかったので、オーディオ
カッセトインターフェイスを使ってつなげるという、おそらく他にあまり前例のないプロジェクト
を思い立ちました。これなら、投資金額は0円。結局カセットインターフェイスを使うので、スピード
の改善にはなりませんが、目的のファイルにランダムアクセス可能、エラーもでなくなる(だろう)
データを他機種でも利用可能ということで、上述の問題点A、B、Cが解決できるわけです。
つまり、どういうことかというと下図のようにつなげて、FM8のFDにデータ、プログラムを
保存し、そこから入力しようということです。
                  [  ラジカセ ]
PC2001===マイク端子
                       イヤホン端子===FM8==FD
まず第一段として、PC2001のBASIC programをFM8のFDに保存するという
プロジェクトにかかりました。
3 フォーマットの探索、CASET-V
  まずは、PC2001のテープのフォーマットについて調べなくてはなりませんが、これについて
言及している文献、技術資料がみあたらず、まったく独力で調べることにしました。
(1) FM8のハードウエアについて
  FM8のCPUは6809というタイプでメモリーマップドI/Oとよばれる方式をとります。これは、
通常のメモリーにI/Oポートが直接わりふらる方式です。FM8の場合メモリー上の&HFD02の
ビット7がカセットインターフェイスの入力につながっています。カセットインターフェイスの入力信号
(電圧)がHigh(Hと略す)のとき&HFD02のビット7はセット(1になる)、Low(Lと略す)
の時は、リセット(0になる)になるようになっています。従ってこの&HFD02のビット7を調べて
やれば、なにか分かるわけです。
(*)&Hをつけた数字は16進数です
(2) CASET-V、テープフォーマット解析
  とりあえず、ひたすらカセットインターフェースからの入力信号(&HFD02のビット7)をチェック
し、信号がHレベルなら*、Lレベルなら・を表示するプログラム「CASET-V」を作成。
CASET-Vの詳細については説明しませんが、カセットインターフェイスからの入力信号のチェック
の部分は機械語で作成し、高速化してます。(CASET-Vのソースリストは下記リスト参照)
PC2001のプログラムをCASET-Vで記録したもの(例)
***・・・***・・・***・・・***・・・***・・・***・・・***・・・***・・・
******・・・・・・******・・・***・・・***・・・***・・・***・・・
***・・・***・・・***・・・***・・・******・・・・・・******・・・・・・
PC2001のプログラムを記録したテープをCASET-Vで読み込ませて、解析したところ、
上記のようなデータがとれました。あとは、これを睨んでテープフォーマツトの推定をおこないま
した。最初、まったくわけがわからず、あきらめかけましたが、飯を食いながらも考え続け、睨む事
数時間、PC2001のテープのフォーマットが見えてきました。
PC2001のテープフォーマット
・・・***・・・***・・・***・・・***     
この短いサイクル(2400Hz)でのHレベルとLレベルの8サイクルの繰り返しは
ビットがセット(1)をあらわしています
・・・******・・・・・・******・・・
この長いサイクル(1200Hz)での4サイクルの繰り返しはビットがリセット(0)を
あらわしています。
1バイトのデータの構造
スタートビット 0が1ビット(これからデータが始まるという合図のためのビット)
データビット   8ビット
ストップビット 1が4ビット(データ終了の合図)
たとえば&H13(00010011)は以下のようになっています
0000100111111
| データビット   |−−−−>ストップビット(4ビット分)
|
|−−−>スタートビット
(*)1バイト(=8ビット)のデータをシリアルデータ転送する場合、だいたい
       スタートビット + データ + ストップビット という形をとる。

CASET-Vソースリスト
5 CLEAR,&H1E00:CLS:WIDTH80,20
7 COLOR4:PRINT"**** CASET DATA ANALIZER ****"
10 RESTORE30
15 FOR T=&H1F00 TO&H1F25
20 READ Q$:POKE T,VAL("&H"+Q$)
25 NEXT
30 DATA34,36,8E,20,00,10,BE,1F,30,78,FD,02,25,FB,C6,8,78,FD,02,66,84,86,C,4A,26,FD,5A,26,F3,30,01,31,3F,26,EB,35,36,39
35 INPUT"END ADRESS",E
40 IF E<&H2000 OR E>&H7000 THEN 35
50 POKE &H1F30,E\256:POKE&H1F31,E MOD 256
60 MOTOR ON:EXEC&H1F00
70 MOTOR OFF
80 INPUT"Hardcopy OR Dump OR Grafic OR End",S$
85 IF S$="G" THEN200
90 IF S$="E" THENEND
95 IF S$="H" THEN HARDC0
100 IF S$="D" THEN 110 ELSE80
110 INPUT"Adress",A
120 FOR I=0 TO15
130 PRINT HEX$(A+I*16)+" :";
140 FOR J=0 TO15
150 PRINT RIGHT$("0"+HEX$(PEEK(A+J+I*16)),2)+" ";
160 NEXT
170 PRINT
180 NEXT I
190 GOTO80
200 INPUT"Adress",A
202 FOR X=0 TO79:IF (X MOD 8)=0 THEN PRINT"<"; ELSEIF (X MOD 8)=7 THEN  PRINT">";ELSE PRINT" ";
204 NEXT
210 FOR K=0 TO169
220 P=PEEK(A+K)
240 FOR V=0 TO7
250 G(V)=P MOD 2
260 P=(P-G(V))/2
270 NEXT
280 FOR N=0 TO7
290 IF G(N)=1 THEN PRINT"*"; ELSE PRINT"・";
300 NEXT
310 NEXT K
320 GOTO80
4  PC2001中間コードの解析、PCread
(1)中間コードについて
BASIC(インタープリタ)のプログラムは、どのようにメモリに格納されているのでしょうか。
例えば   
10 GOTO 15  '行番号15に飛ぶ
というプログラムはそのままメモリーに格納されている
のではなく中間コードという1、または2バイトのバイナリデータに変換されてメモリーに
格納されます。(中間コードはCPUが直接理解できる機械語とはまた違ったものです。)
例えば下のプログラムは以下のように格納されます。
10 GOTO 15
中間コード(PC2001の場合&HE000から格納されます)
(番地)  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
&HE000    00  0A  E0  0A  00  89  0D  09  E0  
              
&HE001,&HE002の&H0A,&HE0はリンクポインタといい、次の行番号のリンクポインタをさしています
&HE003,&HE004の&H0A(=10),&H00は行番号10をあらわしてます。
&HE005の&H89は GOTOの中間コードです。
PC2001のBASICの命令の中間コードの例
LOCATE &HD5
PRINT  &H91
INPUT  &H85
(2) PC2001中間コード解析とテープのヘッダー部解析
PC2001のテープフォーマットがわかったので、次に中間コード解析のために、PC2001
のテープをデータとして読みこむためのプログラムを作成しました。これがPCreadです。
テープの読み込み、バイナリデータとしてメモリーへ格納する部分はPCreadmという
機械語プログラムでやっています。以下、簡単にPC2001のテープのヘーダー部について
説明します。
テープヘッダー部
&HD3が10個続いたあと、プログラム名が続き、その後、プログラム本体が入っています。
例えば'grbel'というプログラムは以下のようにテープに記録されています
0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
D3  D3  D3  D3  D3  D3  D3  D3  D3  D3  67  72  62  65  6C  00
テープヘッダー                          g   r   b   e   l    
0C  E0  ・・・・・・・・・・・
リンクポインタ(BASICプログラム本体)
中間コードの詳細については省略します。
PCreadとPCreadmのソースリストを以下に記載します。
PCread ソースコード
5 CLEAR,&HFFF:IF PEEK(&H6000)<>&H39 THEN LOADM"PCREADM"
10 CLS:PRINT" PC 2001 TAPE READER"
20 POKE &H313,0
30 MOTOR ON
40 FOR I=0 TO10:NEXT
50 EXEC&H6001
60 MOTOR OFF
PCreadm ソースコード (6809アセンブラ用)        
5 ' NAM                              
10 ' ORG $6000                       
20 'L1 RTS                                               
30 ' LDU #$1000
40 'START LDY #0
50 'L2 TST >$313
60 ' BNE L1
70 ' LBSR DIN
80 ' BNE L2
90 'L3 LBSR EDG
100 ' LDX #$19
110 ' LBSR TIME
120 ' BSR DIN
130 ' BEQ L2
140 ' LEAY 1,Y
150 ' CMPY #2
160 ' BNE L2
170 ' LEAU 1,U
180 ' LDY #0
190 'L10 LDA #4
200 'L11 TST >$313
210 ' BNE L1
220 ' LDB >$FD02
230 ' ANDB #$80
240 ' BNE L11
250 ' BSR EDG
260 ' LDX #$19
270 ' BSR TIME
280 ' BSR DIN
290 ' BEQ ZERO
300 ' INCA
310 ' BRA L4
320 'ZERO DECA
330 'L4 CMPA #6
340 ' BEQ ZER1
350 ' CMPA #0
360 ' BEQ ON1
370 ' BRA L11
380 'ZER1 ANDCC #$FE
390 ' BRA L6
400 'ON1 ORCC #1
410 'L6 ROR ,U
420 ' LEAY 1,Y
430 ' CMPY #8
440 ' BEQ STOP
450 ' BRA L10
460 'STOP LDY #0
470 'L30 TST >$313
480 ' BNE L1
490 ' LDB >$FD02
500 ' ANDB #$80
510 ' BNE L30
520 ' BSR EDG
530 ' LDX #$19
540 ' BSR TIME
550 ' BSR DIN
560 ' BNE L30
570 ' LEAY 1,Y
580 ' CMPY #16
590 ' BLO L30
600 ' CMPU #$5FFF
610 ' LBLO START
620 ' RTS
630 'DIN LDB >$FD02
640 ' ANDB #$80
650 ' RTS
660 'EDG LDB >$FD02
670 ' ANDB #$80
680 ' CMPB #$80
690 ' BNE EDG
700 ' LDB >$FD02
710 ' ANDB #$80
720 ' CMPB #$80
730 ' BNE EDG
740 ' RTS
750 'TIME LEAX -1,X
760 ' CMPX #0
770 ' BNE TIME
780 ' RTS
790 ' END
5  中間コード−−−>ASCIIセーブ形式変換 、 PCLIST
(1)ASCIIセーブ形式
  ASCIIセーブ形式とは、いわゆるTXT(てきすと)ファイルといってもよいものです。
中間コードのままではプログラムの内容がようくわからないので、中間コードからASCII
セーブ形式 (10 GOTO 15  のようにいわゆるテキストのソースコードの形)に変換
するプログラムを作成することにしました。上述のPCreadでPC2001のBASIC
の全命令を含んだプログラムを読み込み、解析し、中間コード−−>ASCIIセーブ形式変換
プログラムを作成しました。これが、PCLISTです。PC2001のプログラムを読み込み、
アスキーセーブ形式に変換し、ディスクに保存、プリンターに出力等を行います。
  PC2001のプログラムはカセットテープに保存したものを読み込ませても良いし、テープ
レコーダーを下記のように結線して、PC2001でSAVEコマンドでメモリー上のプログラム
を直接FM8に送ることも可能です。これで、とりあえずPC2001のBASICプログラムを
FM8のFDに保存させることが可能となりました。
  ほとんど、参考になる技術資料がないまま、いちから力技で解析してようやくここまできました。
まったく何も分からないところから、暗号解読のような作業を繰り返してきました。大変だった分
楽しかったともいえます。
                
                 [  ラジカセ ]
PC2001===マイク端子
                       イヤホン端子===FM8==FD
  なお、逆にFM8のFDから保存したPC2001のプログラムを読み込んで、PC2001に送る
ことも可能でしたが、これについてはやりませんでした。
  PCLISTも、カセットインターフェイスの信号入力、ヘッダー、終了部判定等は機械語でやって
います。機械語の部分は上述のPCreadmを拡張したものです。とりあえず、PCLISTのソース
プログラムのみ最後に掲載しておきます。
(2) 浮動小数点
  コンピュターは2進法(バイト単位で考えれば16進数)なので、少数を扱うと、少々話は
ややこしくなります。整数だけなら、10進数と2進数の変換は比較的楽ですが、少数がからんで
くるとどうなるでしょうか。例えば、1.25(10進数)を2進数であらわすと、1.01になり
ます。3.75(10進数)は11.11になります。
  さて、PC2001のBASICは少数を扱うのにどうやっているのでしょうか。これがわから
ないと、PC2001中間コードから正しく少数を変換できません。PCLIST作成にあたって
一番面倒だったのがこの少数の扱いです。
  PC2001ではいわゆる浮動小数点方式というやり方で少数を扱っています。PC2001
では、少数を含む場合、7けたまでが有効となる単精度変数となりますが、これはメモリー上
5バイトのデータとなります。試しに、いくつかの数値が中間コードではどうなっているか例を
あげます。
10進数  中間コード          F(2)     F(1)      F(0)      F0  
0.25                 1D     00       00        00        7F
0.5                  1D     00       00        00        80
0.75                 1D     00       00        40        80
1.0                  1D     00       00        00        81
1.25                 1D     00       00        20        81
  
  最初の&H1Dは少数を示す中間コードです。以下の4バイトがデータです。最後のF0の
データは指数部です。F0の値から&H80を引いた数が2の指数になります。例えば0.25
の場合、F0の値は&H7Fですから、&H7F-&H80=-1が指数になります。すなわち、
この場合では、2^-1 (2の−1乗)ということです。
  F(2)からF(0)までのデータ部については、実際はF(0)が最上位の桁、F(3)が
最下位の桁になります。そして、F(0)の値に自動的に&H80を加えることになっています。
最上位桁のF(0)の場合、&H80を加えたあと2^-8(2の−8乗)をかけます。
すなわち、計算法式としては  
(F(0)の値+&H80)*(2^-8)* 2^(F0の値-&H80)
ということになります。
0.25の例でいくと、
(0+&H80)*(2^-8)*(2^-1)=(2^7)*(2^-8)*(2^-1)=2^-2 =0.25
となります。
1.0の例では
(0+&H80)*(2^-8)*(2^1)=2^0 =1
というわけです。
  頭がこんがらがってきそうですが、結構面倒な手順をふんでいます。PCLISTでは1400行
から1440行で浮動小数点の処理をしていますので、興味ある人は見て下さい。
 

PCLIST
10 CLEAR,&H3FFF
20 WIDTH40,20:CLS:PRINT"PC2001 LIST V1.5":PRINT"Lpt0: or SCRN:"
25 A$=INPUT$(1)
30 IF A$="L" THEN B$="LPT0:":C=13 ELSEIF A$="S" THEN  B$="SCRN:":C=13ELSE25
35 IF PEEK(&H60C1)<>&H40 THEN LOADM"PCTAPE"
36 FOR M=0 TO100:NEXT:POKE&HFD1D,0
38 POKE&H60E8,&H40
40 POKE&H60C1,&H40:EXEC&H60BD
45 OPEN"O",#1,B$
50 I=0:N=0:N1=0:E=0:Y=0
60 I=I+1:D=PEEK(&H4000+I)
70 IF N=0 THEN80 ELSE120
80 IF D=&HD3 THENY=Y+1
85 IF Y=>8 THEN88ELSE60
88 IF D<>&HD3 THEN 90ELSE60
90 N1=N1+1:PRINT#1,CHR$(D);
100 IF N1=6 THEN Q=I:N=1:PRINT#1,CHR$(C):A=PEEK(&H4000+I+1)+PEEK(&H4000+I+2)*256-&HE000+Q:G=PEEK(&H4000+I+3)+PEEK(&H4000+I+4)*256:PRINT#1,G;:I=I+4
110 GOTO60
120 IF I=A THEN A=PEEK(&H4000+I)+PEEK(&H4000+I+1)*256-&HE000+Q:G=PEEK(&H4000+I+2)+PEEK(&H4000+I+3)*256:PRINT#1,CHR$(C):PRINT#1,G;:I=I+3:GOTO60
130 IF D=0 THEN E=E+1:IF E>=6 THEN CLOSE#1:END ELSE60 ELSE E=0
140 IF D=&H81 THEN PRINT#1,"END";:GOTO60
150 IF D=&H82 THEN PRINT#1,"FOR";:GOTO60
160 IF D=&H83 THEN PRINT#1,"NEXT";:GOTO60
170 IF D=&H84 THEN PRINT#1,"DATA";:GOSUB1000:GOTO60
180 IF D=&H85 THEN PRINT#1,"INPUT";:GOTO60
190 IF D=&H86 THEN PRINT#1,"DIM";:GOTO60
200 IF D=&H87 THEN PRINT#1,"READ";:GOTO60
210 IF D=&H89 THEN PRINT#1,"GOTO";:GOTO60
215 IF D=&H8B THEN PRINT#1,"IF";:GOTO60
216 IF D=&H8C THEN PRINT#1,"RESTORE";:GOTO60
220 IF D=&H8D THEN PRINT#1,"GOSUB";:GOTO60
230 IF D=&H8E THEN PRINT#1,"RETURN";:GOTO60
240 IF D=&H8F THEN PRINT#1,"REM";:GOSUB1000:GOTO60
250 IF D=&H91 THEN PRINT#1,"PRINT";:GOTO60
260 IF D=&H95 THEN PRINT#1,"ON";:GOTO60
262 IF D=&HAC THEN PRINT#1,"DEFINT";:GOTO60
265 IF D=&H96 THEN PRINT#1,"WAIT";:GOTO60
266 IF D=&H97 THEN PRINT#1,"DEF";:GOTO60
268 IF D=&HBE THEN PRINT#1,"PAUSE";:GOTO60
270 IF D=&H98 THEN PRINT#1,"POKE";:GOTO60
275 IF D=&HA1 THEN PRINT#1,"ELSE";:GOTO60
276 IF D=&HAB THEN PRINT#1,"DEFSTR";:GOTO60
277 IF D=&HAD THEN PRINT#1,"DEFSNG";:GOTO60
280 IF D=&H9F THEN PRINT#1,"CONSOLE";:GOTO60
290 IF D=&HB2 THEN PRINT#1,"BEEP";:GOTO60
300 IF D=&HBB THEN PRINT#1,"RANDOMIZE";:GOTO60
310 IF D=&HD5 THEN PRINT#1,"LOCATE";:GOTO60
320 IF D=&HD8 THEN PRINT#1,"THEN";:GOTO60
330 IF D=&HDA THEN PRINT#1,"STEP";:GOTO60
335 IF D=&HDC THEN PRINT#1,"FN";:GOTO60
340 IF D=&HD7 THEN PRINT#1,"TO";:GOTO60
345 IF D=&HDE THEN PRINT#1,"NOT";:GOTO60
350 IF D=&HE9 THEN PRINT#1,"INKEY$";:GOTO60
360 IF D=&HEA THEN PRINT#1,"TIME$";:GOTO60
370 IF D=&HEB THEN PRINT#1,"DATE$";:GOTO60
380 IF D>=&H11 AND D<=&H1A THEN D=D-17:PRINT#1,D;:GOTO60
390 IF D=&H22 THEN PRINT#1,CHR$(D);:GOSUB1030:GOTO60
400 IF D=&HF THEN I=I+1:D=PEEK(&H4000+I):PRINT#1,D;:GOTO60
410 IF D=&HE OR D=&H1C THEN D=PEEK(&H4000+I+1)+PEEK(&H4000+I+2)*256:PRINT#1,D;:I=I+2:GOTO60
420 IF D=&HFF THEN GOSUB1060:GOTO60
425 IF D=&H1D THEN GOSUB1400:GOTO60
430 IF D=&HC THEN PRINT#1,"&H";:D=PEEK(&H4000+I+1)+PEEK(&H4000+I+2)*256:PRINT#1,HEX$(D);:I=I+2:GOTO60
440 IF D=&HF0 THEN PRINT#1,">";:GOTO60
450 IF D=&HF1 THEN PRINT#1,"=";:GOTO60
460 IF D=&HF2 THEN PRINT#1,"<";:GOTO60
470 IF D=&HF3 THEN PRINT#1,"+";:GOTO60
480 IF D=&HF4 THEN PRINT#1,"-";:GOTO60
490 IF D=&HF6 THEN PRINT#1,"/";:GOTO60
500 IF D=&HF5 THEN PRINT#1,"*";:GOTO60
510 IF D=&HF9 THEN PRINT#1,"OR";:GOTO60
520 IF D=&HF8 THEN PRINT#1,"AND";:GOTO60
530 IF D=&HF7 THEN PRINT#1,"^";:GOTO60
540 IF D=&HFA THEN PRINT#1,"XOR";:GOTO60
550 IF D=&HFD THEN PRINT#1,"MOD";:GOTO60
560 IF D=&HFE THEN PRINT#1,"\";:GOTO60
900 IF D>=&H20 THEN PRINT#1,CHR$(D);:GOTO60 ELSE60
1000 I=I+1:D=PEEK(&H4000+I)
1010 IF D=&H3A OR D=0 THEN PRINT#1,CHR$(D);:RETURN
1020 PRINT#1,CHR$(D);:GOTO1000
1030 I=I+1:D=PEEK(&H4000+I)
1040 IF D=&H22 THEN PRINT#1,CHR$(D);:RETURN
1050 PRINT#1,CHR$(D);:GOTO1030
1060 I=I+1:D=PEEK(&H4000+I)
1070 IF D=&H81 THEN PRINT#1,"LEFT$";:RETURN
1080 IF D=&H82 THEN PRINT#1,"RIGHT$";:RETURN
1090 IF D=&H83 THEN PRINT#1,"MID$";:RETURN
1100 IF D=&H84 THEN PRINT#1,"SGN";:RETURN
1110 IF D=&H85 THEN PRINT#1,"INT";:RETURN
1120 IF D=&H86 THEN PRINT#1,"ABS";:RETURN
1130 IF D=&H87 THEN PRINT#1,"SQR";:RETURN
1140 IF D=&H88 THEN PRINT#1,"RND";:RETURN
1150 IF D=&H89 THEN PRINT#1,"SIN";:RETURN
1160 IF D=&H8A THEN PRINT#1,"LOG";:RETURN
1170 IF D=&H8B THENPRINT#1,"EXP";:RETURN
1180 IF D=&H8C THEN PRINT#1,"COS";:RETURN
1190 IF D=&H8D THENPRINT#1,"TAN";:RETURN
1200 IF D=&H8E THEN PRINT#1,"ATN";:RETURN
1210 IF D=&H92 THEN PRINT#1,"LEN";:RETURN
1220 IF D=&H93 THEN PRINT#1,"STR$";:RETURN
1230 IF D=&H94 THEN PRINT#1,"VAL";:RETURN
1240 IF D=&H95 THEN PRINT#1,"ASC";:RETURN
1250 IF D=&H96 THENPRINT#1,"CHR$";:RETURN
1260 IF D=&H97 THEN PRINT#1,"PEEK";:RETURN
1270 IF D=&H99 THEN PRINT#1,"OCT$";:RETURN
1280 IF D=&H9A THEN PRINT#1,"HEX$";:RETURN
1290 IF D=&HA2 THEN PRINT#1,"FIX$";:RETURN
1300 RETURN
1400 F=0:F0=PEEK(&H4000+I+4)-&H80:F(0)=PEEK(&H4000+I+3)+&H80:F(1)=PEEK(&H4000+I+2):F(2)=PEEK(&H4000+I+1)
1410 FOR J=0 TO2
1420 F=F+(F(J)AND&H80)*2^(F0-J*8-8)+(F(J)AND&H40)*2^(F0-8-J*8)+(F(J)AND&H20)*2^(F0-8-J*8)+(F(J)AND&H10)*2^(F0-8-J*8)+(F(J)AND8)*2^(F0-8-J*8)+(F(J)AND4)*2^(F0-8-J*8)+(F(J)AND2)*2^(F0-8-J*8)+(F(J)AND1)*2^(F0-8-J*8)
1430 NEXT
1440 I=I+4:PRINT#1,F;:RETURN

TopPage

inserted by FC2 system