2020年1月23日木曜日

FM-7用のFDCカードのプリント基板化完了

FM-7用のFDCカードをプリント基板化しました。


2019年8月26日のブログ「FM77用の拡張I/Oボード、ROM/RAMディスクボードのプリント基板化が完了」の末尾で紹介しました、手配線のFM-7用FDCカードですが、プリント基板化し、ようやく動作確認ができました。

いつものようにいくつかのドジをしてしまい、しなくても良い回り道をしましたが、現在は無事に動作しております。

まず回路図を示します。
2019年10月26日のブログ「FM-7でPC用のフロッピードライブを使う」で示した回路には一個所間違いがありましたので訂正してあります。(Q,E,RW信号からWE信号を作るところです。)
また、Step信号の2倍化回路を追加してあります。


回路図(StepDoubler回路付き)


製作した基板を以下に示します。
およそ12cmx8cmのサイズに計21個のICを何とか収めることができました。
中央の40ピンICがFDCのMB8877A、その右上の8ピンICがデータセパレータの9216B、基板右上隅の8ピンICがStepDoubler用のATtiny85で、その右のスイッチはそのStepDoubler回路のバイパススイッチです。
(ミスのある基板ですので、試作ということで34ピンコネクタの代わりにボックスコネクタを使用したり、FDD用の電源として0.1uのパスコン用の穴にピンを立てて取り出したり、修正をICの足を切断して表面で配線したりしていますので見苦しいですが...)


FM-7用FDCカード


回路のミスのみでなく、FDD用の34ピンコネクタを裏側ではなく表側に配置してしまったり、FDD用の電源コネクタを忘れたりしています。(こんな基板を10枚も作ってしまいました...)
全くダメな基板というわけでもなく、多少の修正で動作するのでまあ良しとします。

もう一度、これらを修正し、FDD用の電源コネクタを追加した基板を作成中です。
このカードのみで普通の2Dのドライブ(あるいはDOS用の2HD/2DDドライブ)を4台まで接続できます。(もちろん、各ドライブにはReady信号を生成する回路が必要ですが。)

一度はもうFM-7ではFDDを使うのはやめようと決めましたし、FDを使わない工夫をされている方々がおられますので(「思い付きハードでソフトに七転八倒」さん、「ysflight.com」さん、「日本橋電気街徘徊日誌」さんなど)、その方々のお知恵を拝借すれば、あえてクラシックなFDDを使う必要もないのですが、大昔、手配線で苦労して製作したFDCカードですので、プリント基板化し、資料として残すことができて満足です。


2020年1月21日火曜日

FM77AV用PS/2キーボード変換器の不具合を修正

FM77AV用のPS/2変換器のビープ音が鳴るという不具合を修正しました


2019年7月19日に公開しましたPS/2キーボード変換器ですが、身近の方々や、ご希望の方に基板やプログラム書き込み済みのATtiny85を配布したりして使っていただいておりました。
最近ある方から、キーを押すたびにビープ音が出て困るというお話をいただきました。
私自身も4年以上使用していましたが、常にボリュームをゼロにしていましたので全く気づいていませんでした。何故か常用しているFM77AV40SXではビープ音は出ませんが、最近入手したFM77AV1では出ました。

キーを押すたびにビープ音が出る原因ですが、RS232Cカードの件でお世話になりましたysflight.comさんのブログによりますと、キーを離したときにリリースコードを発行していないからだということでした。
リリースコードをどのように構成すればよいのか分からず、ysflgith.comさんのプログラムを読んでみたりしていたのですが、40ビットコードを30ビットに変換して処理されていることもあってか処理内容が理解できず、思い余って直接ysflight.comさんに助けを求めましたところ、快く教えていただけました。とても丁寧に解説していただいたのでようやく理解することができました。ありがとうございました。

ysflight.comさんによれば40ビットのコード中の、第4ビットからの8ビットのみを変換すれば良いとのことでした。
ということで処理が必要なのは先頭からの2バイトのみということになりますので、コードを確認したところ、第1バイトは常に0xb4で、第2バイトは0xcc,0xcb,0xb4,0xb3の4通りしかありませんでしたので、それらに必要な処理をした結果は以下のようになりました。
  0xb4, 0xcc -> 0xb3, 0x4c
  0xb4, 0xcb -> 0xb3, 0x4b
  0xb4, 0xb4 -> 0xb3, 0x34
  0xb4, 0xb3 -> 0xb3, 0x33
キーを押下したときのコードの第1,2バイトを上のように置き換えたものをリリースコードとして押下コードの直後に発行することで、無事にビープ音を消すことができました。
その部分のプログラムを以下に示します。



// convert from codeno to serial code
// change keycode to serial code for FM77AV
void outserialdata(unsigned char kcode)
{
 ...
 
  flgE0 = 0;
  flgE1 = 0;
  if (pgm_read_byte(&pscode0[i]) == kcode) {
   cnvcode(i);
   cnvreleasecode(i); // !!! Added to mute the beep !!!
  }
 ...
 
  flgSFTCTRL = 0;
  svsftctrl = 0;
  if (pgm_read_byte(&pscode0[i]) == kcode) {
   cnvcode(i);
   cnvreleasecode(i); // !!! Added to mute the beep !!!
  }
 ...
}


int cnvcode(unsigned int codeno)
{
 unsigned char kc;
 int i; 

 serial2port(0xb4);  // 1st byte
    for (i=0; i<4; i++) { // 2nd-5th bytes
  kc = pgm_read_byte(&fmcode0[codeno][i]);
  serial2port(kc);
    }
 PORTB |= _BV(4);  // PORTB = 0x10(KSDATA=H)
// _delay_ms(20);   // important!!! for 2key pressed
 _delay_ms(1);
    return 0;
}

// convert from codeno to serial releasecode
// only the following four release code patterns to be changed
// 1st  2nd byte
// 0xb4,0xcc -> 0xb3,0x4c
// 0xb4,0xcb -> 0xb3,0x4b
// 0xb4,0xb4 -> 0xb3,0x34
// 0xb4,0xb3 -> 0xb3,0x33
int cnvreleasecode(unsigned int codeno)
{
 unsigned char kc;
 int i; 

 serial2port(0xb3);  // 1st byte
 kc = pgm_read_byte(&fmcode0[codeno][0]); // read 2nd byte
 switch (kc) {
  case 0xcc: serial2port(0x4c);
      break;
  case 0xcb: serial2port(0x4b);
      break;
  case 0xb4: serial2port(0x34);
      break;
  case 0xb3: serial2port(0x33);
      break;
 }
    for (i=1; i<4; i++) { // 3rd-5th bytes
  kc = pgm_read_byte(&fmcode0[codeno][i]);
  serial2port(kc);
    }
 PORTB |= _BV(4);  // PORTB = 0x10(KSDATA=H)
// _delay_ms(20);   // important!!! for 2key pressed
 _delay_ms(1);
    return 0;
}

// serial code out to PORTB(bit4)
// In an 8-bit pattern, the 4th bit is always equal to the 3rd bit
// pulse length (8bit->skip the 4th bit)
//  100us,125us,175us,100us,125us,175us
void serial2port(unsigned char kc)
{
 int i;

    for (i=0; i<8; i++) {
     if ((i+1) % 4 != 0) {  // skip bit3,7
      if((kc & 0x80) == 0x80) {
    PORTB &= ~_BV(4); // PORTB = 0x00(KSDATA=L)
   } else {
    PORTB |= _BV(4); // PORTB = 0x10(KSDATA=H)
      }
  }
  // wait100,125,175us();
     switch (i) {
      case 0:
     case 4:
    _delay_us(100);
    break;
      case 1:
      case 5:
    _delay_us(125);   
       break;
      case 2:
     case 6:
    _delay_us(175);
       break;
      case 3:
      case 7:
       break;
     }
     kc = kc << 1;
 }
}



キーコード番号を得て、それを4バイトのキーコードに変換して出力するルーチン中で
関数cnvcode()に続いてcnvreleasecode()を実行しています。
実際にポートに出力する関数serial2port()も手直ししました。
以前は各ビットの出力時間は全て等しく100usでしたが、ysflight.comさんが実機で確認されています長さに合わせて100us,125us,175us(第4ビットはパス)に変更してあります。

また、以前のプログラムではキーが連打されたときにキーコードを正しく認識するためにcnvcode()の末尾に20msのdeleyを入れていましたが、リリースコードでキーが離されたことを認識できますのでそれが不要となりました。(なしにはできず、1msのdelayは必要でしたが。)
結果として、かなりの高速で連打しても正しく入力ができるようになりました。
OneDriveにプログラムを公開してありますので、詳しくはそちらをご覧ください。

貴重なアドバイスをいただいたysflight.comさんに感謝いたします。

【追記】変換器を購入された方で、ご自分でATtiny85に書き込めない方には、新しいプログラムを書き込んだATtiny85をお送りしますので、私からの連絡をお待ちください。