1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * IDE HD/ATAPI CD emulation
5 *
6 * (c) 2006 - 2015 Toni Wilen
7 */
8
9 #define IDE_LOG 2
10
11 #include "sysconfig.h"
12 #include "sysdeps.h"
13
14 #include "options.h"
15 #include "blkdev.h"
16 #include "filesys.h"
17 #include "gui.h"
18 #include "uae.h"
19 #include "memory.h"
20 #include "newcpu.h"
21 #include "threaddep/thread.h"
22 #include "debug.h"
23 #include "savestate.h"
24 #include "scsi.h"
25 #include "ide.h"
26
27 /* STATUS bits */
28 #define IDE_STATUS_ERR 0x01 // 0
29 #define IDE_STATUS_IDX 0x02 // 1
30 #define IDE_STATUS_DRQ 0x08 // 3
31 #define IDE_STATUS_DSC 0x10 // 4
32 #define IDE_STATUS_DRDY 0x40 // 6
33 #define IDE_STATUS_BSY 0x80 // 7
34 #define ATAPI_STATUS_CHK IDE_STATUS_ERR
35 /* ERROR bits */
36 #define IDE_ERR_UNC 0x40
37 #define IDE_ERR_MC 0x20
38 #define IDE_ERR_IDNF 0x10
39 #define IDE_ERR_MCR 0x08
40 #define IDE_ERR_ABRT 0x04
41 #define IDE_ERR_NM 0x02
42 #define ATAPI_ERR_EOM 0x02
43 #define ATAPI_ERR_ILI 0x01
44 /* ATAPI interrupt reason (Sector Count) */
45 #define ATAPI_IO 0x02
46 #define ATAPI_CD 0x01
47
48 #define ATAPI_MAX_TRANSFER 32768
49 #define MAX_IDE_MULTIPLE_SECTORS 128
50
51
adide_decode_word(uae_u16 w)52 uae_u16 adide_decode_word(uae_u16 w)
53 {
54 uae_u16 o = 0;
55
56 if (w & 0x8000)
57 o |= 0x0001;
58 if (w & 0x0001)
59 o |= 0x0002;
60
61 if (w & 0x4000)
62 o |= 0x0004;
63 if (w & 0x0002)
64 o |= 0x0008;
65
66 if (w & 0x2000)
67 o |= 0x0010;
68 if (w & 0x0004)
69 o |= 0x0020;
70
71 if (w & 0x1000)
72 o |= 0x0040;
73 if (w & 0x0008)
74 o |= 0x0080;
75
76 if (w & 0x0800)
77 o |= 0x0100;
78 if (w & 0x0010)
79 o |= 0x0200;
80
81 if (w & 0x0400)
82 o |= 0x0400;
83 if (w & 0x0020)
84 o |= 0x0800;
85
86 if (w & 0x0200)
87 o |= 0x1000;
88 if (w & 0x0040)
89 o |= 0x2000;
90
91 if (w & 0x0100)
92 o |= 0x4000;
93 if (w & 0x0080)
94 o |= 0x8000;
95
96 return o;
97 }
98
adide_encode_word(uae_u16 w)99 uae_u16 adide_encode_word(uae_u16 w)
100 {
101 uae_u16 o = 0;
102
103 if (w & 0x0001)
104 o |= 0x8000;
105 if (w & 0x0002)
106 o |= 0x0001;
107
108 if (w & 0x0004)
109 o |= 0x4000;
110 if (w & 0x0008)
111 o |= 0x0002;
112
113 if (w & 0x0010)
114 o |= 0x2000;
115 if (w & 0x0020)
116 o |= 0x0004;
117
118 if (w & 0x0040)
119 o |= 0x1000;
120 if (w & 0x0080)
121 o |= 0x0008;
122
123 if (w & 0x0100)
124 o |= 0x0800;
125 if (w & 0x0200)
126 o |= 0x0010;
127
128 if (w & 0x0400)
129 o |= 0x0400;
130 if (w & 0x0800)
131 o |= 0x0020;
132
133 if (w & 0x1000)
134 o |= 0x0200;
135 if (w & 0x2000)
136 o |= 0x0040;
137
138 if (w & 0x4000)
139 o |= 0x0100;
140 if (w & 0x8000)
141 o |= 0x0080;
142
143 return o;
144 }
145
ide_grow_buffer(struct ide_hdf * ide,int newsize)146 static void ide_grow_buffer(struct ide_hdf *ide, int newsize)
147 {
148 if (ide->secbuf_size >= newsize)
149 return;
150 uae_u8 *oldbuf = ide->secbuf;
151 int oldsize = ide->secbuf_size;
152 ide->secbuf_size = newsize + 16384;
153 if (oldsize)
154 write_log(_T("IDE%d buffer %d -> %d\n"), ide->num, oldsize, ide->secbuf_size);
155 ide->secbuf = xmalloc(uae_u8, ide->secbuf_size);
156 memcpy(ide->secbuf, oldbuf, oldsize);
157 xfree(oldbuf);
158 }
159
pw(struct ide_hdf * ide,int offset,uae_u16 w)160 static void pw (struct ide_hdf *ide, int offset, uae_u16 w)
161 {
162 if (ide->byteswap) {
163 w = (w >> 8) | (w << 8);
164 }
165 if (ide->adide)
166 w = adide_decode_word(w);
167 ide->secbuf[offset * 2 + 0] = (uae_u8)w;
168 ide->secbuf[offset * 2 + 1] = w >> 8;
169 }
170
ps(struct ide_hdf * ide,int offset,const TCHAR * src,int max)171 static void ps (struct ide_hdf *ide, int offset, const TCHAR *src, int max)
172 {
173 int i, len;
174 char *s;
175
176 s = ua (src);
177 len = strlen (s);
178 for (i = 0; i < max; i += 2) {
179 char c1 = ' ';
180 if (i < len)
181 c1 = s[i];
182 char c2 = ' ';
183 if (i + 1 < len)
184 c2 = s[i + 1];
185 uae_u16 w = (c1 << 0) | (c2 << 8);
186 if (ide->byteswap) {
187 w = (w >> 8) | (w << 8);
188 }
189 if (ide->adide)
190 w = adide_decode_word(w);
191 ide->secbuf[offset * 2 + 0] = w >> 8;
192 ide->secbuf[offset * 2 + 1] = w >> 0;
193 offset++;
194 }
195 xfree (s);
196 }
197
ide_isdrive(struct ide_hdf * ide)198 bool ide_isdrive (struct ide_hdf *ide)
199 {
200 return ide && (ide->hdhfd.size != 0 || ide->atapi);
201 }
202
ide_interrupt(struct ide_hdf * ide)203 static void ide_interrupt (struct ide_hdf *ide)
204 {
205 ide->regs.ide_status |= IDE_STATUS_BSY;
206 ide->regs.ide_status &= ~IDE_STATUS_DRQ;
207 ide->irq_delay = 2;
208 }
209
ide_fast_interrupt(struct ide_hdf * ide)210 static void ide_fast_interrupt (struct ide_hdf *ide)
211 {
212 ide->regs.ide_status |= IDE_STATUS_BSY;
213 ide->regs.ide_status &= ~IDE_STATUS_DRQ;
214 ide->irq_delay = 1;
215 }
216
ide_interrupt_do(struct ide_hdf * ide)217 static bool ide_interrupt_do (struct ide_hdf *ide)
218 {
219 uae_u8 os = ide->regs.ide_status;
220 ide->regs.ide_status &= ~IDE_STATUS_DRQ;
221 if (ide->intdrq)
222 ide->regs.ide_status |= IDE_STATUS_DRQ;
223 ide->regs.ide_status &= ~IDE_STATUS_BSY;
224 if (IDE_LOG > 1)
225 write_log (_T("IDE INT %02X -> %02X\n"), os, ide->regs.ide_status);
226 ide->intdrq = false;
227 ide->irq_delay = 0;
228 if (ide->regs.ide_devcon & 2)
229 return false;
230 ide->irq_new = true;
231 ide->irq = 1;
232 return true;
233 }
234
ide_drq_check(struct ide_hdf * idep)235 bool ide_drq_check(struct ide_hdf *idep)
236 {
237 for (int i = 0; idep && i < 2; i++) {
238 struct ide_hdf *ide = i == 0 ? idep : idep->pair;
239 if (ide) {
240 if (ide->regs.ide_status & IDE_STATUS_DRQ)
241 return true;
242 }
243 }
244 return false;
245 }
246
ide_irq_check(struct ide_hdf * idep,bool edge_triggered)247 bool ide_irq_check(struct ide_hdf *idep, bool edge_triggered)
248 {
249 for (int i = 0; idep && i < 2; i++) {
250 struct ide_hdf *ide = i == 0 ? idep : idep->pair;
251 if (ide->irq) {
252 if (edge_triggered) {
253 if (ide->irq_new) {
254 ide->irq_new = false;
255 return true;
256 }
257 continue;
258 }
259 return true;
260 }
261 }
262 return false;
263 }
264
ide_interrupt_hsync(struct ide_hdf * idep)265 bool ide_interrupt_hsync(struct ide_hdf *idep)
266 {
267 bool irq = false;
268 for (int i = 0; idep && i < 2; i++) {
269 struct ide_hdf *ide = i == 0 ? idep : idep->pair;
270 if (ide) {
271 if (ide->irq_delay > 0) {
272 ide->irq_delay--;
273 if (ide->irq_delay == 0) {
274 ide_interrupt_do (ide);
275 }
276 }
277 if (ide->irq && !(ide->regs.ide_devcon & 2))
278 irq = true;
279 }
280 }
281 return irq;
282 }
283
ide_fail_err(struct ide_hdf * ide,uae_u8 err)284 static void ide_fail_err (struct ide_hdf *ide, uae_u8 err)
285 {
286 ide->regs.ide_error |= err;
287 if (ide->ide_drv == 1 && !ide_isdrive (ide->pair)) {
288 ide->pair->regs.ide_status |= IDE_STATUS_ERR;
289 }
290 ide->regs.ide_status |= IDE_STATUS_ERR;
291 ide_interrupt (ide);
292 }
293
ide_fail(struct ide_hdf * ide)294 static void ide_fail (struct ide_hdf *ide)
295 {
296 ide_fail_err (ide, IDE_ERR_ABRT);
297 }
298
ide_data_ready(struct ide_hdf * ide)299 static void ide_data_ready (struct ide_hdf *ide)
300 {
301 memset (ide->secbuf, 0, ide->blocksize);
302 ide->data_offset = 0;
303 ide->data_size = ide->blocksize;
304 ide->data_multi = 1;
305 ide->intdrq = true;
306 ide_interrupt (ide);
307 }
308
ide_recalibrate(struct ide_hdf * ide)309 static void ide_recalibrate (struct ide_hdf *ide)
310 {
311 write_log (_T("IDE%d recalibrate\n"), ide->num);
312 ide->regs.ide_sector = 0;
313 ide->regs.ide_lcyl = ide->regs.ide_hcyl = 0;
314 ide_interrupt (ide);
315 }
316
ide_identify_drive(struct ide_hdf * ide)317 static void ide_identify_drive (struct ide_hdf *ide)
318 {
319 uae_u64 totalsecs;
320 int v;
321 uae_u8 *buf = ide->secbuf;
322 TCHAR tmp[100];
323 bool atapi = ide->atapi;
324 bool cf = ide->media_type > 0;
325
326 if (!ide_isdrive (ide)) {
327 ide_fail (ide);
328 return;
329 }
330 memset (buf, 0, ide->blocksize);
331 ide->byteswapped_buffer = 1;
332 if (IDE_LOG > 0)
333 write_log (_T("IDE%d identify drive\n"), ide->num);
334 ide_data_ready (ide);
335 ide->direction = 0;
336 pw (ide, 0, atapi ? 0x85c0 : (cf ? 0x848a : (1 << 6)));
337 pw (ide, 1, ide->hdhfd.cyls_def);
338 pw (ide, 2, 0xc837);
339 pw (ide, 3, ide->hdhfd.heads_def);
340 pw (ide, 4, ide->blocksize * ide->hdhfd.secspertrack_def);
341 pw (ide, 5, ide->blocksize);
342 pw (ide, 6, ide->hdhfd.secspertrack_def);
343 ps (ide, 10, _T("68000"), 20); /* serial */
344 pw (ide, 20, 3);
345 pw (ide, 21, ide->blocksize);
346 pw (ide, 22, 4);
347 ps (ide, 23, _T("0.7"), 8); /* firmware revision */
348 if (ide->atapi)
349 _tcscpy (tmp, _T("UAE-ATAPI"));
350 else
351 _stprintf (tmp, _T("UAE-IDE %s"), ide->hdhfd.hfd.product_id);
352 ps (ide, 27, tmp, 40); /* model */
353 pw (ide, 47, MAX_IDE_MULTIPLE_SECTORS >> (ide->blocksize / 512 - 1)); /* max sectors in multiple mode */
354 pw (ide, 48, 1);
355 pw (ide, 49, (1 << 9) | (1 << 8)); /* LBA and DMA supported */
356 pw (ide, 51, 0x200); /* PIO cycles */
357 pw (ide, 52, 0x200); /* DMA cycles */
358 pw (ide, 53, 1 | 2 | 4);
359 pw (ide, 54, ide->hdhfd.cyls);
360 pw (ide, 55, ide->hdhfd.heads);
361 pw (ide, 56, ide->hdhfd.secspertrack);
362 totalsecs = ide->hdhfd.cyls * ide->hdhfd.heads * ide->hdhfd.secspertrack;
363 pw (ide, 57, (uae_u16)totalsecs);
364 pw (ide, 58, (uae_u16)(totalsecs >> 16));
365 v = ide->multiple_mode;
366 pw (ide, 59, (v > 0 ? 0x100 : 0) | v);
367 totalsecs = ide->blocksize ? ide->hdhfd.size / ide->blocksize : 0;
368 if (totalsecs > 0x0fffffff)
369 totalsecs = 0x0fffffff;
370 pw (ide, 60, (uae_u16)totalsecs);
371 pw (ide, 61, (uae_u16)(totalsecs >> 16));
372 pw (ide, 62, 0x0f);
373 pw (ide, 63, 0x0f);
374 if (ide->ata_level) {
375 pw (ide, 64, ide->ata_level ? 0x03 : 0x00); /* PIO3 and PIO4 */
376 pw (ide, 65, 120); /* MDMA2 supported */
377 pw (ide, 66, 120);
378 pw (ide, 67, 120);
379 pw (ide, 68, 120);
380 pw (ide, 80, (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)); /* ATA-1 to ATA-6 */
381 pw (ide, 81, 0x1c); /* ATA revision */
382 pw (ide, 82, (1 << 14) | (atapi ? 0x10 | 4 : 0)); /* NOP, ATAPI: PACKET and Removable media features supported */
383 pw (ide, 83, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 supported */
384 pw (ide, 84, 1 << 14);
385 pw (ide, 85, 1 << 14);
386 pw (ide, 86, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 enabled */
387 pw (ide, 87, 1 << 14);
388 pw (ide, 88, (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); /* UDMA modes */
389 pw (ide, 93, (1 << 14) | (1 << 13) | (1 << 0));
390 if (ide->lba48) {
391 totalsecs = ide->hdhfd.size / ide->blocksize;
392 pw (ide, 100, (uae_u16)(totalsecs >> 0));
393 pw (ide, 101, (uae_u16)(totalsecs >> 16));
394 pw (ide, 102, (uae_u16)(totalsecs >> 32));
395 pw (ide, 103, (uae_u16)(totalsecs >> 48));
396 }
397 }
398 }
399
set_signature(struct ide_hdf * ide)400 static void set_signature (struct ide_hdf *ide)
401 {
402 if (ide->atapi) {
403 ide->regs.ide_sector = 1;
404 ide->regs.ide_nsector = 1;
405 ide->regs.ide_lcyl = 0x14;
406 ide->regs.ide_hcyl = 0xeb;
407 ide->regs.ide_status = 0;
408 ide->atapi_drdy = false;
409 } else {
410 ide->regs.ide_nsector = 1;
411 ide->regs.ide_sector = 1;
412 ide->regs.ide_lcyl = 0;
413 ide->regs.ide_hcyl = 0;
414 ide->regs.ide_status = 0;
415 }
416 ide->regs.ide_error = 0x01; // device ok
417 ide->packet_state = 0;
418 }
419
reset_device(struct ide_hdf * ide,bool both)420 static void reset_device (struct ide_hdf *ide, bool both)
421 {
422 set_signature (ide);
423 if (both)
424 set_signature (ide->pair);
425 }
426
ide_reset_device(struct ide_hdf * ide)427 void ide_reset_device(struct ide_hdf *ide)
428 {
429 reset_device(ide, true);
430 }
431
ide_execute_drive_diagnostics(struct ide_hdf * ide,bool irq)432 static void ide_execute_drive_diagnostics (struct ide_hdf *ide, bool irq)
433 {
434 reset_device (ide, irq);
435 if (irq)
436 ide_interrupt (ide);
437 else
438 ide->regs.ide_status &= ~IDE_STATUS_BSY;
439 }
440
ide_initialize_drive_parameters(struct ide_hdf * ide)441 static void ide_initialize_drive_parameters (struct ide_hdf *ide)
442 {
443 if (ide->hdhfd.size) {
444 ide->hdhfd.secspertrack = ide->regs.ide_nsector == 0 ? 256 : ide->regs.ide_nsector;
445 ide->hdhfd.heads = (ide->regs.ide_select & 15) + 1;
446 if (ide->hdhfd.hfd.ci.pcyls)
447 ide->hdhfd.cyls = ide->hdhfd.hfd.ci.pcyls;
448 else
449 ide->hdhfd.cyls = (ide->hdhfd.size / ide->blocksize) / (ide->hdhfd.secspertrack * ide->hdhfd.heads);
450 if (ide->hdhfd.heads * ide->hdhfd.cyls * ide->hdhfd.secspertrack > 16515072 || ide->lba48) {
451 if (ide->hdhfd.hfd.ci.pcyls)
452 ide->hdhfd.cyls = ide->hdhfd.hfd.ci.pcyls;
453 else
454 ide->hdhfd.cyls = ide->hdhfd.cyls_def;
455 ide->hdhfd.heads = ide->hdhfd.heads_def;
456 ide->hdhfd.secspertrack = ide->hdhfd.secspertrack_def;
457 }
458 } else {
459 ide->regs.ide_error |= IDE_ERR_ABRT;
460 ide->regs.ide_status |= IDE_STATUS_ERR;
461 }
462 write_log (_T("IDE%d initialize drive parameters, CYL=%d,SPT=%d,HEAD=%d\n"),
463 ide->num, ide->hdhfd.cyls, ide->hdhfd.secspertrack, ide->hdhfd.heads);
464 ide_interrupt (ide);
465 }
466
ide_set_multiple_mode(struct ide_hdf * ide)467 static void ide_set_multiple_mode (struct ide_hdf *ide)
468 {
469 write_log (_T("IDE%d drive multiple mode = %d\n"), ide->num, ide->regs.ide_nsector);
470 ide->multiple_mode = ide->regs.ide_nsector;
471 ide_interrupt (ide);
472 }
473
ide_set_features(struct ide_hdf * ide)474 static void ide_set_features (struct ide_hdf *ide)
475 {
476 int type = ide->regs.ide_nsector >> 3;
477 int mode = ide->regs.ide_nsector & 7;
478
479 write_log (_T("IDE%d set features %02X (%02X)\n"), ide->num, ide->regs.ide_feat, ide->regs.ide_nsector);
480 switch (ide->regs.ide_feat)
481 {
482 // 8-bit mode
483 case 1:
484 ide->mode_8bit = true;
485 ide_interrupt(ide);
486 break;
487 case 0x81:
488 ide->mode_8bit = false;
489 ide_interrupt(ide);
490 break;
491 // write cache
492 case 2:
493 case 0x82:
494 ide_interrupt(ide);
495 break;
496 default:
497 ide_fail (ide);
498 break;
499 }
500 }
501
get_lbachs(struct ide_hdf * ide,uae_u64 * lbap,unsigned int * cyl,unsigned int * head,unsigned int * sec)502 static void get_lbachs (struct ide_hdf *ide, uae_u64 *lbap, unsigned int *cyl, unsigned int *head, unsigned int *sec)
503 {
504 if (ide->lba48 && ide->lba48cmd && (ide->regs.ide_select & 0x40)) {
505 uae_u64 lba;
506 lba = (ide->regs.ide_hcyl << 16) | (ide->regs.ide_lcyl << 8) | ide->regs.ide_sector;
507 lba |= ((ide->regs.ide_hcyl2 << 16) | (ide->regs.ide_lcyl2 << 8) | ide->regs.ide_sector2) << 24;
508 *lbap = lba;
509 } else {
510 if (ide->regs.ide_select & 0x40) {
511 *lbap = ((ide->regs.ide_select & 15) << 24) | (ide->regs.ide_hcyl << 16) | (ide->regs.ide_lcyl << 8) | ide->regs.ide_sector;
512 } else {
513 *cyl = (ide->regs.ide_hcyl << 8) | ide->regs.ide_lcyl;
514 *head = ide->regs.ide_select & 15;
515 *sec = ide->regs.ide_sector;
516 *lbap = (((*cyl) * ide->hdhfd.heads + (*head)) * ide->hdhfd.secspertrack) + (*sec) - 1;
517 }
518 }
519 }
520
get_nsec(struct ide_hdf * ide)521 static int get_nsec (struct ide_hdf *ide)
522 {
523 if (ide->lba48 && ide->lba48cmd)
524 return (ide->regs.ide_nsector == 0 && ide->regs.ide_nsector2 == 0) ? 65536 : (ide->regs.ide_nsector2 * 256 + ide->regs.ide_nsector);
525 else
526 return ide->regs.ide_nsector == 0 ? 256 : ide->regs.ide_nsector;
527 }
dec_nsec(struct ide_hdf * ide,int v)528 static int dec_nsec (struct ide_hdf *ide, int v)
529 {
530 if (ide->lba48 && ide->lba48cmd) {
531 uae_u16 nsec;
532 nsec = (ide->regs.ide_nsector2 << 8) | ide->regs.ide_nsector;
533 nsec -= v;
534 ide->regs.ide_nsector2 = nsec >> 8;
535 ide->regs.ide_nsector = nsec & 0xff;
536 return (ide->regs.ide_nsector2 << 8) | ide->regs.ide_nsector;
537 } else {
538 ide->regs.ide_nsector -= v;
539 return ide->regs.ide_nsector;
540 }
541 }
542
put_lbachs(struct ide_hdf * ide,uae_u64 lba,unsigned int cyl,unsigned int head,unsigned int sec,unsigned int inc)543 static void put_lbachs (struct ide_hdf *ide, uae_u64 lba, unsigned int cyl, unsigned int head, unsigned int sec, unsigned int inc)
544 {
545 if (ide->lba48 && ide->lba48cmd) {
546 lba += inc;
547 ide->regs.ide_hcyl = (lba >> 16) & 0xff;
548 ide->regs.ide_lcyl = (lba >> 8) & 0xff;
549 ide->regs.ide_sector = lba & 0xff;
550 lba >>= 24;
551 ide->regs.ide_hcyl2 = (lba >> 16) & 0xff;
552 ide->regs.ide_lcyl2 = (lba >> 8) & 0xff;
553 ide->regs.ide_sector2 = lba & 0xff;
554 } else {
555 if (ide->regs.ide_select & 0x40) {
556 lba += inc;
557 ide->regs.ide_select &= ~15;
558 ide->regs.ide_select |= (lba >> 24) & 15;
559 ide->regs.ide_hcyl = (lba >> 16) & 0xff;
560 ide->regs.ide_lcyl = (lba >> 8) & 0xff;
561 ide->regs.ide_sector = lba & 0xff;
562 } else {
563 sec += inc;
564 while (sec >= ide->hdhfd.secspertrack) {
565 sec -= ide->hdhfd.secspertrack;
566 head++;
567 if (head >= ide->hdhfd.heads) {
568 head -= ide->hdhfd.heads;
569 cyl++;
570 }
571 }
572 ide->regs.ide_select &= ~15;
573 ide->regs.ide_select |= head;
574 ide->regs.ide_sector = sec;
575 ide->regs.ide_hcyl = cyl >> 8;
576 ide->regs.ide_lcyl = (uae_u8)cyl;
577 }
578 }
579 }
580
check_maxtransfer(struct ide_hdf * ide,int state)581 static void check_maxtransfer (struct ide_hdf *ide, int state)
582 {
583 if (state == 1) {
584 // transfer was started
585 if (ide->maxtransferstate < 2 && ide->regs.ide_nsector == 0) {
586 ide->maxtransferstate = 1;
587 } else if (ide->maxtransferstate == 2) {
588 // second transfer was started (part of split)
589 write_log (_T("IDE maxtransfer check detected split >256 block transfer\n"));
590 ide->maxtransferstate = 0;
591 } else {
592 ide->maxtransferstate = 0;
593 }
594 } else if (state == 2) {
595 // address was read
596 if (ide->maxtransferstate == 1)
597 ide->maxtransferstate++;
598 else
599 ide->maxtransferstate = 0;
600 }
601 }
602
setdrq(struct ide_hdf * ide)603 static void setdrq (struct ide_hdf *ide)
604 {
605 ide->regs.ide_status |= IDE_STATUS_DRQ;
606 ide->regs.ide_status &= ~IDE_STATUS_BSY;
607 }
setbsy(struct ide_hdf * ide)608 static void setbsy (struct ide_hdf *ide)
609 {
610 ide->regs.ide_status |= IDE_STATUS_BSY;
611 ide->regs.ide_status &= ~IDE_STATUS_DRQ;
612 }
613
process_rw_command(struct ide_hdf * ide)614 static void process_rw_command (struct ide_hdf *ide)
615 {
616 setbsy (ide);
617 write_comm_pipe_u32 (&ide->its->requests, ide->num, 1);
618 }
process_packet_command(struct ide_hdf * ide)619 static void process_packet_command (struct ide_hdf *ide)
620 {
621 setbsy (ide);
622 write_comm_pipe_u32 (&ide->its->requests, ide->num | 0x80, 1);
623 }
624
atapi_data_done(struct ide_hdf * ide)625 static void atapi_data_done (struct ide_hdf *ide)
626 {
627 ide->regs.ide_nsector = ATAPI_IO | ATAPI_CD;
628 ide->regs.ide_status = IDE_STATUS_DRDY;
629 ide->data_size = 0;
630 ide->packet_data_offset = 0;
631 ide->data_offset = 0;
632 }
633
atapi_set_size(struct ide_hdf * ide)634 static bool atapi_set_size (struct ide_hdf *ide)
635 {
636 int size;
637 size = ide->data_size;
638 ide->data_offset = 0;
639 if (!size) {
640 ide->packet_state = 0;
641 ide->packet_transfer_size = 0;
642 return false;
643 }
644 if (ide->packet_state == 2) {
645 if (size > ide->packet_data_size)
646 size = ide->packet_data_size;
647 if (size > ATAPI_MAX_TRANSFER)
648 size = ATAPI_MAX_TRANSFER;
649 ide->packet_transfer_size = size & ~1;
650 ide->regs.ide_lcyl = size & 0xff;
651 ide->regs.ide_hcyl = size >> 8;
652 } else {
653 ide->packet_transfer_size = 12;
654 }
655 if (IDE_LOG > 1)
656 write_log (_T("ATAPI data transfer %d/%d bytes\n"), ide->packet_transfer_size, ide->data_size);
657 return true;
658 }
659
atapi_packet(struct ide_hdf * ide)660 static void atapi_packet (struct ide_hdf *ide)
661 {
662 ide->packet_data_offset = 0;
663 ide->packet_data_size = (ide->regs.ide_hcyl << 8) | ide->regs.ide_lcyl;
664 if (ide->packet_data_size == 65535)
665 ide->packet_data_size = 65534;
666 ide->data_size = 12;
667 if (IDE_LOG > 0)
668 write_log (_T("ATAPI packet command. Data size = %d\n"), ide->packet_data_size);
669 ide->packet_state = 1;
670 ide->data_multi = 1;
671 ide->data_offset = 0;
672 ide->regs.ide_nsector = ATAPI_CD;
673 ide->regs.ide_error = 0;
674 if (atapi_set_size (ide))
675 setdrq (ide);
676 }
677
do_packet_command(struct ide_hdf * ide)678 static void do_packet_command (struct ide_hdf *ide)
679 {
680 memcpy (ide->scsi->cmd, ide->secbuf, 12);
681 ide->scsi->cmd_len = 12;
682 if (IDE_LOG > 0) {
683 uae_u8 *c = ide->scsi->cmd;
684 write_log (_T("ATASCSI %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n"),
685 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], c[11]);
686 }
687 ide->direction = 0;
688 scsi_emulate_analyze (ide->scsi);
689 if (ide->scsi->direction <= 0) {
690 // data in
691 scsi_emulate_cmd (ide->scsi);
692 ide->data_size = ide->scsi->data_len;
693 ide->regs.ide_status = 0;
694 if (ide->scsi->status) {
695 // error
696 ide->regs.ide_error = (ide->scsi->sense[2] << 4) | 4;
697 atapi_data_done (ide);
698 ide->regs.ide_status |= ATAPI_STATUS_CHK;
699 atapi_set_size (ide);
700 return;
701 } else if (ide->scsi->data_len) {
702 // data in
703 ide_grow_buffer(ide, ide->scsi->data_len);
704 memcpy (ide->secbuf, ide->scsi->buffer, ide->scsi->data_len);
705 ide->regs.ide_nsector = ATAPI_IO;
706 } else {
707 // no data
708 atapi_data_done (ide);
709 }
710 } else {
711 // data out
712 ide->direction = 1;
713 ide->regs.ide_nsector = 0;
714 ide->data_size = ide->scsi->data_len;
715 }
716 ide->packet_state = 2; // data phase
717 if (atapi_set_size (ide))
718 ide->intdrq = true;
719 }
720
do_process_packet_command(struct ide_hdf * ide)721 static void do_process_packet_command (struct ide_hdf *ide)
722 {
723 if (ide->packet_state == 1) {
724 do_packet_command (ide);
725 } else {
726 ide->packet_data_offset += ide->packet_transfer_size;
727 if (!ide->direction) {
728 // data still remaining, next transfer
729 if (atapi_set_size (ide))
730 ide->intdrq = true;
731 } else {
732 if (atapi_set_size (ide)) {
733 ide->intdrq = true;
734 } else {
735 if (IDE_LOG > 1)
736 write_log(_T("IDE%d ATAPI write finished, %d bytes\n"), ide->num, ide->data_size);
737 memcpy (&ide->scsi->buffer, ide->secbuf, ide->data_size);
738 ide->scsi->data_len = ide->data_size;
739 scsi_emulate_cmd (ide->scsi);
740 }
741 }
742 }
743 ide_fast_interrupt (ide);
744 }
745
do_process_rw_command(struct ide_hdf * ide)746 static void do_process_rw_command (struct ide_hdf *ide)
747 {
748 unsigned int cyl, head, sec, nsec, nsec_total;
749 uae_u64 lba;
750 bool last;
751
752 ide->data_offset = 0;
753 nsec = get_nsec (ide);
754 get_lbachs (ide, &lba, &cyl, &head, &sec);
755 if (IDE_LOG > 1)
756 write_log (_T("IDE%d off=%d, nsec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
757 if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) {
758 nsec = (ide->hdhfd.size - lba * ide->blocksize) / ide->blocksize;
759 if (IDE_LOG > 1)
760 write_log (_T("IDE%d nsec changed to %d\n"), ide->num, nsec);
761 }
762 if (nsec <= 0) {
763 ide_data_ready (ide);
764 ide_fail_err (ide, IDE_ERR_IDNF);
765 return;
766 }
767 nsec_total = nsec;
768 ide_grow_buffer(ide, nsec_total * ide->blocksize);
769
770 if (nsec > ide->data_multi)
771 nsec = ide->data_multi;
772
773 if (ide->buffer_offset == 0) {
774 // store initial lba and number of sectors to transfer
775 ide->start_lba = lba;
776 ide->start_nsec = nsec_total;
777 }
778
779 if (ide->direction) {
780 if (IDE_LOG > 1)
781 write_log (_T("IDE%d write, %d/%d bytes, buffer offset %d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset);
782 } else {
783 if (ide->buffer_offset == 0) {
784 hdf_read(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize);
785 if (IDE_LOG > 1)
786 write_log(_T("IDE%d initial read, %d bytes\n"), ide->num, nsec_total * ide->blocksize);
787 }
788 if (IDE_LOG > 1)
789 write_log (_T("IDE%d read, read %d/%d bytes, buffer offset=%d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset);
790 }
791 ide->intdrq = true;
792 last = dec_nsec (ide, nsec) == 0;
793 // ATA-2 spec says CHS/LBA does only need to be updated if error condition
794 if (ide->ata_level != 2 || !last) {
795 put_lbachs (ide, lba, cyl, head, sec, last ? nsec - 1 : nsec);
796 }
797 if (last && ide->direction) {
798 if (IDE_LOG > 1)
799 write_log(_T("IDE%d write finished, %d bytes\n"), ide->num, ide->start_nsec * ide->blocksize);
800 ide->intdrq = false;
801 hdf_write (&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize);
802 }
803
804 if (ide->direction) {
805 if (last) {
806 ide_fast_interrupt(ide);
807 } else {
808 ide->irq_delay = 1;
809 }
810 } else {
811 if (ide->buffer_offset == 0) {
812 ide_fast_interrupt(ide);
813 } else {
814 ide->irq_delay = 1;
815 }
816 }
817 }
818
ide_read_sectors(struct ide_hdf * ide,int flags)819 static void ide_read_sectors (struct ide_hdf *ide, int flags)
820 {
821 unsigned int cyl, head, sec, nsec;
822 uae_u64 lba;
823 int multi = flags & 1;
824
825 ide->lba48cmd = (flags & 2) != 0;
826 if (multi && ide->multiple_mode == 0) {
827 ide_fail (ide);
828 return;
829 }
830 check_maxtransfer (ide, 1);
831 gui_flicker_led (LED_HD, ide->num, 1);
832 nsec = get_nsec (ide);
833 get_lbachs (ide, &lba, &cyl, &head, &sec);
834 if (lba * ide->blocksize >= ide->hdhfd.size) {
835 ide_data_ready (ide);
836 ide_fail_err (ide, IDE_ERR_IDNF);
837 return;
838 }
839 if (IDE_LOG > 0)
840 write_log (_T("IDE%d %s off=%d, sec=%d (%d) lba48=%d\n"),
841 ide->num, (flags & 4) ? _T("verify") : _T("read"), (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
842 if (flags & 4) {
843 // verify
844 ide_interrupt(ide);
845 return;
846 }
847
848 ide->data_multi = multi ? ide->multiple_mode : 1;
849 ide->data_offset = 0;
850 ide->data_size = nsec * ide->blocksize;
851 ide->direction = 0;
852 ide->buffer_offset = 0;
853 // read start: preload sector(s), then trigger interrupt.
854 process_rw_command (ide);
855 }
856
ide_write_sectors(struct ide_hdf * ide,int flags)857 static void ide_write_sectors (struct ide_hdf *ide, int flags)
858 {
859 unsigned int cyl, head, sec, nsec;
860 uae_u64 lba;
861 int multi = flags & 1;
862
863 ide->lba48cmd = (flags & 2) != 0;
864 if (multi && ide->multiple_mode == 0) {
865 ide_fail (ide);
866 return;
867 }
868 check_maxtransfer (ide, 1);
869 gui_flicker_led (LED_HD, ide->num, 2);
870 nsec = get_nsec (ide);
871 get_lbachs (ide, &lba, &cyl, &head, &sec);
872 if (lba * ide->blocksize >= ide->hdhfd.size) {
873 ide_data_ready (ide);
874 ide_fail_err (ide, IDE_ERR_IDNF);
875 return;
876 }
877 if (IDE_LOG > 0)
878 write_log (_T("IDE%d write off=%d, sec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
879 if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize)
880 nsec = (ide->hdhfd.size - lba * ide->blocksize) / ide->blocksize;
881 if (nsec <= 0) {
882 ide_data_ready (ide);
883 ide_fail_err (ide, IDE_ERR_IDNF);
884 return;
885 }
886 ide->data_multi = multi ? ide->multiple_mode : 1;
887 ide->data_offset = 0;
888 ide->data_size = nsec * ide->blocksize;
889 ide->direction = 1;
890 ide->buffer_offset = 0;
891 // write start: set DRQ and clear BSY. No interrupt.
892 ide->regs.ide_status |= IDE_STATUS_DRQ;
893 ide->regs.ide_status &= ~IDE_STATUS_BSY;
894 }
895
ide_do_command(struct ide_hdf * ide,uae_u8 cmd)896 static void ide_do_command (struct ide_hdf *ide, uae_u8 cmd)
897 {
898 int lba48 = ide->lba48;
899
900 if (IDE_LOG > 1)
901 write_log (_T("**** IDE%d command %02X\n"), ide->num, cmd);
902 ide->regs.ide_status &= ~ (IDE_STATUS_DRDY | IDE_STATUS_DRQ | IDE_STATUS_ERR);
903 ide->regs.ide_error = 0;
904 ide->intdrq = false;
905 ide->lba48cmd = false;
906 ide->byteswapped_buffer = 0;
907
908 if (ide->atapi) {
909
910 gui_flicker_led (LED_CD, ide->num, 1);
911 ide->atapi_drdy = true;
912 if (cmd == 0x00) { /* nop */
913 ide_interrupt (ide);
914 } else if (cmd == 0x08) { /* device reset */
915 ide_execute_drive_diagnostics (ide, true);
916 } else if (cmd == 0xa1) { /* identify packet device */
917 ide_identify_drive (ide);
918 } else if (cmd == 0xa0) { /* packet */
919 atapi_packet (ide);
920 } else if (cmd == 0x90) { /* execute drive diagnostics */
921 ide_execute_drive_diagnostics (ide, true);
922 } else {
923 ide_execute_drive_diagnostics (ide, false);
924 ide->atapi_drdy = false;
925 ide_fail (ide);
926 write_log (_T("IDE%d: unknown ATAPI command 0x%02x\n"), ide->num, cmd);
927 }
928
929 } else {
930
931 if (cmd == 0x10) { /* recalibrate */
932 ide_recalibrate (ide);
933 } else if (cmd == 0xec) { /* identify drive */
934 ide_identify_drive (ide);
935 } else if (cmd == 0x90) { /* execute drive diagnostics */
936 ide_execute_drive_diagnostics (ide, true);
937 } else if (cmd == 0x91) { /* initialize drive parameters */
938 ide_initialize_drive_parameters (ide);
939 } else if (cmd == 0xc6) { /* set multiple mode */
940 ide_set_multiple_mode (ide);
941 } else if (cmd == 0x20 || cmd == 0x21) { /* read sectors */
942 ide_read_sectors(ide, 0);
943 } else if (cmd == 0x40 || cmd == 0x41) { /* verify sectors */
944 ide_read_sectors(ide, 4);
945 } else if (cmd == 0x24 && lba48) { /* read sectors ext */
946 ide_read_sectors (ide, 2);
947 } else if (cmd == 0xc4) { /* read multiple */
948 ide_read_sectors (ide, 1);
949 } else if (cmd == 0x29 && lba48) { /* read multiple ext */
950 ide_read_sectors (ide, 1|2);
951 } else if (cmd == 0x30 || cmd == 0x31) { /* write sectors */
952 ide_write_sectors (ide, 0);
953 } else if (cmd == 0x34 && lba48) { /* write sectors ext */
954 ide_write_sectors (ide, 2);
955 } else if (cmd == 0xc5) { /* write multiple */
956 ide_write_sectors (ide, 1);
957 } else if (cmd == 0x39 && lba48) { /* write multiple ext */
958 ide_write_sectors (ide, 1|2);
959 } else if (cmd == 0x50) { /* format track (nop) */
960 ide_interrupt (ide);
961 } else if (cmd == 0xef) { /* set features */
962 ide_set_features (ide);
963 } else if (cmd == 0x00) { /* nop */
964 ide_fail (ide);
965 } else if (cmd == 0x70) { /* seek */
966 ide_interrupt (ide);
967 } else if (cmd == 0xe0 || cmd == 0xe1 || cmd == 0xe7 || cmd == 0xea) { /* standby now/idle/flush cache/flush cache ext */
968 ide_interrupt (ide);
969 } else if (cmd == 0xe5) { /* check power mode */
970 ide->regs.ide_nsector = 0xff;
971 ide_interrupt (ide);
972 } else {
973 ide_fail (ide);
974 write_log (_T("IDE%d: unknown ATA command 0x%02x\n"), ide->num, cmd);
975 }
976 }
977 }
978
ide_get_data_2(struct ide_hdf * ide,int bussize)979 static uae_u16 ide_get_data_2(struct ide_hdf *ide, int bussize)
980 {
981 bool irq = false;
982 uae_u16 v;
983 int inc = bussize ? 2 : 1;
984
985 if (ide->data_size == 0) {
986 if (IDE_LOG > 0)
987 write_log (_T("IDE%d DATA but no data left!? %02X PC=%08X\n"), ide->num, ide->regs.ide_status, m68k_getpc ());
988 if (!ide_isdrive (ide))
989 return 0xffff;
990 return 0;
991 }
992 if (ide->packet_state) {
993 if (bussize) {
994 v = ide->secbuf[ide->packet_data_offset + ide->data_offset + 1] | (ide->secbuf[ide->packet_data_offset + ide->data_offset + 0] << 8);
995 } else {
996 v = ide->secbuf[(ide->packet_data_offset + ide->data_offset)];
997 }
998 if (IDE_LOG > 4)
999 write_log (_T("IDE%d DATA read %04x\n"), ide->num, v);
1000 ide->data_offset += inc;
1001 if (ide->data_size < 0)
1002 ide->data_size += inc;
1003 else
1004 ide->data_size -= inc;
1005 if (ide->data_offset == ide->packet_transfer_size) {
1006 if (IDE_LOG > 1)
1007 write_log (_T("IDE%d ATAPI partial read finished, %d bytes remaining\n"), ide->num, ide->data_size);
1008 if (ide->data_size == 0) {
1009 ide->packet_state = 0;
1010 atapi_data_done (ide);
1011 if (IDE_LOG > 1)
1012 write_log (_T("IDE%d ATAPI read finished, %d bytes\n"), ide->num, ide->packet_data_offset + ide->data_offset);
1013 irq = true;
1014 } else {
1015 process_packet_command (ide);
1016 }
1017 }
1018 } else {
1019 if (bussize) {
1020 v = ide->secbuf[ide->buffer_offset + ide->data_offset + 1] | (ide->secbuf[ide->buffer_offset + ide->data_offset + 0] << 8);
1021 } else {
1022 v = ide->secbuf[(ide->buffer_offset + ide->data_offset)];
1023 }
1024 if (IDE_LOG > 4)
1025 write_log (_T("IDE%d DATA read %04x %d/%d\n"), ide->num, v, ide->data_offset, ide->data_size);
1026 ide->data_offset += inc;
1027 if (ide->data_size < 0) {
1028 ide->data_size += inc;
1029 } else {
1030 ide->data_size -= inc;
1031 if (((ide->data_offset % ide->blocksize) == 0) && ((ide->data_offset / ide->blocksize) % ide->data_multi) == 0) {
1032 if (ide->data_size) {
1033 ide->buffer_offset += ide->data_offset;
1034 do_process_rw_command(ide);
1035 }
1036 }
1037 }
1038 if (ide->data_size == 0) {
1039 if (!(ide->regs.ide_status & IDE_STATUS_DRQ)) {
1040 write_log (_T("IDE%d read finished but DRQ was not active?\n"), ide->num);
1041 }
1042 ide->regs.ide_status &= ~IDE_STATUS_DRQ;
1043 if (IDE_LOG > 1)
1044 write_log (_T("IDE%d read finished\n"), ide->num);
1045 }
1046 }
1047 if (irq)
1048 ide_fast_interrupt (ide);
1049 return v;
1050 }
1051
ide_get_data(struct ide_hdf * ide)1052 uae_u16 ide_get_data(struct ide_hdf *ide)
1053 {
1054 return ide_get_data_2(ide, 1);
1055 }
ide_get_data_8bit(struct ide_hdf * ide)1056 uae_u8 ide_get_data_8bit(struct ide_hdf *ide)
1057 {
1058 return (uae_u8)ide_get_data_2(ide, 0);
1059 }
1060
ide_put_data_2(struct ide_hdf * ide,uae_u16 v,int bussize)1061 static void ide_put_data_2(struct ide_hdf *ide, uae_u16 v, int bussize)
1062 {
1063 int inc = bussize ? 2 : 1;
1064 if (IDE_LOG > 4)
1065 write_log (_T("IDE%d DATA write %04x %d/%d\n"), ide->num, v, ide->data_offset, ide->data_size);
1066 if (ide->data_size == 0) {
1067 if (IDE_LOG > 0)
1068 write_log (_T("IDE%d DATA write without request!? %02X PC=%08X\n"), ide->num, ide->regs.ide_status, m68k_getpc ());
1069 return;
1070 }
1071 ide_grow_buffer(ide, ide->packet_data_offset + ide->data_offset + 2);
1072 if (ide->packet_state) {
1073 if (bussize) {
1074 ide->secbuf[ide->packet_data_offset + ide->data_offset + 1] = v & 0xff;
1075 ide->secbuf[ide->packet_data_offset + ide->data_offset + 0] = v >> 8;
1076 } else {
1077 ide->secbuf[(ide->packet_data_offset + ide->data_offset) ^ 1] = v;
1078 }
1079 } else {
1080 if (bussize) {
1081 ide->secbuf[ide->buffer_offset + ide->data_offset + 1] = v & 0xff;
1082 ide->secbuf[ide->buffer_offset + ide->data_offset + 0] = v >> 8;
1083 } else {
1084 ide->secbuf[(ide->buffer_offset + ide->data_offset)] = v;
1085 }
1086 }
1087 ide->data_offset += inc;
1088 ide->data_size -= inc;
1089 if (ide->packet_state) {
1090 if (ide->data_offset == ide->packet_transfer_size) {
1091 if (IDE_LOG > 0) {
1092 uae_u16 v = (ide->regs.ide_hcyl << 8) | ide->regs.ide_lcyl;
1093 write_log (_T("Data size after command received = %d (%d)\n"), v, ide->packet_data_size);
1094 }
1095 process_packet_command (ide);
1096 }
1097 } else {
1098 if (ide->data_size == 0) {
1099 process_rw_command (ide);
1100 } else if (((ide->data_offset % ide->blocksize) == 0) && ((ide->data_offset / ide->blocksize) % ide->data_multi) == 0) {
1101 int off = ide->data_offset;
1102 do_process_rw_command(ide);
1103 ide->buffer_offset += off;
1104 }
1105 }
1106 }
1107
ide_put_data(struct ide_hdf * ide,uae_u16 v)1108 void ide_put_data(struct ide_hdf *ide, uae_u16 v)
1109 {
1110 ide_put_data_2(ide, v, 1);
1111 }
ide_put_data_8bit(struct ide_hdf * ide,uae_u8 v)1112 void ide_put_data_8bit(struct ide_hdf *ide, uae_u8 v)
1113 {
1114 ide_put_data_2(ide, v, 0);
1115 }
1116
ide_read_reg(struct ide_hdf * ide,int ide_reg)1117 uae_u32 ide_read_reg (struct ide_hdf *ide, int ide_reg)
1118 {
1119 uae_u8 v = 0;
1120 bool isdrv = ide_isdrive (ide);
1121
1122 if (!ide)
1123 goto end;
1124
1125 if (ide->regs.ide_status & IDE_STATUS_BSY)
1126 ide_reg = IDE_STATUS;
1127 if (!ide_isdrive (ide)) {
1128 if (ide_reg == IDE_STATUS) {
1129 if (ide->pair->irq)
1130 ide->pair->irq = 0;
1131 if (ide_isdrive (ide->pair))
1132 v = 0x01;
1133 else
1134 v = 0xff;
1135 } else {
1136 v = 0;
1137 }
1138 goto end;
1139 }
1140
1141 switch (ide_reg)
1142 {
1143 case IDE_SECONDARY:
1144 case IDE_SECONDARY + 1:
1145 case IDE_SECONDARY + 2:
1146 case IDE_SECONDARY + 3:
1147 case IDE_SECONDARY + 4:
1148 case IDE_SECONDARY + 5:
1149 v = 0xff;
1150 break;
1151 case IDE_DRVADDR:
1152 v = ((ide->ide_drv ? 2 : 1) | ((ide->regs.ide_select & 15) << 2)) ^ 0xff;
1153 break;
1154 case IDE_DATA:
1155 break;
1156 case IDE_ERROR:
1157 v = ide->regs.ide_error;
1158 break;
1159 case IDE_NSECTOR:
1160 if (isdrv) {
1161 if (ide->regs.ide_devcon & 0x80)
1162 v = ide->regs.ide_nsector2;
1163 else
1164 v = ide->regs.ide_nsector;
1165 }
1166 break;
1167 case IDE_SECTOR:
1168 if (isdrv) {
1169 if (ide->regs.ide_devcon & 0x80)
1170 v = ide->regs.ide_sector2;
1171 else
1172 v = ide->regs.ide_sector;
1173 check_maxtransfer (ide, 2);
1174 }
1175 break;
1176 case IDE_LCYL:
1177 if (isdrv) {
1178 if (ide->regs.ide_devcon & 0x80)
1179 v = ide->regs.ide_lcyl2;
1180 else
1181 v = ide->regs.ide_lcyl;
1182 }
1183 break;
1184 case IDE_HCYL:
1185 if (isdrv) {
1186 if (ide->regs.ide_devcon & 0x80)
1187 v = ide->regs.ide_hcyl2;
1188 else
1189 v = ide->regs.ide_hcyl;
1190 }
1191 break;
1192 case IDE_SELECT:
1193 v = ide->regs.ide_select;
1194 break;
1195 case IDE_STATUS:
1196 ide->irq = 0;
1197 ide->irq_new = false;
1198 /* fall through */
1199 case IDE_DEVCON: /* ALTSTATUS when reading */
1200 if (!isdrv) {
1201 v = 0;
1202 if (ide->regs.ide_error)
1203 v |= IDE_STATUS_ERR;
1204 } else {
1205 v = ide->regs.ide_status;
1206 if (!ide->atapi || (ide->atapi && ide->atapi_drdy))
1207 v |= IDE_STATUS_DRDY | IDE_STATUS_DSC;
1208 }
1209 break;
1210 }
1211 end:
1212 if (IDE_LOG > 2 && ide_reg > 0 && (1 || ide->num > 0))
1213 write_log (_T("IDE%d GET register %d->%02X (%08X)\n"), ide->num, ide_reg, (uae_u32)v & 0xff, m68k_getpc ());
1214 return v;
1215 }
1216
ide_write_reg(struct ide_hdf * ide,int ide_reg,uae_u32 val)1217 void ide_write_reg (struct ide_hdf *ide, int ide_reg, uae_u32 val)
1218 {
1219 if (!ide)
1220 return;
1221
1222 ide->regs1->ide_devcon &= ~0x80; /* clear HOB */
1223 ide->regs0->ide_devcon &= ~0x80; /* clear HOB */
1224 if (IDE_LOG > 2 && ide_reg > 0 && (1 || ide->num > 0))
1225 write_log (_T("IDE%d PUT register %d=%02X (%08X)\n"), ide->num, ide_reg, (uae_u32)val & 0xff, m68k_getpc ());
1226
1227 switch (ide_reg)
1228 {
1229 case IDE_DRVADDR:
1230 break;
1231 case IDE_DEVCON:
1232 if ((ide->regs.ide_devcon & 4) == 0 && (val & 4) != 0) {
1233 reset_device (ide, true);
1234 if (IDE_LOG > 1)
1235 write_log (_T("IDE%d: SRST\n"), ide->num);
1236 }
1237 ide->regs0->ide_devcon = val;
1238 ide->regs1->ide_devcon = val;
1239 break;
1240 case IDE_DATA:
1241 break;
1242 case IDE_ERROR:
1243 ide->regs0->ide_feat2 = ide->regs0->ide_feat;
1244 ide->regs0->ide_feat = val;
1245 ide->regs1->ide_feat2 = ide->regs1->ide_feat;
1246 ide->regs1->ide_feat = val;
1247 break;
1248 case IDE_NSECTOR:
1249 ide->regs0->ide_nsector2 = ide->regs0->ide_nsector;
1250 ide->regs0->ide_nsector = val;
1251 ide->regs1->ide_nsector2 = ide->regs1->ide_nsector;
1252 ide->regs1->ide_nsector = val;
1253 break;
1254 case IDE_SECTOR:
1255 ide->regs0->ide_sector2 = ide->regs0->ide_sector;
1256 ide->regs0->ide_sector = val;
1257 ide->regs1->ide_sector2 = ide->regs1->ide_sector;
1258 ide->regs1->ide_sector = val;
1259 break;
1260 case IDE_LCYL:
1261 ide->regs0->ide_lcyl2 = ide->regs0->ide_lcyl;
1262 ide->regs0->ide_lcyl = val;
1263 ide->regs1->ide_lcyl2 = ide->regs1->ide_lcyl;
1264 ide->regs1->ide_lcyl = val;
1265 break;
1266 case IDE_HCYL:
1267 ide->regs0->ide_hcyl2 = ide->regs0->ide_hcyl;
1268 ide->regs0->ide_hcyl = val;
1269 ide->regs1->ide_hcyl2 = ide->regs1->ide_hcyl;
1270 ide->regs1->ide_hcyl = val;
1271 break;
1272 case IDE_SELECT:
1273 ide->regs0->ide_select = val;
1274 ide->regs1->ide_select = val;
1275 #if IDE_LOG > 2
1276 if (ide->ide_drv != (val & 0x10) ? 1 : 0)
1277 write_log (_T("DRIVE=%d\n"), (val & 0x10) ? 1 : 0);
1278 #endif
1279 ide->pair->ide_drv = ide->ide_drv = (val & 0x10) ? 1 : 0;
1280 break;
1281 case IDE_STATUS:
1282 ide->irq = 0;
1283 ide->irq_new = false;
1284 if (ide_isdrive (ide)) {
1285 ide->regs.ide_status |= IDE_STATUS_BSY;
1286 ide_do_command (ide, val);
1287 }
1288 break;
1289 }
1290 }
1291
ide_thread(void * idedata)1292 static void *ide_thread (void *idedata)
1293 {
1294 struct ide_thread_state *its = (struct ide_thread_state*)idedata;
1295 for (;;) {
1296 uae_u32 unit = read_comm_pipe_u32_blocking (&its->requests);
1297 struct ide_hdf *ide;
1298 if (its->state == 0 || unit == 0xfffffff)
1299 break;
1300 ide = its->idetable[unit & 0x7f];
1301 if (unit & 0x80)
1302 do_process_packet_command (ide);
1303 else
1304 do_process_rw_command (ide);
1305 }
1306 its->state = -1;
1307 return 0;
1308 }
1309
start_ide_thread(struct ide_thread_state * its)1310 void start_ide_thread(struct ide_thread_state *its)
1311 {
1312 if (!its->state) {
1313 its->state = 1;
1314 init_comm_pipe (&its->requests, 100, 1);
1315 uae_start_thread (_T("ide"), ide_thread, its, NULL);
1316 }
1317 }
1318
stop_ide_thread(struct ide_thread_state * its)1319 void stop_ide_thread(struct ide_thread_state *its)
1320 {
1321 if (its->state > 0) {
1322 its->state = 0;
1323 write_comm_pipe_u32 (&its->requests, 0xffffffff, 1);
1324 while(its->state == 0)
1325 sleep_millis (10);
1326 its->state = 0;
1327 }
1328 }
1329
ide_initialize(struct ide_hdf ** idetable,int chpair)1330 void ide_initialize(struct ide_hdf **idetable, int chpair)
1331 {
1332 struct ide_hdf *ide0 = idetable[chpair * 2 + 0];
1333 struct ide_hdf *ide1 = idetable[chpair * 2 + 1];
1334
1335 ide0->regs0 = &ide0->regs;
1336 ide0->regs1 = &ide1->regs;
1337 ide0->pair = ide1;
1338
1339 ide1->regs1 = &ide1->regs;
1340 ide1->regs0 = &ide0->regs;
1341 ide1->pair = ide0;
1342
1343 ide0->num = chpair * 2 + 0;
1344 ide1->num = chpair * 2 + 1;
1345
1346 reset_device (ide0, true);
1347 }
1348
alloc_ide_mem(struct ide_hdf ** idetable,int max,struct ide_thread_state * its)1349 void alloc_ide_mem (struct ide_hdf **idetable, int max, struct ide_thread_state *its)
1350 {
1351 for (int i = 0; i < max; i++) {
1352 struct ide_hdf *ide;
1353 if (!idetable[i]) {
1354 ide = idetable[i] = xcalloc (struct ide_hdf, 1);
1355 ide->cd_unit_num = -1;
1356 }
1357 ide = idetable[i];
1358 ide_grow_buffer(ide, 1024);
1359 if (its)
1360 ide->its = its;
1361 }
1362 }
1363
remove_ide_unit(struct ide_hdf ** idetable,int ch)1364 void remove_ide_unit(struct ide_hdf **idetable, int ch)
1365 {
1366 struct ide_hdf *ide;
1367 if (!idetable)
1368 return;
1369 ide = idetable[ch];
1370 if (ide) {
1371 struct ide_thread_state *its;
1372 hdf_hd_close(&ide->hdhfd);
1373 scsi_free(ide->scsi);
1374 xfree(ide->secbuf);
1375 its = ide->its;
1376 memset(ide, 0, sizeof(struct ide_hdf));
1377 ide->its = its;
1378 }
1379 }
1380
add_ide_unit(struct ide_hdf ** idetable,int max,int ch,struct uaedev_config_info * ci,struct romconfig * rc)1381 struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct uaedev_config_info *ci, struct romconfig *rc)
1382 {
1383 struct ide_hdf *ide;
1384
1385 alloc_ide_mem(idetable, max, NULL);
1386 if (ch < 0)
1387 return NULL;
1388 ide = idetable[ch];
1389 if (ci)
1390 memcpy (&ide->hdhfd.hfd.ci, ci, sizeof (struct uaedev_config_info));
1391 if (ci->type == UAEDEV_CD && ci->device_emu_unit >= 0) {
1392 device_func_init (0);
1393 ide->scsi = scsi_alloc_cd (ch, ci->device_emu_unit, true);
1394 if (!ide->scsi) {
1395 write_log (_T("IDE: CD EMU unit %d failed to open\n"), ide->cd_unit_num);
1396 return NULL;
1397 }
1398 ide->cd_unit_num = ci->device_emu_unit;
1399 ide->atapi = true;
1400 ide->blocksize = 512;
1401 gui_flicker_led (LED_CD, ch, -1);
1402
1403 write_log (_T("IDE%d CD %d\n"), ch, ide->cd_unit_num);
1404
1405 } else if (ci->type == UAEDEV_HDF) {
1406 if (!hdf_hd_open (&ide->hdhfd))
1407 return NULL;
1408 ide->blocksize = ide->hdhfd.hfd.ci.blocksize;
1409 ide->lba48 = (ide->hdhfd.hfd.ci.unit_special_flags & 1) || ide->hdhfd.size >= 128 * (uae_u64)0x40000000 ? 1 : 0;
1410 gui_flicker_led (LED_HD, ch, -1);
1411 ide->cd_unit_num = -1;
1412 ide->media_type = ci->controller_media_type;
1413 ide->ata_level = ci->unit_feature_level;
1414 if (!ide->ata_level && (ide->hdhfd.size >= 4 * (uae_u64)0x40000000 || ide->media_type))
1415 ide->ata_level = 1;
1416
1417 write_log (_T("IDE%d HD '%s', LCHS=%d/%d/%d. PCHS=%d/%d/%d %uM. LBA48=%d\n"),
1418 ch, ide->hdhfd.hfd.ci.rootdir,
1419 ide->hdhfd.cyls, ide->hdhfd.heads, ide->hdhfd.secspertrack,
1420 ide->hdhfd.hfd.ci.pcyls, ide->hdhfd.hfd.ci.pheads, ide->hdhfd.hfd.ci.psecs,
1421 (int)(ide->hdhfd.size / (1024 * 1024)), ide->lba48);
1422
1423 }
1424 ide->regs.ide_status = 0;
1425 ide->data_offset = 0;
1426 ide->data_size = 0;
1427 return ide;
1428 }
1429
1430 #ifdef SAVESTATE
1431
ide_save_state(uae_u8 * dst,struct ide_hdf * ide)1432 uae_u8 *ide_save_state(uae_u8 *dst, struct ide_hdf *ide)
1433 {
1434 save_u64 (ide->hdhfd.size);
1435 save_string (ide->hdhfd.hfd.ci.rootdir);
1436 save_u32 (ide->hdhfd.hfd.ci.blocksize);
1437 save_u32 (ide->hdhfd.hfd.ci.readonly);
1438 save_u8 (ide->multiple_mode);
1439 save_u32 (ide->hdhfd.cyls);
1440 save_u32 (ide->hdhfd.heads);
1441 save_u32 (ide->hdhfd.secspertrack);
1442 save_u8 (ide->regs.ide_select);
1443 save_u8 (ide->regs.ide_nsector);
1444 save_u8 (ide->regs.ide_nsector2);
1445 save_u8 (ide->regs.ide_sector);
1446 save_u8 (ide->regs.ide_sector2);
1447 save_u8 (ide->regs.ide_lcyl);
1448 save_u8 (ide->regs.ide_lcyl2);
1449 save_u8 (ide->regs.ide_hcyl);
1450 save_u8 (ide->regs.ide_hcyl2);
1451 save_u8 (ide->regs.ide_feat);
1452 save_u8 (ide->regs.ide_feat2);
1453 save_u8 (ide->regs.ide_error);
1454 save_u8 (ide->regs.ide_devcon);
1455 save_u64 (ide->hdhfd.hfd.virtual_size);
1456 save_u32 (ide->hdhfd.hfd.ci.sectors);
1457 save_u32 (ide->hdhfd.hfd.ci.surfaces);
1458 save_u32 (ide->hdhfd.hfd.ci.reserved);
1459 save_u32 (ide->hdhfd.hfd.ci.bootpri);
1460 return dst;
1461 }
1462
ide_restore_state(uae_u8 * src,struct ide_hdf * ide)1463 uae_u8 *ide_restore_state(uae_u8 *src, struct ide_hdf *ide)
1464 {
1465 ide->multiple_mode = restore_u8 ();
1466 ide->hdhfd.cyls = restore_u32 ();
1467 ide->hdhfd.heads = restore_u32 ();
1468 ide->hdhfd.secspertrack = restore_u32 ();
1469 ide->regs.ide_select = restore_u8 ();
1470 ide->regs.ide_nsector = restore_u8 ();
1471 ide->regs.ide_sector = restore_u8 ();
1472 ide->regs.ide_lcyl = restore_u8 ();
1473 ide->regs.ide_hcyl = restore_u8 ();
1474 ide->regs.ide_feat = restore_u8 ();
1475 ide->regs.ide_nsector2 = restore_u8 ();
1476 ide->regs.ide_sector2 = restore_u8 ();
1477 ide->regs.ide_lcyl2 = restore_u8 ();
1478 ide->regs.ide_hcyl2 = restore_u8 ();
1479 ide->regs.ide_feat2 = restore_u8 ();
1480 ide->regs.ide_error = restore_u8 ();
1481 ide->regs.ide_devcon = restore_u8 ();
1482 ide->hdhfd.hfd.virtual_size = restore_u64 ();
1483 ide->hdhfd.hfd.ci.sectors = restore_u32 ();
1484 ide->hdhfd.hfd.ci.surfaces = restore_u32 ();
1485 ide->hdhfd.hfd.ci.reserved = restore_u32 ();
1486 ide->hdhfd.hfd.ci.bootpri = restore_u32 ();
1487 return src;
1488 }
1489
1490 #endif /* SAVESTATE */
1491