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