|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // FDD
9: //
10:
11: #pragma once
12:
13: #include "device.h"
14: #include "diskimage.h"
15: #include "message.h"
16: #include "textscreen.h"
17:
18: // FD マーク
19: #define MARK_IAM (0xfc)
20: #define MARK_IDAM (0xfe)
21: #define MARK_DAM (0xfb)
22: #define MARK_DDAM (0xf8)
23:
1.1.1.2 root 24: class FDCDevice;
25: class PEDECDevice;
26:
1.1 root 27: // フロッピーディスクの 1 トラック
28: class FDTrack
29: {
30: public:
31: // トラック記録の開始
32: void Begin();
33: // トラック記録の終了
34: void End();
35: // トラックデータ追加(FDDDevice から呼ばれる)
36: void Append(uint8 data);
37: void Append(uint8 data, int count);
38:
39: // トラックデータにマーク追加
40: void AppendMark(uint8 data);
41:
42: void Clear();
43:
44: // buf[0] はインデックスホールの位置と一致させる
1.1.1.2 root 45: std::vector<uint8> buf {}; // リングアクセスバッファ
1.1 root 46: std::vector<int> markpos {}; // アドレスマーク位置
47: // SYNC の次にあるIAM,IDAM,DAM/DDAM
1.1.1.2 root 48: uint32 lba {}; // バッファしているトラックの先頭セクタのLBA
1.1 root 49: };
50:
51: class FDDDevice : public Device
52: {
53: using inherited = Device;
54: public:
55: // メディアへの書き込みモード
56: //
57: // Device Media Ignore
58: // RW RO * WriteProtect
59: // RW RW no Writeable
60: // RW RW yes WriteIgnore
61: enum class RW {
62: WriteProtect = 1, // 書き込み禁止メディア
63: Writeable = 0, // 書き込み可能
64: WriteIgnore = -1, // 書き込み可能メディアで書き込みを無視
65: };
66:
67: // アクセス LED 状態
68: enum class LED {
69: OFF = 0,
70: GREEN,
71: RED,
72: BLINK, // 緑点滅 (内部のみで使用)
73: };
74:
75: public:
1.1.1.4 root 76: explicit FDDDevice(uint unit_);
1.1 root 77: ~FDDDevice() override;
78:
79: bool Init() override;
80: void ResetHard(bool poweron) override;
81:
82: // モニタ更新 (FDC の下請け)
1.1.1.6 ! root 83: void MonitorScreenFDD(TextScreen&, uint hd);
1.1 root 84:
85: // ユニット番号を返す
86: int GetUnitNo() const { return unit; }
87:
88: // ドライブコントロールレジスタへの書き込み
89: void SetDriveCtrl(uint8);
90:
91: // ドライブセレクト入力
92: void SetDriveSelect(uint sel, bool is_2dd_);
93:
94: // MOTOR_ON 信号入力
95: void SetMotorOn(bool);
96:
97: bool GetReady() const;
98:
99: // TRK00 信号
100: bool GetTrack0() const;
101:
102: // WRITEPROTECT 信号
103: bool GetWriteProtect() const;
104:
105: // 1 step シーク実行
106: void DoSeek(int dir_);
107:
108: // インデックスホール位置なら true
109: bool IsIndex() const { return pos == 0; }
110:
111: // トラックの現在のアクセス位置の 1 バイトを取得
112: uint8 ReadByte();
113:
114: // トラックの現在のアクセス位置に 1 バイト書き込み
115: void WriteByte(uint8 data);
116:
117: // 指定した相対位置のデータを取得
118: uint8 PeekByte(int) const;
119:
120: // 次のマークまたはインデックスホールまでのバイト距離を返す。
121: int GetDistanceToMark() const;
122:
123: // トラックバッファに現在のトラックを読み込む
124: void ReadTrack(int hd);
125:
126: // トラックバッファをイメージに書き出す
127: void WriteTrack();
128:
129: // メディアが入っていれば true
130: bool IsMediumLoaded() const { return medium_loaded; }
131:
132: // メディアの書き込みモードを返す
133: RW GetWriteMode() const { return write_mode; }
134:
135: // メディア(ディスク)イメージを開く/閉じる。(同一スレッドから呼ぶこと)
136: bool LoadDisk(const std::string& path_);
137: void UnloadDisk(bool force = false);
138:
139: // メディア(ディスク)イメージを開く/閉じる。(UI スレッドから呼ぶ)
140: void LoadDiskUI(const std::string& path_);
141: void UnloadDiskUI(bool force);
142:
143: // メディアの取り出し可否
144: bool IsEjectEnable() const { return eject_enable; }
145:
146: // イメージファイルのフルパスを返す
147: const std::string& GetPathName() const { return pathname; }
148:
149: // アクセスランプの状態取得。
150: LED GetAccessLED() const;
151:
152: // イジェクトランプの状態取得。点灯なら true
153: bool GetEjectLED() const;
154:
155: private:
156: // モータ状態変更
157: void DoMotorOn();
158: void DoMotorOff();
159:
160: // モータ、LED の状態更新
161: void ChangeStatus();
162:
163: // ディスクイメージを閉じる (内部用)
164: bool UnloadDisk_internal();
165:
166: // ディスク状態をクリアする
167: void Clear();
168:
169: // メディア状態変更を UI に通知する
170: void MediaChanged() const;
171:
172: // メディア挿入/排出コールバック
1.1.1.3 root 173: void LoadMessage(MessageID, uint32);
174: void UnloadMessage(MessageID, uint32);
1.1 root 175:
176: // イベントコールバック
1.1.1.5 root 177: void EventCallback(Event *);
1.1 root 178:
1.1.1.4 root 179: uint unit {}; // ユニット番号(ドライブ番号)
1.1 root 180: bool selected {}; // FDD SELECT 入力信号で選択されていれば true
181: enum {
182: STOPPED = 0, // モータ停止中
183: SPIN_DOWN, // 停止に向けて慣性回転中
184: SPIN_UP, // モータ始動
185: READY, // 定常回転中
186: } motor_state {};
187: bool motor_on {}; // モーターオン入力信号の状態
188: bool IsMotorActive() const {
189: return (motor_state == SPIN_UP || motor_state == READY);
190: }
191: bool IsReady() const { return (motor_state == READY); }
192: bool is_blink {}; // LED ブリンク
1.1.1.4 root 193: uint cylinder {}; // 現在のシリンダ番号
194: uint pos {}; // アクセス位置
1.1 root 195:
196: // トラックバッファ
197: FDTrack trackbuf {};
198:
199: // メディアフォーマット
200: uint32 ncyl {}; // シリンダ数 (C)
201: uint32 nhead {}; // ヘッド数 (H)
202: uint32 nsect {}; // トラックあたりのセクタ数 (R)
203: uint8 format_n {}; // セクタ長 (N)
204: uint32 sectsize {}; // 1セクタあたりのバイト数
205: uint gap3 {}; // Gap3
206: uint gap4b {}; // Gap4b
207: std::string format_name {}; // フォーマット名
208:
209: // イメージファイル
210: DiskImage image {};
211:
212: bool write_ignore {}; // 書き込み無視オプション
213: bool medium_loaded {}; // メディアが挿入されていれば true
214:
215: // メディアの書き込みモード
216: RW write_mode {};
217:
218: // メディアの取り出しを許可するなら true。
219: bool eject_enable {};
220:
221: // アクセス LED の状態
222: LED access_led {};
223: // アクセス LED の点滅開始時刻
224: uint64 blink_start {};
225:
226: // イメージファイルのフルパス
227: std::string pathname {};
228: // 新しいイメージファイルのフルパス (UIから)
229: std::string new_pathname {};
230:
1.1.1.2 root 231: FDCDevice *fdc {};
232: PEDECDevice *pedec {};
233:
1.1.1.5 root 234: Event *event {};
1.1 root 235: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.