メモリ内容SAVE & LOAD実験

 VX-7のメモリ内容をパソコンで編集するためには、"クローン機能"でやりとりされるデータ(=クローンデータ)をパソコンで読み書きできることが必須の条件である。そこで、第一段階として、クローンデータをパソコンに保存し、再びVX-7に書き込む実験をすることにした。

インターフェース

 VX-7とパソコン(RS-232-C)を接続するには、インターフェースが必要である。
 このインターフェースについては、現時点(2002年11月)では市販されていないが、VX-1/VX-5用のものがそのまま流用できることは容易に想像できたので、VX-1でのメモリデータ読み出し/書き込み実験に使った自作品をそのまま流用した。(しかし、本当にこれでいいのか、つまり、VX-7を破壊しないのかは、今のところわからない!)

 VX-1の場合と同じく、マイクアダプタ(CT-91)を介して、VX-7とインターフェースを接続する。接続の様子は、下の写真を参考にしていただきたい。なお、このインターフェースは、VX7 Commanderでも使用可能であった。(ただし、動作を保証するものではない。)

 
 
 
 
インターフェースの回路について

 VX-7とパソコン(RS-232-C)を接続するためのインターフェースについては、海外のサイトに様々な回路例が示されている。(例:Yaesu VX-7R Modifications & Information)
 私が知る限り、すべて外部電源を要しないものであるが、回路の電源をRS-232-Cの使用しない信号線から得ているために、COMポートのドライブ能力によっては、満足に動作しない場合もあるようだ。
 インターフェースのなかでもっとも微妙な調整を要するのが信号線のバイアス抵抗(R3〜R5)である。定数の決定には、電源電圧やVX-7のドライブ能力(非公開)を勘案する必要があるのだが、電源が不安定だと信号線の電圧が変化してしまい、うまくいかないようである。
 私の回路では、電源は安定化されているが、それでも、下記の定数を得るまでに数回の試行錯誤を要した。数台のVX-7で試用した限りにおいてはすべてうまく動作したが、VX-7の個体差によっては、更に調整を要するかもしれない。

 
 
 
 


VX-7 クローンデータ SAVE/LOAD実験の様子


バーテックススタンダード社製トランシーバ用 RS-232-C / TTL インターフェース回路図

基板上の主要パーツリスト
部品 形式・定数  備 考
IC1 MAX232 RS-232-C - TTL レベルコンバータ (Maxim Integrated Products)
IC2 74LS04 Hex INVERTER (Texas Instruments)
IC3 7805 +5V 1A 電源IC (Matsushita等各社, 放熱器取付がbetter)
Q1 2SC2120 小信号NPNならだいたいOK (Toshiba)
Q2 2SC2120  (同上)
LED11〜LED15 (汎用LED) モニタ用(LED14・LED15は将来の予備)
R1 10KΩ(1/4W)  
R2 10KΩ(1/4W)  
R3 47KΩ(1/4W)  
R4 47KΩ(1/4W)  
R5 100KΩ(1/4W)  
R6 10KΩ(1/4W)  
R11〜R15 1KΩ(1/4W) LEDの電流制限用
C1 2.2μF(50V) 電解コンデンサ(極性注意!)
C2 2.2μF(50V)  (同上)
C3 2.2μF(50V)  (同上)
C4 2.2μF(50V)  (同上)
C5 0.01μF 積層セラミック
C6 47μF(25V) 電解コンデンサ
C7 0.1μF(50V) タンタルコンデンサ
C8 0.1μF(50V)  (同上)
C9 2.2μF(50V) 電解コンデンサ

プロトコル

 VX-1の実験と同じ手順で、VX-7のクローン動作での情報授受のプロトコルを解析した。その結果、概ねつぎの手順で情報交換がなされることが判明した。

通信条件

*1:19,200bpsで連続送信すると、受信側のVX-7が情報を処理しきれなくなるので、1キャラクタ送信するごとに適当な時間待ちが必要。

通信手順

送信側の操作・動作 受信側の操作・動作
1) [MON]を押しながら電源ON。
2) LCDに"CLONE"と表示する。
1) [MON]を押しながら電源ON。
2) LCDに"CLONE"と表示する。
3) [V/M]
4) LCDに"CLONE WAIT"と表示する。
3) [BAND]
4) LCDに"CLONE TX"と表示する。
5) 第1ブロックのデータ(10byte)を送信する。
5) LCDに"CLONE RX"と表示する。
6) 応答信号"06"(16進表示) 1byteを送信する。
6) 第2ブロックのデータ(8byte)を送信する。
7) 応答信号"06"(16進表示) 1byteを送信する。
7) 第3ブロックのデータ(16193byte)を送信する。
8) データを受信し終えたら、電源投入時と同じ動作(オープニングのグラフィック表示)をして、通常モードに戻る。
終了
(LCD表示は"CLONE TX"のまま)
終了
  • 太字は、ユーザーによる操作内容。
  • 赤字は、データの授受を示すもので、外見上はわからない。
  • あくまでも私が解析したものなので、正確性は保証しない。

メモリ内容のSAVE

 VX-7のメモリ内容を保存するために作成したN88-BASIC(86)のプログラム"SAVEVX7.BAS"を示す。

10000 '**********************************************************
10010 '
10020 'VERTEX STANDARD VX-7
10030 'クローンデータ読み出しプログラム Ver1.00 (Sep 22 2002)
10040 '
10050 'Copyright by Heian Software Engineering
10060 '(C)2002 H.S.E. Allrights reserved.
10070 '
10080 '**********************************************************
10090 '
10100 '
10110 '
10120 '
10130 '
10140 '
10150 *START
10160 CLEAR
10170 DEFINT A-Z
10180 WIDTH 80,25:CONSOLE 0,25,1,1:COLOR 7,0,0,7,2:CLS 2
10190 '
10200 RX.BUFF.SIZE=32000:'受信バッファサイズ
10210 DISP.SKIP.N=200:'表示スキップ点
10220 '
10230 COMPORT.NAME$="COM1:N81NN":'通信ポートファイルディスクリプタ
10240 COMPORT.SPEED=8:'通信速度 8:19200,0:SPEEDコマンドによる
10250 '
10260 GOTO *MAIN
10270 '
10280 'HEX.CHR$
10290 GOTO *MAIN
10300 *READ.HEX.CHR
10310 DIM HEX.CHR$(255)
10320 RESTORE *READ.HEX.CHR
10330 FOR READ.HEX.CHR.W=0 TO 255:READ HEX.CHR$(READ.HEX.CHR.W):NEXT
10340 DATA 00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F
10350 DATA 10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F
10360 DATA 20,21,22,23,24,25,26,27,28,29,2A,2B,2C,2D,2E,2F
10370 DATA 30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,3F
10380 DATA 40,41,42,43,44,45,46,47,48,49,4A,4B,4C,4D,4E,4F
10390 DATA 50,51,52,53,54,55,56,57,58,59,5A,5B,5C,5D,5E,5F
10400 DATA 60,61,62,63,64,65,66,67,68,69,6A,6B,6C,6D,6E,6F
10410 DATA 70,71,72,73,74,75,76,77,78,79,7A,7B,7C,7D,7E,7F
10420 DATA 80,81,82,83,84,85,86,87,88,89,8A,8B,8C,8D,8E,8F
10430 DATA 90,91,92,93,94,95,96,97,98,99,9A,9B,9C,9D,9E,9F
10440 DATA A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF
10450 DATA B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,BA,BB,BC,BD,BE,BF
10460 DATA C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,CA,CB,CC,CD,CE,CF
10470 DATA D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF
10480 DATA E0,E1,E2,E3,E4,E5,E6,E7,E8,E9,EA,EB,EC,ED,EE,EF
10490 DATA F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,FA,FB,FC,FD,FE,FF
10500 RETURN
10510 '
10520 *RX.BUFF.INIT
10530 DIM RX.BUFF(RX.BUFF.SIZE-1)
10540 GOSUB *RX.BUFF.CLEAR
10550 RETURN
10560 '
10570 *RX.BUFF.CLEAR
10580 G.RX.BUFF.RP=0:'読み出しポインタ
10590 G.RX.BUFF.WP=0:'書き込みポインタ
10600 G.RX.BUFF.N=0 :'バッファ内データ数
10610 G.RX.BUFF.OV=0:'バッファオーバーフロー
10620 G.RX.BUFF.EM=0:'バッファ内エンプティ
10630 RETURN
10640 '
10650 *RX.BUFF.WRITE
10660 IF G.RX.BUFF.N>=RX.BUFF.SIZE THEN G.RX.BUFF.OV=-1:RETURN
10670 RX.BUFF(G.RX.BUFF.WP)=G.RX.WRITE.DATA
10680 G.RX.BUFF.WP=(G.RX.BUFF.WP+1) MOD RX.BUFF.SIZE
10690 G.RX.BUFF.N=G.RX.BUFF.N+1
10700 G.RX.BUFF.OV=0
10710 RETURN
10720 '
10730 *RX.BUFF.READ
10740 IF G.RX.BUFF.N=0 THEN G.RX.BUFF.EM=-1:RETURN
10750 G.RX.READ.DATA=RX.BUFF(G.RX.BUFF.RP)
10760 G.RX.BUFF.RP=(G.RX.BUFF.RP+1) MOD RX.BUFF.SIZE
10770 G.RX.BUFF.N=G.RX.BUFF.N-1
10780 G.RX.BUFF.EM=0
10790 RETURN
10800 '
10810 '
10820 *COMPORT.INIT
10830 OPEN COMPORT.NAME$ AS #1
10840 IF COMPORT.SPEED=0 THEN GOTO *COMPORT.INIT.1000
10850 OUT &H75,COMPORT.SPEED MOD 256
10860 OUT &H75,COMPORT.SPEED \ 256

10870 *COMPORT.INIT.1000
10880 G.COMPORT.ERROR=0
10890 ON COM GOSUB *COMPORT.INT
10900 RETURN
10910 '
10920 *COMPORT.INT
10930 *COMPORT.INT.1000
10940 IF LOC(1)=0 THEN RETURN
10950 G.RX.WRITE.DATA=ASC(INPUT$(1,1))
10960 GOSUB *RX.BUFF.WRITE
10970 IF G.COMPORT.ERROR=0 THEN G.COMPORT.ERROR=G.RX.BUFF.OV
10980 GOTO *COMPORT.INT.1000
10990 '
11000 '
11010 *STOP.INT
11020 IF G.COMPORT.ERROR<>0 THEN PRINT #2,"**エラー**"
11030 COM OFF
11040 CLOSE
11050 COLOR 7
11060 END
11070 '
11080 '
11090 *MAIN
11100 INPUT "出力(ログ)ファイル名:",OUT.FILE.NAME$
11110 GOSUB *READ.HEX.CHR
11120 GOSUB *RX.BUFF.INIT
11130 GOSUB *COMPORT.INIT
11140 ON STOP GOSUB *STOP.INT
11150 STOP ON:COM ON
11160 '
11170 *MAIN.1000
11180 COM OFF
11190 CLOSE 2
11200 OPEN OUT.FILE.NAME$ FOR OUTPUT AS #2
11210 OFFSET.ADRS=0
11220 GOSUB *RX.BUFF.CLEAR
11230 COM ON
11240 PRINT:PRINT "--準備OK--"
11250 '
11260 *MAIN.1500
11270 COM STOP:GOSUB *RX.BUFF.READ:COM ON
11280 IF G.COMPORT.ERROR<>0 THEN COLOR 2
11290 IF G.RX.BUFF.EM=-1 THEN GOTO *MAIN.2000
11300 OUTPUT.STR$= HEX.CHR$(OFFSET.ADRS \ 256)+HEX.CHR$(OFFSET.ADRS MOD 256)+" : "+HEX.CHR$(G.RX.READ.DATA)
11310 PRINT #2,OUTPUT.STR$
11320 IF DISP.SKIP.N=>G.RX.BUFF.N THEN PRINT OUTPUT.STR$
11330 OFFSET.ADRS=OFFSET.ADRS+1
11340 *MAIN.2000
11350 K$=INKEY$
11360 IF K$="" THEN GOTO 11270
11370 IF K$=CHR$(0) THEN GOTO *MAIN.1000
11380 PRINT #1,K$;
11390 GOTO *MAIN.1500

 このプログラム使った場合のVX-7のメモリデータのSAVE方法はつぎのとおりである。

1) VX-7と自作インターフェース、パソコンを接続する。
2) パソコンの電源を入れ、MS-DOSを起動する。
3) N88-BASIC(86)を起動し、プログラムをLOAD、更にRUNする。
4) [MON]を押しながらVX-7の電源ONする。LCDに"CLONE"と表示される。
5) パソコンで出力(ログ)ファイル名を指定する。
6) パソコンに"--準備OK--"と表示される。
7) VX-7の[BAND]を押す。LCDに"CLONE TX"と表示される。
8) パソコンにVX-7から送られた第1ブロック(10byte)のデータが表示されるので、CTRL-Fを押す(=応答信号送出)。
9) パソコンにVX-7から送られた第2ブロック(8byte)のデータが表示されるので、CTRL-Fを押す(=応答信号送出)。
10) VX-7から、第3ブロック(16193byte)が一気に送信される。
11) パソコンに表示されるデータのスクロールが止まったら、VX-7は第3ブロックを送信し終えているので、STOPキーを押す。
12) VX-7の電源を切る。

メモリ内容のLOAD

 "SAVEVX7.BAS"によって保存されたデータをVX-7に書き込むために作成したN88-BASIC(86)のプログラム"LOADVX7.BAS"を示す。

10000 '**********************************************************
10010 '
10020 'VERTEX STANDARD VX-7
10030 'クローンデータ書き込みプログラム Ver1.00 (Sep 22 2002)
10040 '
10050 'Copyright by Heian Software Engineering
10060 '(C)2002 H.S.E. Allrights reserved.
10070 '
10080 '**********************************************************
10090 '
10100 '
10110 '
10120 *START
10130 CLEAR
10140 DEFINT A-Z
10150 WIDTH 80,25:CONSOLE 0,25,1,1:COLOR 7,0,0,7,2:CLS 2
10160 '
10170 RX.BUFF.SIZE=32000:'受信バッファサイズ
10180 TX.BUFF.SIZE=32000:'送信バッファサイズ
10190 '
10200 COMPORT.NAME$="COM1:N81NN":'通信ポートファイルディスクリプタ
10210 COMPORT.SPEED=8:'通信速度 8:19200,0:SPEEDコマンドによる
10220 G.SEND.DATA.TO.TRX.W=1000:'送信時間調整

10230 '
10240 GOTO *MAIN
10250 '
10260 'HEX.CHR$
10270 *READ.HEX.CHR
10280 DIM HEX.CHR$(255)
10290 RESTORE *READ.HEX.CHR
10300 FOR READ.HEX.CHR.W=0 TO 255:READ HEX.CHR$(READ.HEX.CHR.W):NEXT
10310 DATA 00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F
10320 DATA 10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F
10330 DATA 20,21,22,23,24,25,26,27,28,29,2A,2B,2C,2D,2E,2F
10340 DATA 30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,3F
10350 DATA 40,41,42,43,44,45,46,47,48,49,4A,4B,4C,4D,4E,4F
10360 DATA 50,51,52,53,54,55,56,57,58,59,5A,5B,5C,5D,5E,5F
10370 DATA 60,61,62,63,64,65,66,67,68,69,6A,6B,6C,6D,6E,6F
10380 DATA 70,71,72,73,74,75,76,77,78,79,7A,7B,7C,7D,7E,7F
10390 DATA 80,81,82,83,84,85,86,87,88,89,8A,8B,8C,8D,8E,8F
10400 DATA 90,91,92,93,94,95,96,97,98,99,9A,9B,9C,9D,9E,9F
10410 DATA A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF
10420 DATA B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,BA,BB,BC,BD,BE,BF
10430 DATA C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,CA,CB,CC,CD,CE,CF
10440 DATA D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF
10450 DATA E0,E1,E2,E3,E4,E5,E6,E7,E8,E9,EA,EB,EC,ED,EE,EF
10460 DATA F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,FA,FB,FC,FD,FE,FF
10470 RETURN
10480 '
10490 *RX.BUFF.INIT
10500 DIM RX.BUFF(RX.BUFF.SIZE-1)
10510 GOSUB *RX.BUFF.CLEAR
10520 RETURN
10530 '
10540 *RX.BUFF.CLEAR
10550 G.RX.BUFF.RP=0:'読み出しポインタ
10560 G.RX.BUFF.WP=0:'書き込みポインタ
10570 G.RX.BUFF.N=0 :'バッファ内データ数
10580 G.RX.BUFF.OV=0:'バッファオーバーフロー
10590 G.RX.BUFF.EM=0:'バッファ内エンプティ
10600 RETURN
10610 '
10620 *RX.BUFF.WRITE
10630 IF G.RX.BUFF.N>=RX.BUFF.SIZE THEN G.RX.BUFF.OV=-1:RETURN
10640 RX.BUFF(G.RX.BUFF.WP)=G.RX.WRITE.DATA
10650 G.RX.BUFF.WP=(G.RX.BUFF.WP+1) MOD RX.BUFF.SIZE
10660 G.RX.BUFF.N=G.RX.BUFF.N+1
10670 G.RX.BUFF.OV=0
10680 RETURN
10690 '
10700 *RX.BUFF.READ
10710 IF G.RX.BUFF.N=0 THEN G.RX.BUFF.EM=-1:RETURN
10720 G.RX.READ.DATA=RX.BUFF(G.RX.BUFF.RP)
10730 G.RX.BUFF.RP=(G.RX.BUFF.RP+1) MOD RX.BUFF.SIZE
10740 G.RX.BUFF.N=G.RX.BUFF.N-1
10750 G.RX.BUFF.EM=0
10760 RETURN
10770 '
10780 '
10790 *TX.BUFF.INIT
10800 DIM TX.BUFF(TX.BUFF.SIZE-1)
10810 GOSUB *TX.BUFF.CLEAR
10820 RETURN
10830 '
10840 *TX.BUFF.CLEAR
10850 G.TX.BUFF.RP=0:'読み出しポインタ
10860 G.TX.BUFF.WP=0:'書き込みポインタ
10870 G.TX.BUFF.N=0 :'バッファ内データ数
10880 G.TX.BUFF.OV=0:'バッファオーバーフロー
10890 G.TX.BUFF.EM=0:'バッファ内エンプティ
10900 RETURN
10910 '
10920 *TX.BUFF.WRITE
10930 IF G.TX.BUFF.N>=TX.BUFF.SIZE THEN G.TX.BUFF.OV=-1:RETURN
10940 TX.BUFF(G.TX.BUFF.WP)=G.TX.WRITE.DATA
10950 G.TX.BUFF.WP=(G.TX.BUFF.WP+1) MOD TX.BUFF.SIZE
10960 G.TX.BUFF.N=G.TX.BUFF.N+1
10970 G.TX.BUFF.OV=0
10980 RETURN
10990 '
11000 *TX.BUFF.READ
11010 IF G.TX.BUFF.N=0 THEN G.TX.BUFF.EM=-1:RETURN
11020 G.TX.READ.DATA=TX.BUFF(G.TX.BUFF.RP)
11030 G.TX.BUFF.RP=(G.TX.BUFF.RP+1) MOD TX.BUFF.SIZE
11040 G.TX.BUFF.N=G.TX.BUFF.N-1
11050 G.TX.BUFF.EM=0
11060 RETURN
11070 '
11080 '
11090 *COMPORT.INIT
11100 OPEN COMPORT.NAME$ AS #1
11110 IF COMPORT.SPEED=0 THEN GOTO *COMPORT.INIT.1000
11120 OUT &H75,COMPORT.SPEED MOD 256
11130 OUT &H75,COMPORT.SPEED \ 256

11140 *COMPORT.INIT.1000
11150 G.COMPORT.ERROR=0
11160 ON COM GOSUB *COMPORT.INT
11170 RETURN
11180 '
11190 *COMPORT.INT
11200 *COMPORT.INT.1000
11210 IF LOC(1)=0 THEN RETURN
11220 G.RX.WRITE.DATA=ASC(INPUT$(1,1))
11230 GOSUB *RX.BUFF.WRITE
11240 IF G.COMPORT.ERROR=0 THEN G.COMPORT.ERROR=G.RX.BUFF.OV
11250 GOTO *COMPORT.INT.1000
11260 '
11270 '
11280 *SEND.DATA.TO.TRX
11290 PRINT #1,CHR$(G.SEND.DATA.TO.TRX);
11300 FOR SEND.DATA.TO.TRX.W=0 TO G.SEND.DATA.TO.TRX.W:NEXT
11310 RETURN
11320 '
11330 '
11340 *STOP.INT
11350 *FINISH
11360 IF G.COMPORT.ERROR<>0 THEN PRINT #2,"*****ERROR*****"
11370 COM OFF
11380 CLOSE
11390 COLOR 7
11400 END
11410 '
11420 '
11430 *MAIN
11440 INPUT "入力(データ)ファイル名:",IN.FILE.NAME$
11450 INPUT "出力(ログ)ファイル名:",OUT.FILE.NAME$
11460 GOSUB *READ.HEX.CHR
11470 GOSUB *RX.BUFF.INIT
11480 GOSUB *TX.BUFF.INIT
11490 GOSUB *COMPORT.INIT
11500 ON STOP GOSUB *STOP.INT
11510 STOP ON:COM ON
11520 '
11530 *MAIN.1000
11540 CLOSE 2
11550 OPEN OUT.FILE.NAME$ FOR OUTPUT AS #2
11560 CLOSE 3
11570 OPEN IN.FILE.NAME$ FOR INPUT AS #3
11580 OFFSET.ADRS=0
11590 '
11600 '送信データ準備
11610 *MAIN.1300
11620 COLOR 4
11630 IF EOF(3) THEN GOTO *MAIN.1400
11640 INPUT #3,INPUT.LINE$
11650 'PRINT INPUT.LINE$
11660 IF INPUT.LINE$="" THEN GOTO *MAIN.1300
11670 IF LEFT$(INPUT.LINE$,1)="'" THEN GOTO *MAIN.1300
11680 IF LEN(INPUT.LINE$)<>9 GOTO *MAIN.1380
11690 INPUT.DATA$=MID$(INPUT.LINE$,8,2)
11700 IF HEX.CHR$(VAL("&H"+INPUT.DATA$))<>INPUT.DATA$ THEN GOTO *MAIN.1380
11710 G.TX.WRITE.DATA=VAL("&H"+INPUT.DATA$)
11720 GOSUB *TX.BUFF.WRITE
11730 IF G.TX.BUFF.OV<>0 THEN PRINT:PRINT "**入力(データ)ファイルが大きすぎます**":GOTO *FINISH
11740 GOTO *MAIN.1300
11750 '
11760 '送信データエラー
11770 *MAIN.1380
11780 PRINT:PRINT "**入力(データ)ファイルに誤りがあります**":GOTO *FINISH
11790 *MAIN.1400
11800 PRINT "--データの準備ができました。スペースバーを押してください--"
11810 *MAIN.1410
11820 K$=INKEY$:IF K$<>" " THEN GOTO *MAIN.1410
11830 GOSUB *RX.BUFF.CLEAR
11840 COLOR 7
11850 G.SEND.BLOCK.N=10:G.SEND.BLOCK.ACK=6:GOSUB *SEND.BLOCK
11860 IF SEND.BLOCK.ERROR=-1 THEN PRINT SEND.BLOCK.ERROR.MES$:GOTO *FINISH
11870 G.SEND.BLOCK.N=8:G.SEND.BLOCK.ACK=6:GOSUB *SEND.BLOCK
11880 IF SEND.BLOCK.ERROR=-1 THEN PRINT SEND.BLOCK.ERROR.MES$:GOTO *FINISH
11890 G.SEND.BLOCK.N=30000:G.SEND.BLOCK.ACK=6:GOSUB *SEND.BLOCK
11900 *MAIN.1450
11910 PRINT:PRINT "--書込み終了--"
11920 GOTO *STOP.INT
11930 '
11940 '
11950 'ブロック送信
11960 *SEND.BLOCK
11970 SEND.BLOCK.ERROR=-1
11980 SEND.BLOCK.ERROR.MES$=""
11990 SEND.BLOCK.N=G.SEND.BLOCK.N
12000 '
12010 'データ送信動作
12020 *SEND.BLOCK.0500
12030 IF SEND.BLOCK.N=0 THEN GOTO *SEND.BLOCK.1000
12040 GOSUB *TX.BUFF.READ
12050 IF G.TX.BUFF.EM=-1 THEN SEND.BLOCK.ERROR.MES$="**入力(データ)ファイルが不足しています**":RETURN
12060 'PRINT #1,CHR$(G.TX.READ.DATA);
12070 G.SEND.DATA.TO.TRX=G.TX.READ.DATA:GOSUB *SEND.DATA.TO.TRX
12080 *SEND.BLOCK.0550
12090 COM STOP:GOSUB *RX.BUFF.READ:COM ON
12100 IF G.RX.BUFF.EM=-1 THEN GOTO *SEND.BLOCK.0550
12110 OUTPUT.STR$= HEX.CHR$(OFFSET.ADRS \ 256)+HEX.CHR$(OFFSET.ADRS MOD 256)+" : "+HEX.CHR$(G.RX.READ.DATA)
12120 PRINT #2,OUTPUT.STR$
12130 PRINT OUTPUT.STR$
12140 OFFSET.ADRS=OFFSET.ADRS+1
12150 SEND.BLOCK.N=SEND.BLOCK.N-1
12160 GOTO *SEND.BLOCK.0500
12170 *SEND.BLOCK.1000
12180 GOSUB *TX.BUFF.READ
12190 IF G.TX.BUFF.EM=-1 THEN SEND.BLOCK.ERROR.MES$="**入力(データ)ファイルが不足しています**":RETURN
12200 *SEND.BLOCK.1050
12210 COM STOP:GOSUB *RX.BUFF.READ:COM ON
12220 IF G.RX.BUFF.EM=-1 THEN GOTO *SEND.BLOCK.1050
12230 OUTPUT.STR$= HEX.CHR$(OFFSET.ADRS \ 256)+HEX.CHR$(OFFSET.ADRS MOD 256)+" : "+HEX.CHR$(G.RX.READ.DATA)
12240 PRINT #2,OUTPUT.STR$
12250 PRINT OUTPUT.STR$
12260 OFFSET.ADRS=OFFSET.ADRS+1
12270 IF G.RX.READ.DATA<>G.SEND.BLOCK.ACK THEN SEND.BLOCK.ERROR.MES$="**不正なACKです**":RETURN
12280 SEND.BLOCK.ERROR=0
12290 '
12300 PRINT:PRINT "--ブロック送信完了--"
12310 RETURN

 このプログラム使った場合のVX-7のメモリデータのLOAD方法はつぎのとおりである。

1) VX-7と自作インターフェース、パソコンを接続する。
2) パソコンの電源を入れ、MS-DOSを起動する。
3) N88-BASIC(86)を起動し、プログラムをLOAD、更にRUNする。
4) [MON]を押しながらVX-7の電源ONする。LCDに"CLONE"と表示される。
5) パソコンで入力(データ)ファイル名を指定する。ここで指定するのは、"SAVEVX7.BAS"で作成されたVX-7のメモリ内容データである。
6) パソコンで出力(ログ)ファイル名を指定する。
7) しばらくすると、パソコンに"--データの準備ができました。スペースバーを押してください--"と表示される。
8) VX-7の[V/M]を押す。LCDに"CLONE WAIT"と表示される。
9) パソコンのスペースバーを押す。
10) VX-7のLCDが"CLONE RX"に変る。パソコンには、VX-7に送信しているデータが表示される。
11) パソコンがデータの送信を終えると、"--書込み終了--"と表示する。VX-7は、正常にデータ書き込みができた場合、通常の電源ON時と同じオープニングのグラフィックを表示して、通常モードに戻る。

プログラムの解説

 ここに示したプログラムは、PC-9800シリーズ用のN88-BASIC(86)(MS-DOS版)で書かれたものなので、一般のWindowsマシンでは動かない。また、自作インターフェースがないと動作させることはできない。私のPC-9821Xa12(Pentium 120MHz)とVX-7(Serial No 2G020469)、自作インターフェースで動作確認を行っているが、他の環境で動作可能か否かは未確認である。

 VX-7は、クローン動作時に19,200bpsでデータ交換を行うようだが、PC-9800シリーズとN88-BASIC(86)は、公式的には9,600bpsまでしか対応していない。そこで、8253(相当)を直接コントロールして、19,200bpsでの通信を可能にしている("SAVEVX7.BAS"の行番号10240,10850及び10860、"LOADVX7.BAS"の行番号10210,11120及び11130)。I/Oを直接コントロールするあまりに乱暴かつ無謀な方法なので、システムがハングアップする可能性が大いにある。しかし、実験のために私は何度もこのプログラムを走らせたが、一度もそういうことは起きなかった。無論これは確実に動作することを保証するものではない! なお、いわゆる"8MHz系"のPC-9800シリーズでは、COMポートの通信速度はハードウエア的に9,600bpsに制限されるから、このプログラムは使えない。

 VX-7のクローン動作では、特別なフロー制御はないようである。したがって、"SAVEVX7.BAS"及び"LOADVX7.BAS"でも、フロー制御は特に考慮していない。低速のPC-9800シリーズでは、VX-7から送られてくるデータをとりこぼす可能性がある。
 逆に、"LOADVX7.BAS"で、パソコンからVX-7に19,200bpsでデータを一気に送信すると、VX-7がデータを取りこぼす現象がみられた。この場合、パソコンに"--書込み終了--"の表示が出るが、VX-7のLCDは"CLONE RX"のままである。そこで、1byte送信するごとに適当な時間待ちを行うことにしてある。"LOADVX7.BAS"の行番号10220で待ち時間を指定しているので、動作環境(PC-9800のCPU/クロック周波数)にあわせて適宜調整する必要がある。

 ここに示したプログラムは、あくまでも実験用なので、エラー処理などは大幅に省略している。

 筆者は、ここに示したプログラムの著作権を放棄するものではないが、営利を目的としない限り、誰でも自由に利用・改変してよい。WindowsやMacOSに移植する試みは大歓迎であり、ドンドンやっていただきたい。(事後にいいので、私まで連絡をいただけるとありがたい!) ただし、このプログラムを使用した結果、パソコンやVX-7に不可逆的な変化(=故障など)が生じても、筆者は一切責任を負わないので、あらかじめ了解願いたい。

 プログラムの使用条件、ダウンロード等は、こちらにどうぞ。

データ内容の解析

 "SAVEVX7.BAS" で生成されるファイルは、単なるテキストファイルだから、エディタ等で容易に内容を見ることができる。ファイルの一例を示す。

0000 : 0A
0001 : 01
0002 : 02
0003 : 06
0004 : 09
0005 : 24
0006 : F8
0007 : 00
0008 : 01
0009 : 24
000A : 06
000B : F8
000C : 00
000D : 02
000E : 01
000F : FF
0010 : FF
0011 : FF
0012 : FF
0013 : 06
0014 : 00
0015 : 00
0016 : 00
0017 : 00
0018 : 00
0019 : 00
001A : 05
001B : 05
001C : 00

(省略)

3F49 : FF
3F4A : FF
3F4B : FF
3F4C : FF
3F4D : FF
3F4E : FF
3F4F : FF
3F50 : FF
3F51 : FF
3F52 : C9
3F53 : FF
3F54 : 0C

 行の最初は、データの先頭からのオフセット(16進表示)、コロンのあとがデータそのもの(16進表示)である。

 オフセット000Aの"06"と0012の"06"は、SAVE時にパソコンのキーボードから入力したCTRL-Fのエコーである。"LOADVX7.BAS"でデータをVX-7に書き込む際には、無視される。

 今のところ、個々のデータ(bit列)が何を意味するかは不明である。

 しかし、たとえば、VX-7のメモリデータをパソコンに保存したあと、VX-7のメモリにいずれかの周波数・メモリタグをひとつだけ書き込み、メモリデータを再度保存する。そして、2つのファイルを比較すれば、メモリデータの構成が少しずつ明らかに出来るであろう。メモリデータの構成が解明されれば、最終目標である、VX-7のメモリデータをパソコン上で編集することも可能になる。

 次なる実験は、こうして得られたメモリデータの構成を解明することである。

注意

 ここに記載された情報は、私が独自に収集したものです。内容の正確性については保証しません。あなたの自己責任でご利用ください。
 VX-7のクローン機能は、あくまでも2台のVX-7を接続したうえで、設定等の情報をコピーするためのものです。ここに記した情報は私が個人的に解析した結果であり、この件に関して、(株)バーテックススタンダードもしくはその販売店に問い合わせることはご遠慮ください。

続き

戻る


Copyright (C) 2003-2003 Heian Software Engineering. Allrights Reserved.
制作:2002年9月22日 最終修正:2003年4月29日