Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
#pragma once
2
 
3
const int Z80FQ = 3500000; // todo: #define as (conf.frame*conf.intfq)
4
const int FDD_RPS = 5; // rotation speed
5
 
6
const int MAX_TRACK_LEN = 6250;
7
const int MAX_CYLS = 86;            // don't load images with so many tracks
8
const int MAX_PHYS_CYL = 86;        // don't seek over it
9
const int MAX_SEC = 256;
10
 
11
struct SECHDR
12
{
13
   unsigned char c,s,n,l;
14
   unsigned short crc; // CRC заголовка сектора
15
 
16
   // флаги crc зоны адреса и данных:
17
   // При форматировании:
18
   //   0 - генерируется правильное значение crc
19
   //   1 - запись crc из crc(для адреса)/crcd(для данных)
20
   //   2 - ошибочный crc (генерируется инверсией правильного crc))
21
   // При чтении (функция seek устанавливает поля c1 и c2):
22
   //   0 - рассчитанное crc не совпадает с указанным в заголовке (возвращается crc error)
23
   //   1 - рассчитанное crc совпадает с указанным в заголовке
24
   unsigned char c1, c2;
25
   u8 *data; // Указатель на данные сектора внутри трэка
26
   u8 *id; // Указатель на заголовок сектора внутри трэка
27
   u8 *wp; // Указатель на битовую карту сбойных байтов сектора внутри трэка (используется только при загрузке)
28
   unsigned wp_start; // Номер первого бита в карте сбойных байтов (относительно начала трэка) для данного сектора
29
   unsigned datlen; // Размер сектора в байтах
30
   unsigned crcd;        // used to load specific CRC from FDI-file
31
};
32
 
33
enum SEEK_MODE { JUST_SEEK = 0, LOAD_SECTORS = 1 };
34
 
35
static inline bool test_bit(const u8 *data, unsigned bit)
36
{
37
    return (data[bit >> 3] & (1U << (bit & 7))) != 0;
38
}
39
 
40
static inline void set_bit(u8 *data, unsigned bit)
41
{
42
    data[bit >> 3] |= (1U << (bit & 7));
43
}
44
 
45
static inline void clr_bit(u8 *data, unsigned bit)
46
{
47
    data[bit >> 3] &= ~(1U << (bit & 7));
48
}
49
 
50
 
51
struct TRKCACHE
52
{
53
   // cached track position
54
   struct FDD *drive;
55
   unsigned cyl, side;
56
 
57
   // generic track data
58
   unsigned trklen;
59
    // pointer to data inside UDI
60
   u8 *trkd; // данные
61
   u8 *trki; // битовая карта синхроимпульсов
62
   u8 *trkwp; // битовая карта сбойных байтов
63
   unsigned ts_byte;                 // cpu.t per byte
64
   SEEK_MODE sf;                     // flag: is sectors filled
65
   unsigned s;                       // no. of sectors
66
 
67
   // sectors on track
68
   SECHDR hdr[MAX_SEC];
69
 
70
   void set_i(unsigned pos) { set_bit(trki, pos); }
71
   void clr_i(unsigned pos) { clr_bit(trki, pos); }
72
   bool test_i(unsigned pos) { return test_bit(trki, pos); }
73
 
74
   void set_wp(unsigned pos) { set_bit(trkwp, pos); }
75
   bool test_wp(unsigned pos) { return test_bit(trkwp, pos); }
76
 
77
   void write(unsigned pos, unsigned char byte, char index)
78
   {
79
       if(!trkd)
80
           return;
81
 
82
       trkd[pos] = byte;
83
       if (index)
84
           set_i(pos);
85
       else
86
           clr_i(pos);
87
   }
88
 
89
   void seek(FDD *d, unsigned cyl, unsigned side, SEEK_MODE fs);
90
   void format(); // before use, call seek(d,c,s,JUST_SEEK), set s and hdr[]
91
   int write_sector(unsigned sec, unsigned char *data); // call seek(d,c,s,LOAD_SECTORS)
92
   const SECHDR *get_sector(unsigned sec) const; // before use, call fill(d,c,s,LOAD_SECTORS)
93
 
94
   void dump();
95
   void clear()
96
   {
97
       drive = 0;
98
       trkd = 0;
99
       ts_byte = Z80FQ/(MAX_TRACK_LEN * FDD_RPS);
100
   }
101
   TRKCACHE() { clear(); }
102
};
103
 
104
 
105
struct FDD
106
{
107
   u8 Id;
108
   // drive data
109
 
110
   __int64 motor;       // 0 - not spinning, >0 - time when it'll stop
111
   unsigned char track; // head position
112
 
113
   // disk data
114
 
115
   unsigned char *rawdata;              // used in VirtualAlloc/VirtualFree
116
   unsigned rawsize;
117
   unsigned cyls, sides;
118
   unsigned trklen[MAX_CYLS][2];
119
   u8 *trkd[MAX_CYLS][2]; // данные
120
   u8 *trki[MAX_CYLS][2]; // битовые карты синхроимпульсов
121
   u8 *trkwp[MAX_CYLS][2]; // битовые карты сбойных байтов
122
   unsigned char optype; // bits: 0-not modified, 1-write sector, 2-format track
123
   unsigned char snaptype;
124
 
125
   TRKCACHE t; // used in read/write image
126
   char name[0x200];
127
   char dsc[0x200];
128
 
129
   char test();
130
   void free();
131
   int index();
132
 
133
   void format_trd(unsigned CylCnt); // Используется только для wldr_trd
134
   void emptydisk(unsigned FreeSecCnt); // Используется только для wldr_trd
135
   int addfile(unsigned char *hdr, unsigned char *data); // Используется только для wldr_trd
136
   void addboot(); // Используется только для wldr_trd
137
 
138
   void newdisk(unsigned cyls, unsigned sides);
139
 
140
   int read(unsigned char snType);
141
 
142
   int read_scl();
143
   int read_hob();
144
   int read_trd();
145
   int write_trd(FILE *ff);
146
   int read_fdi();
147
   int write_fdi(FILE *ff);
148
   int read_td0();
149
   int write_td0(FILE *ff);
150
   int read_udi();
151
   int write_udi(FILE *ff);
152
 
153
   void format_isd();
154
   int read_isd();
155
   int write_isd(FILE *ff);
156
 
157
   void format_pro();
158
   int read_pro();
159
   int write_pro(FILE *ff);
160
 
161
   ~FDD() { free(); }
162
};
163
 
164
 
165
struct WD1793
166
{
167
   enum WDSTATE
168
   {
169
      S_IDLE = 0,
170
      S_WAIT,
171
 
172
      S_DELAY_BEFORE_CMD,
173
      S_CMD_RW,
174
      S_FOUND_NEXT_ID,
175
      S_RDSEC,
176
      S_READ,
177
      S_WRSEC,
178
      S_WRITE,
179
      S_WRTRACK,
180
      S_WR_TRACK_DATA,
181
 
182
      S_TYPE1_CMD,
183
      S_STEP,
184
      S_SEEKSTART,
185
      S_RESTORE,
186
      S_SEEK,
187
      S_VERIFY,
188
      S_VERIFY2,
189
 
190
      S_WAIT_HLT,
191
      S_WAIT_HLT_RW,
192
 
193
      S_RESET
194
   };
195
 
196
   __int64 next, time;
197
   __int64 idx_tmo;
198
 
199
   FDD *seldrive;
200
   unsigned tshift;
201
 
202
   WDSTATE state, state2;
203
 
204
   unsigned char cmd;
205
   unsigned char data, track, sector;
206
   unsigned char rqs, status;
207
   u8 sign_status; // Внешние сигналы (пока только HLD)
208
 
209
   unsigned drive, side;                // update this with changing 'system'
210
 
211
   signed char stepdirection;
212
   unsigned char system;                // beta128 system register
213
 
214
   unsigned idx_cnt; // idx counter
215
 
216
   // read/write sector(s) data
217
   __int64 end_waiting_am;
218
   unsigned foundid;                    // index in trkcache.hdr for next encountered ID and bytes before this ID
219
   unsigned rwptr, rwlen;
220
 
221
   // format track data
222
   unsigned start_crc;
223
 
224
   enum CMDBITS
225
   {
226
      CMD_SEEK_RATE     = 0x03,
227
      CMD_SEEK_VERIFY   = 0x04,
228
      CMD_SEEK_HEADLOAD = 0x08,
229
      CMD_SEEK_TRKUPD   = 0x10,
230
      CMD_SEEK_DIR      = 0x20,
231
 
232
      CMD_WRITE_DEL     = 0x01,
233
      CMD_SIDE_CMP_FLAG = 0x02,
234
      CMD_DELAY         = 0x04,
235
      CMD_SIDE          = 0x08,
236
      CMD_SIDE_SHIFT    = 3,
237
      CMD_MULTIPLE      = 0x10
238
   };
239
 
240
   enum BETA_STATUS
241
   {
242
      DRQ   = 0x40,
243
      INTRQ = 0x80
244
   };
245
 
246
   enum WD_STATUS
247
   {
248
      WDS_BUSY      = 0x01,
249
      WDS_INDEX     = 0x02,
250
      WDS_DRQ       = 0x02,
251
      WDS_TRK00     = 0x04,
252
      WDS_LOST      = 0x04,
253
      WDS_CRCERR    = 0x08,
254
      WDS_NOTFOUND  = 0x10,
255
      WDS_SEEKERR   = 0x10,
256
      WDS_RECORDT   = 0x20,
257
      WDS_HEADL     = 0x20,
258
      WDS_WRFAULT   = 0x20,
259
      WDS_WRITEP    = 0x40,
260
      WDS_NOTRDY    = 0x80
261
   };
262
 
263
   enum WD_SYS
264
   {
265
      SYS_HLT       = 0x08
266
   };
267
 
268
   enum WD_SIG
269
   {
270
       SIG_HLD      = 0x01
271
   };
272
 
273
   unsigned char in(unsigned char port);
274
   void out(unsigned char port, unsigned char val);
275
   u8 RdStatus();
276
 
277
   void process();
278
   void find_marker();
279
   char notready();
280
   void load();
281
   void getindex();
282
   void trdos_traps();
283
 
284
//   TRKCACHE trkcache;
285
   FDD fdd[4];
286
 
287
   WD1793()
288
   {
289
       for(unsigned i = 0; i < 4; i++) // [vv] Для удобства отладки
290
           fdd[i].Id = i;
291
       seldrive = &fdd[0];
292
       idx_cnt = 0;
293
       idx_tmo = LLONG_MAX;
294
       sign_status = 0;
295
   }
296
};