Last Updated on 2024年12月19日 by kabekin
こちらで作ったレベル3でPC/AT用FDDを使う投稿でFM用のパラメータのままだとエラー
になることがあるのでレベル3のパルスを調べてレベル3で保証された値にしてみました^^
現在はこんな環境で作業しています^^

MB-S1とレベル3を楽しむための環境で3インチFDDやAIWAのDR-1などレアな周辺機器も
楽しめます。(早くMT-2を接続したい^^)
このガラス扉のテレビ台も昭和のHITLINE用で日立純正 です
一応、MP-1802と1800は外部デッキ側から電源を供給せず排他で使えば同居可能です。
排他にする必要はあるようで同時には使用できませんでした。
MP-1802のステップ信号を見てみると

なんと4μSでした。
FMの実測は1500μSのようなので、L3はかなり短めです^^
次のステップパルスが出るまでの時間は、

約11.92msでした。
一度で出力されるステップパルスは1~4個。←これはどのような動作か不明^^;;;
この波形確認はMP-1802から出力されるステップパルスを観測したかったので、
SAVEM “1:TEST”,&H1000,&H6FFF,&H1000
と6トラック分を連続書込する際の波形を観測しています。
そこでステップパルスが1回ではなく2~4回出ることがありました。
この動作は今のところ理解できていません・・・^^;;;
1トラック16セクタの書込の処理には200ms程度の時間がかかるのではと思っていたのですが
12ms毎にステップパルスが出力されているように見えます。

MB8866でステップパルスは先読みで複数回出力されることはあるのでしょうか?
ご存じの方、教えてください
マニュアルトリガで普通にトリガをかけていますが、トリガのかけ方が悪く混乱している
だけかもしれません^^;;;
これを踏まえてFM77と比較するとこんな感じになります。

と、言うわけで
オン時のパルス幅は余裕を見て10μS,
2個目のパルスは約5ms後で10μS
余裕時間は 約7msにしてみました。
ステップ信号2倍化出力を確認すると、

一つ目のパルス出力から5ms後に2個目のパルス出力されます。
パルス幅は10μS

オリジナルの4μSからみるとかなりの余裕^^;;;
(ATTiny85の精度が高ければこんなに余裕を取る必要はないかも・・・)
2発目のパルス出力後MP-1802からのステップ出力まで約7ms

これで2発目のステップパルスを別途生成してもMP-1802から出力されるパルスには影響されることなくステップ信号2倍で使っても問題なさそうです。
レベル3で使用する場合のステップ信号2倍化プログラムは次のようにしてみました。(ArduinoIDE用)
オリジナルのプログラムはold68funさんのプログラムです。
*(1)STEP PULSE for FDD changes to double pulse
* ->output first pulse (pulse width is 1.5ms)
* output second pulse (pulse width is 1.5ms)
* 1.5ms 4.5ms 1.5ms (4.5ms) 12.5ms
* PORTB bit2:input pulse, bit4:output pulse (double pulse)
* If the Motor On signal is on, Check the Index signal.
* While check 2000 times in 0.5 ms, if it is not detected
* PORTB bit0:MotorOn, bit1:Index, bit3:Ready
* Low:E2(change from 62), High:DF, Ex:FF
* Original Version '2020.07.18
* Copyright (C) by Yuichi Yamamoto
* ベーシックマスタレベル3でDISK I/Oエラーにならないようにパルス幅変更
#include <avr/interrupt.h>
//#define F_CPU 8000000UL
MCUSR = 0x00; /* MCUSRのWDRFを解除(0) */
WDTCR |= (1<<WDCE)|(1<<WDE); /* WDCEとWDEに論理1書き込み */
WDTCR = 0x00; /* ウォッチドッグ禁止 */
DDRB = 0b11111000; /* PORTB bit0,1,2,5:input, bit3,4:output */
PORTB = 0xff; /* PORTB all pull up */
// MCUCR = (1 << ISC01) | (1 << ISC00); /* INT0 interrupt on rising edge */
MCUCR = (1 << ISC01) | (0 << ISC00); /* INT0 interrupt on falling edge */
// PCMSK = (1<<PCINT1); /* Pin Change Mask : PCINT1のみ許可 */
// GIMSK = (1 << INT0) | (1 << PCIE); /* Enable INT0 & PCIE interrupt */
GIMSK = (1 << INT0); /* Enable INT0 interrupt */
PORTB &= ~_BV(4); // DATA bit=L
PORTB |= _BV(4); // DATA bit=H
PORTB &= ~_BV(4); // DATA bit=L
PORTB |= _BV(4); // DATA bit=H
while ((PINB & 0x20) == 0) { //PB5:MotorOn?
if ((PINB & 0x40) == 0) { //PB6:Index?
PORTB &= ~_BV(3); //PB3=0:Ready On
for (int ct=0; ct<5000; ct++) { //check Index while 1s
_delay_us(500); //delay 0.5ms
if ((PINB & 0x60) == 0) { //MotorOn & Index?
if (indexct == 0) { //index off
PORTB |= _BV(3); //PB3=1:Ready Off
PORTB |= _BV(3); //PB3=1:Ready Off
/*
* StepDoublerWithReady.c
*
*(1)STEP PULSE for FDD changes to double pulse
* input pulse
* ->output first pulse (pulse width is 1.5ms)
* wait 4.5ms
* output second pulse (pulse width is 1.5ms)
* wait 12.5ms
*
* L H L H NEXT PULSE
* 1.5ms 4.5ms 1.5ms (4.5ms) 12.5ms
*
* PORTB bit2:input pulse, bit4:output pulse (double pulse)
*
*(2)Ready signal
* If the Motor On signal is on, Check the Index signal.
* While check 2000 times in 0.5 ms, if it is not detected
* at all, Ready is off.
*
* PORTB bit0:MotorOn, bit1:Index, bit3:Ready
*
*[Note!]Fuse bit
* Low:E2(change from 62), High:DF, Ex:FF
*
* Original Version '2020.07.18
* Copyright (C) by Yuichi Yamamoto
*
* KABEKIN MEMO
* ベーシックマスタレベル3でDISK I/Oエラーにならないようにパルス幅変更
* オン時間:10uS オフ時間:5000uS
*/
#include <avr/io.h>
#include <avr/interrupt.h>
//#define F_CPU 8000000UL
#include <util/delay.h>
volatile int chg = 0;
void setup(void)
{
MCUSR = 0x00; /* MCUSRのWDRFを解除(0) */
WDTCR |= (1<<WDCE)|(1<<WDE); /* WDCEとWDEに論理1書き込み */
WDTCR = 0x00; /* ウォッチドッグ禁止 */
DDRB = 0b11111000; /* PORTB bit0,1,2,5:input, bit3,4:output */
PORTB = 0xff; /* PORTB all pull up */
// MCUCR = (1 << ISC01) | (1 << ISC00); /* INT0 interrupt on rising edge */
MCUCR = (1 << ISC01) | (0 << ISC00); /* INT0 interrupt on falling edge */
// PCMSK = (1<<PCINT1); /* Pin Change Mask : PCINT1のみ許可 */
// GIMSK = (1 << INT0) | (1 << PCIE); /* Enable INT0 & PCIE interrupt */
GIMSK = (1 << INT0); /* Enable INT0 interrupt */
sei();
}
ISR (INT0_vect)
{
// first pulse
PORTB &= ~_BV(4); // DATA bit=L
_delay_us(10);
PORTB |= _BV(4); // DATA bit=H
// interval time
_delay_us(5000);
// second pulse
PORTB &= ~_BV(4); // DATA bit=L
_delay_us(10);
PORTB |= _BV(4); // DATA bit=H
// interval time
_delay_us(5000);
}
/*
ISR (PCINT0_vect)
{
chg++;
}
*/
int main(void)
{
int indexct = 0;
setup();
while (1) {
while ((PINB & 0x20) == 0) { //PB5:MotorOn?
if ((PINB & 0x40) == 0) { //PB6:Index?
PORTB &= ~_BV(3); //PB3=0:Ready On
indexct = 0;
for (int ct=0; ct<5000; ct++) { //check Index while 1s
_delay_us(500); //delay 0.5ms
if ((PINB & 0x60) == 0) { //MotorOn & Index?
indexct++;
}
}
if (indexct == 0) { //index off
PORTB |= _BV(3); //PB3=1:Ready Off
}
}
}
PORTB |= _BV(3); //PB3=1:Ready Off
}
return 0;
}
/*
* StepDoublerWithReady.c
*
*(1)STEP PULSE for FDD changes to double pulse
* input pulse
* ->output first pulse (pulse width is 1.5ms)
* wait 4.5ms
* output second pulse (pulse width is 1.5ms)
* wait 12.5ms
*
* L H L H NEXT PULSE
* 1.5ms 4.5ms 1.5ms (4.5ms) 12.5ms
*
* PORTB bit2:input pulse, bit4:output pulse (double pulse)
*
*(2)Ready signal
* If the Motor On signal is on, Check the Index signal.
* While check 2000 times in 0.5 ms, if it is not detected
* at all, Ready is off.
*
* PORTB bit0:MotorOn, bit1:Index, bit3:Ready
*
*[Note!]Fuse bit
* Low:E2(change from 62), High:DF, Ex:FF
*
* Original Version '2020.07.18
* Copyright (C) by Yuichi Yamamoto
*
* KABEKIN MEMO
* ベーシックマスタレベル3でDISK I/Oエラーにならないようにパルス幅変更
* オン時間:10uS オフ時間:5000uS
*/
#include <avr/io.h>
#include <avr/interrupt.h>
//#define F_CPU 8000000UL
#include <util/delay.h>
volatile int chg = 0;
void setup(void)
{
MCUSR = 0x00; /* MCUSRのWDRFを解除(0) */
WDTCR |= (1<<WDCE)|(1<<WDE); /* WDCEとWDEに論理1書き込み */
WDTCR = 0x00; /* ウォッチドッグ禁止 */
DDRB = 0b11111000; /* PORTB bit0,1,2,5:input, bit3,4:output */
PORTB = 0xff; /* PORTB all pull up */
// MCUCR = (1 << ISC01) | (1 << ISC00); /* INT0 interrupt on rising edge */
MCUCR = (1 << ISC01) | (0 << ISC00); /* INT0 interrupt on falling edge */
// PCMSK = (1<<PCINT1); /* Pin Change Mask : PCINT1のみ許可 */
// GIMSK = (1 << INT0) | (1 << PCIE); /* Enable INT0 & PCIE interrupt */
GIMSK = (1 << INT0); /* Enable INT0 interrupt */
sei();
}
ISR (INT0_vect)
{
// first pulse
PORTB &= ~_BV(4); // DATA bit=L
_delay_us(10);
PORTB |= _BV(4); // DATA bit=H
// interval time
_delay_us(5000);
// second pulse
PORTB &= ~_BV(4); // DATA bit=L
_delay_us(10);
PORTB |= _BV(4); // DATA bit=H
// interval time
_delay_us(5000);
}
/*
ISR (PCINT0_vect)
{
chg++;
}
*/
int main(void)
{
int indexct = 0;
setup();
while (1) {
while ((PINB & 0x20) == 0) { //PB5:MotorOn?
if ((PINB & 0x40) == 0) { //PB6:Index?
PORTB &= ~_BV(3); //PB3=0:Ready On
indexct = 0;
for (int ct=0; ct<5000; ct++) { //check Index while 1s
_delay_us(500); //delay 0.5ms
if ((PINB & 0x60) == 0) { //MotorOn & Index?
indexct++;
}
}
if (indexct == 0) { //index off
PORTB |= _BV(3); //PB3=1:Ready Off
}
}
}
PORTB |= _BV(3); //PB3=1:Ready Off
}
return 0;
}
ATTiny85への書込みはこちらで作ったArduino UNOを使ったライターで行いました。

しばらく使ってみましたが安定して動作しています。
レベル3で使う場合はこのパラメータでもよさそうです。
ごにょごにょやっている間に5Vラインに12Vを流してATTiny85とFD-235HGを焼いてしまいました。

IBMイジェクトボタンのFD-235HGを焼いたのはかなり残念・・・
こんな感じで真っ黒のFD-235HGになってしまいました(泣
そんなレベル3用にFM7用ステップ信号2倍化プログラムを微調整してみた記録・・・
関連

こちらで作ったレベル3用外付けFDDでAT用のFDDが使えるか試してみました。使ったのはold68f…
コンピュータ

ぺるもさんから送って頂いた日立 MB-S1用ジョイスティックカードの写真から回路トレースに取りかかり…
R10

こちらで組み立てた Sasajiさん のレベル3 / S1用データセパレータ基板をFDD用のシャーシ…
コンピュータ