石原 博の覚書

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

テラステーションの復旧(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



CP/M 68K で C言語

2024-04-14 22:30:02 | 日記
せっかくCP/M 68K でCが動くので、プログラムを動かした

Web上にCのソースは色々あるが、今となってはansi準拠がほとんど。

CP/M 68K のCは古いので、いろいろ対応していないため書き換える必要がある。大掛かりなものは面倒なので小物を探す。
手頃なものがあったので、書き換えてコンパイルまでしてみたが動かない。(エラーじゃなくて固まる)

昔を思い出しながらddtでデバッグすると、メモリのないところをアクセスして止まっている。
($FFFFCA28+$C になんてメモリがない)

link A6,#$0
PC=00009582 USP=00036546 SSP=00005D26 ST=0008=>IM=0 NEG
D 00000008 00036247 00000000 00000000 00000000 00000000 00000000 00000005
A 0000C838 00000008 00008081 00000000 00000000 00008086 00036546 00036546

movem.l D7-D7/A5-A5,-(A7)
PC=00009586 USP=0003653E SSP=00005D26 ST=0008=>IM=0 NEG
D 00000008 00036247 00000000 00000000 00000000 00000000 00000000 00000005
A 0000C838 00000008 00008081 00000000 00000000 00008086 00036546 0003653E

movea.l $8(A6),A5
PC=0000958A USP=0003653E SSP=00005D26 ST=0008=>IM=0 NEG
D 00000008 00036247 00000000 00000000 00000000 00000000 00000000 00000005
A 0000C838 00000008 00008081 00000000 00000000 FFFFCA28 00036546 0003653E

subq.w #$1,$C(A5)


そういえば、コンパイル時にwarningが出てた。警告なので無視したけど。
(warning) short assigned to pointer

そういえば このCはintは16bitでポインタは32bitだった。
該当箇所のアッセンブリソースを見ると以下のとおりfopenの返り値を符号拡張している。そりゃだめだ。
fp = fopen("test.txt", "r");

move.l #L3,(sp)
move.l #L2,-(sp)
jsr _fopen
addq.l #4,sp
ext.l R0
move.l R0,-4(R14)

特にCPM400SRを使っているのでTPAが$8000以降のため、返り値が符号拡張されfgetc(fp)で、
とんでもないアドレスをアクセスして固まったものと思われる。

本来 FILE *fopen(); がstdio.hにあるべきだと思ったんだが?

とりあえずソースの最初に「File *fopen();」を入れてコンパイルすれば警告も出ず、正常に動作させることが出来た。

2024/4/15追記
stdio.hはhttp:/www.cpm.z80.de/binary.htmlからダウンロードしたCP/M-68K BINARY version1.3
のものだがおかしい。後半が消えているようだ。
同ページの MICRO EMACS for CP/M-68K の中のstdio.hには、FILE *fopen();がある。
他にもヘッダファイルが途中までのようなものがいくつかある。 なぜだろう。

CP/M68K SDカード内容整理

2024-03-20 12:53:57 | 日記
CP/M68Kが一応動き出したがプログラムのやり取りが面倒

linux側から毎回cpmtoolsを使用してSDカードに書き込みしていたが、
逆にSDカードからlinuxへの読み出しを試みた。

SDカードのイメージを dd でdiskimagecに読み出したあと、
cpmcpでファイルに戻す
>cpmcp -f 8mb diskimagec 0:* diskc

ところが「malloc(): invalid size (unsorted)」というエラーが出る。
確保した領域以上になにかしているのかなあ。素人だから良くわからない。

githubでcpmtoolsがあった(https://github.com/lipro-cpm4l/cpmtools)のでダウンロード。
unofficial forkらしい。とりあえずソースを読むがやっぱりわからない。

gdbで動きを見ようと
./configure CFLAGS="-g O0"
make
sudo make install
とすると動いた??
(apt get install では /usr/binだが、コンパイルすると/usr/local/binにインストールされる)

あれっと思い、今度はconfigureにオプションをつけずにコンパイル
./configure
make clean
make
sudo make install
すると今度も動いた???

debianのレポジトリのcpmtoolsにバグがあったのか、コンパイラのバージョン違いか
良くわからないが、まあ動いたので良しとしよう。

これでSD内のファイル整理がしやすくなる。

FDD-USB(USB_FDD@1306)が動いた

2024-03-17 12:54:47 | 日記
先日Arduinoを利用したFDD読み取りができたが、別にアマゾンで1800円程度のボードがあるのを見つけた
話のネタに注文。少し時間がかかったが到着。


動かない。

良く見ると半田ブリッジ。出荷検査してないのか? これでは動くわけないやと修正。


一応電源用のケーブルはあるが、これを使ってもモーターがちゃんと動かない(カタカタいうけど回らない)。
調べて見るとMITSUMI D353M3Dは5V 1.6W 一応USB2.0の範囲内とも言えなくもないが、
こんな細い線でモーターを動かすのは問題。

外部からドライブの電源を接続。


lsusbでは
Bus 001 Device 043: ID 0644:0000 TEAC Corp. Floppy
と表示される。

一応3.5inchフロッピーディスクを読めることが確認できた。