]> git.sesse.net Git - pistorm/blob - platforms/amiga/gayle-ide/ide.c
Update config_file.h, emulator.c, and amiga-platform.c
[pistorm] / platforms / amiga / gayle-ide / ide.c
1 /*
2  *      IDE Emulation Layer for retro-style PIO interfaces
3  *
4  *      (c) Copyright Alan Cox, 2015-2019
5  *
6  *      IDE-emu is free software: you can redistribute it and/or modify
7  *      it under the terms of the GNU General Public License as published by
8  *      the Free Software Foundation, either version 2 of the License, or
9  *      (at your option) any later version.
10  *
11  *      IDE-emu is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *      GNU General Public License for more details.
15  *
16  *      You should have received a copy of the GNU General Public License
17  *      along with IDE-emu.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <time.h>
27 #include <arpa/inet.h>
28
29 #include "ide.h"
30
31 #define IDE_IDLE        0
32 #define IDE_CMD         1
33 #define IDE_DATA_IN     2
34 #define IDE_DATA_OUT    3
35  
36 #define DCR_NIEN        2
37 #define DCR_SRST        4
38
39 #define DEVH_HEAD       15
40 #define DEVH_DEV        16
41 #define DEVH_LBA        64
42
43 #define ERR_AMNF        1
44 #define ERR_TKNONF      2
45 #define ERR_ABRT        4
46 #define ERR_MCR         8
47 #define ERR_IDNF        16
48 #define ERR_MC          32
49 #define ERR_UNC         64
50
51 #define ST_ERR          1
52 #define ST_IDX          2
53 #define ST_CORR         4
54 #define ST_DRQ          8
55 #define ST_DSC          16
56 #define ST_DF           32
57 #define ST_DRDY         64
58 #define ST_BSY          128
59
60 #define DCL_SRST        4
61 #define DCL_NIEN        2
62
63 #define IDE_CMD_CALIB           0x10
64 #define IDE_CMD_READ            0x20
65 #define IDE_CMD_READ_NR         0x21
66 #define IDE_CMD_WRITE           0x30
67 #define IDE_CMD_WRITE_NR        0x31
68 #define IDE_CMD_VERIFY          0x40
69 #define IDE_CMD_VERIFY_NR       0x41
70 #define IDE_CMD_SEEK            0x70
71 #define IDE_CMD_EDD             0x90
72 #define IDE_CMD_INTPARAMS       0x91
73 #define IDE_CMD_IDENTIFY        0xEC
74 #define IDE_CMD_SETFEATURES     0xEF
75
76 const uint8_t ide_magic[8] = {
77   '1','D','E','D','1','5','C','0'
78 };
79
80 static char *charmap(uint8_t v)
81 {
82   static char cbuf[3];
83   if (v < 32)
84     sprintf(cbuf, "^%c", '@'+v);
85   else if (v < 127)
86     sprintf(cbuf, " %c", v);
87   else if (v == 127)
88     sprintf(cbuf, "DL");
89   else if (v < 160)
90     sprintf(cbuf, ":%c", '@' + v - 128);
91   else if (v < 255)
92     sprintf(cbuf, "~%c", v - 128);
93   else
94     sprintf(cbuf, "!D");
95   return cbuf;
96 }
97
98 static void hexdump(uint8_t *bp)
99 {
100   int i,j;
101   for (i = 0; i < 512; i+= 16) {
102     for(j = 0; j < 16; j++)
103       fprintf(stderr, "%02X ", bp[i+j]);
104     fprintf(stderr, "|");
105     for(j = 0; j < 16; j++)
106       fprintf(stderr, "%2s", charmap(bp[i+j]));
107     fprintf(stderr, "\n");
108   }
109 }
110
111 /* FIXME: use proper endian convertors! */
112 static uint16_t le16(uint16_t v)
113 {
114   uint8_t *p = (uint8_t *)&v;
115   return p[0] | (p[1] << 8);
116 }
117
118 static void ide_xlate_errno(struct ide_taskfile *t, int len)
119 {
120   t->status |= ST_ERR;
121   if (len == -1) {
122     if (errno == EIO)
123       t->error = ERR_UNC;
124     else
125       t->error = ERR_AMNF;
126   } else
127     t->error = ERR_AMNF;
128 }
129
130 static void ide_fault(struct ide_drive *d, const char *p)
131 {
132   fprintf(stderr, "ide: %s: %d: %s\n", d->controller->name,
133                         (int)(d - d->controller->drive), p);
134 }
135
136 /* Disk translation */
137 static off_t xlate_block(struct ide_taskfile *t)
138 {
139   struct ide_drive *d = t->drive;
140   uint16_t cyl;
141
142   if (t->lba4 & DEVH_LBA) {
143 /*    fprintf(stderr, "XLATE LBA %02X:%02X:%02X:%02X\n", 
144       t->lba4, t->lba3, t->lba2, t->lba1);*/
145     if (d->lba)
146       return 2 + (((t->lba4 & DEVH_HEAD) << 24) | (t->lba3 << 16) | (t->lba2 << 8) | t->lba1);
147     ide_fault(d, "LBA on non LBA drive");
148   }
149
150   /* Some well known software asks for 0/0/0 when it means 0/0/1. Drives appear
151      to interpret sector 0 as sector 1 */
152   if (t->lba1 == 0) {
153     fprintf(stderr, "[Bug: request for sector offset 0].\n");
154     t->lba1 = 1;
155   }
156   cyl = (t->lba3 << 8) | t->lba2;
157   /* fprintf(stderr, "(H %d C %d S %d)\n", t->lba4 & DEVH_HEAD, cyl, t->lba1); */
158   if (t->lba1 == 0 || t->lba1 > d->sectors || t->lba4 >= d->heads || cyl >= d->cylinders) {
159     return -1;
160   }
161   /* Sector 1 is first */
162   /* Images generally go cylinder/head/sector. This also matters if we ever
163      implement more advanced geometry setting */
164   return 1 + ((cyl * d->heads) + (t->lba4 & DEVH_HEAD)) * d->sectors + t->lba1;
165 }
166
167 /* Indicate the drive is ready */
168 static void ready(struct ide_taskfile *tf)
169 {
170   tf->status &= ~(ST_BSY|ST_DRQ);
171   tf->status |= ST_DRDY;
172   tf->drive->state = IDE_IDLE;
173 }
174
175 /* Return to idle state, completing a command */
176 static void completed(struct ide_taskfile *tf)
177 {
178   ready(tf);
179   tf->drive->intrq = 1;
180 }
181
182 static void drive_failed(struct ide_taskfile *tf)
183 {
184   tf->status |= ST_ERR;
185   tf->error = ERR_IDNF;
186   ready(tf);
187 }
188
189 static void data_in_state(struct ide_taskfile *tf)
190 {
191   struct ide_drive *d = tf->drive;
192   d->state = IDE_DATA_IN;
193   d->dptr = d->data + 512;
194   /* We don't clear DRDY here, drives may well accept a command at this
195      point and at least one firmware for RC2014 assumes this */
196   tf->status &= ~ST_BSY;
197   tf->status |= ST_DRQ;
198   d->intrq = 1;                 /* Double check */
199 }
200
201 static void data_out_state(struct ide_taskfile *tf)
202 {
203   struct ide_drive *d = tf->drive;
204   d->state = IDE_DATA_OUT;
205   d->dptr = d->data;
206   tf->status &= ~ (ST_BSY|ST_DRDY);
207   tf->status |= ST_DRQ;
208   d->intrq = 1;                 /* Double check */
209 }
210
211 static void edd_setup(struct ide_taskfile *tf)
212 {
213   tf->error = 0x01;             /* All good */
214   tf->lba1 = 0x01;              /* EDD always updates drive 0 */
215   tf->lba2 = 0x00;
216   tf->lba3 = 0x00;
217   tf->lba4 = 0x00;
218   tf->count = 0x01;
219   ready(tf);
220 }
221
222 void ide_reset(struct ide_controller *c)
223 {
224   if (c->drive[0].present) {
225     edd_setup(&c->drive[0].taskfile);
226     /* A drive could clear busy then set DRDY up to 2 minutes later if its
227        mindnumbingly slow to start up ! We don't emulate any of that */
228     c->drive[0].taskfile.status = ST_DRDY;
229     c->drive[0].eightbit = 0;
230   }
231   if (c->drive[1].present) {
232     edd_setup(&c->drive[1].taskfile);
233     c->drive[1].taskfile.status = ST_DRDY;
234     c->drive[1].eightbit = 0;
235   }
236   c->selected = 0;
237 }
238
239 void ide_reset_begin(struct ide_controller *c)
240 {
241   if (c->drive[0].present)
242     c->drive[0].taskfile.status |= ST_BSY;
243   if (c->drive[1].present)
244     c->drive[1].taskfile.status |= ST_BSY;
245   /* Ought to be a time delay relative to reset or power on */
246   ide_reset(c);
247 }
248
249 static void ide_srst_begin(struct ide_controller *c)
250 {
251   ide_reset(c);
252   if (c->drive[0].present)
253     c->drive[0].taskfile.status |= ST_BSY;
254   if (c->drive[1].present)
255     c->drive[1].taskfile.status |= ST_BSY;
256 }  
257
258 static void ide_srst_end(struct ide_controller *c)
259 {
260   /* Could be time delays here */
261   ready(&c->drive[0].taskfile);
262   ready(&c->drive[1].taskfile);
263 }
264
265 static void cmd_edd_complete(struct ide_taskfile *tf)
266 {
267   struct ide_controller *c = tf->drive->controller;
268   if (c->drive[0].present)
269     edd_setup(&c->drive[0].taskfile);
270   if (c->drive[1].present)
271     edd_setup(&c->drive[1].taskfile);
272   c->selected = 0;
273 }
274
275 static void cmd_identify_complete(struct ide_taskfile *tf)
276 {
277   struct ide_drive *d = tf->drive;
278   memcpy(d->data, d->identify, 512);
279   data_in_state(tf);
280   /* Arrange to copy just the identify buffer */
281   d->dptr = d->data;
282   d->length = 1;
283 }
284
285 static void cmd_initparam_complete(struct ide_taskfile *tf)
286 {
287   struct ide_drive *d = tf->drive;
288   /* We only support the current mapping */
289   if (tf->count != d->sectors || (tf->lba4 & DEVH_HEAD) + 1 != d->heads) {
290     tf->status |= ST_ERR;
291     tf->error |= ERR_ABRT;
292     tf->drive->failed = 1;              /* Report ID NF until fixed */
293 /*    fprintf(stderr, "geo is %d %d, asked for %d %d\n",
294       d->sectors, d->heads, tf->count, (tf->lba4 & DEVH_HEAD) + 1); */
295     ide_fault(d, "invalid geometry");
296   } else if (tf->drive->failed == 1)
297     tf->drive->failed = 0;              /* Valid translation */
298   completed(tf);
299 }
300
301 static void cmd_readsectors_complete(struct ide_taskfile *tf)
302 {
303   struct ide_drive *d = tf->drive;
304   /* Move to data xfer */
305   if (d->failed) {
306     drive_failed(tf);
307     return;
308   }
309   d->offset = xlate_block(tf);
310   /* DRDY is not guaranteed here but at least one buggy RC2014 firmware
311      expects it */
312   tf->status |= ST_DRQ | ST_DSC | ST_DRDY;
313   tf->status &= ~ST_BSY;
314   /* 0 = 256 sectors */
315   d->length = tf->count ? tf->count : 256;
316   /* fprintf(stderr, "READ %d SECTORS @ %ld\n", d->length, d->offset); */
317   if (d->offset == -1 ||  lseek(d->fd, 512 * d->offset, SEEK_SET) == -1) {
318     tf->status |= ST_ERR;
319     tf->status &= ~ST_DSC;
320     tf->error |= ERR_IDNF;
321     /* return null data */
322     completed(tf);
323     return;
324   }
325   /* do the xfer */
326   data_in_state(tf);
327 }
328
329 static void cmd_verifysectors_complete(struct ide_taskfile *tf)
330 {
331   struct ide_drive *d = tf->drive;
332   /* Move to data xfer */
333   if (d->failed) {
334     drive_failed(tf);
335     return;
336   }
337   d->offset = xlate_block(tf);
338   /* 0 = 256 sectors */
339   d->length = tf->count ? tf->count : 256;
340   if (d->offset == -1 || lseek(d->fd, 512 * (d->offset + d->length - 1), SEEK_SET) == -1) {
341     tf->status &= ~ST_DSC;
342     tf->status |= ST_ERR;
343     tf->error |= ERR_IDNF;
344   }
345   tf->status |= ST_DSC;
346   completed(tf);
347 }
348
349 static void cmd_recalibrate_complete(struct ide_taskfile *tf)
350 {
351   struct ide_drive *d = tf->drive;
352   if (d->failed)
353     drive_failed(tf);
354   if (d->offset == -1 || xlate_block(tf) != 0L) {
355     tf->status &= ~ST_DSC;
356     tf->status |= ST_ERR;
357     tf->error |= ERR_ABRT;
358   }
359   tf->status |= ST_DSC;
360   completed(tf);
361 }
362
363 static void cmd_seek_complete(struct ide_taskfile *tf)
364 {
365   struct ide_drive *d = tf->drive;
366   if (d->failed)
367     drive_failed(tf);
368   d->offset = xlate_block(tf);
369   if (d->offset == -1 || lseek(d->fd, 512 * d->offset, SEEK_SET) == -1) {
370     tf->status &= ~ST_DSC;
371     tf->status |= ST_ERR;
372     tf->error |= ERR_IDNF;
373   }
374   tf->status |= ST_DSC;
375   completed(tf);
376 }
377
378 static void cmd_setfeatures_complete(struct ide_taskfile *tf)
379 {
380   struct ide_drive *d = tf->drive;
381   switch(tf->feature) {
382     case 0x01:
383       d->eightbit = 1;
384       break;
385     case 0x03:
386       if ((tf->count & 0xF0) >= 0x20) {
387         tf->status |= ST_ERR;
388         tf->error |= ERR_ABRT;
389       }
390       /* Silently accept PIO mode settings */
391       break;
392     case 0x81:
393       d->eightbit = 0;
394       break;
395     default:
396       tf->status |= ST_ERR;
397       tf->error |= ERR_ABRT;
398   }
399   completed(tf);
400 }
401
402 static void cmd_writesectors_complete(struct ide_taskfile *tf)
403 {
404   struct ide_drive *d = tf->drive;
405   /* Move to data xfer */
406   if (d->failed) {
407     drive_failed(tf);
408     return;
409   }
410   d->offset = xlate_block(tf);
411   tf->status |= ST_DRQ;
412   /* 0 = 256 sectors */
413   d->length = tf->count ? tf->count : 256;
414 /*  fprintf(stderr, "WRITE %d SECTORS @ %ld\n", d->length, d->offset); */
415   if (d->offset == -1 ||  lseek(d->fd, 512 * d->offset, SEEK_SET) == -1) {
416     tf->status |= ST_ERR;
417     tf->error |= ERR_IDNF;
418     tf->status &= ~ST_DSC;
419     /* return null data */
420     completed(tf);
421     return;
422   }
423   /* do the xfer */
424   data_out_state(tf);
425 }
426
427 static void ide_set_error(struct ide_drive *d)
428 {
429   d->taskfile.lba4 &= ~DEVH_HEAD;
430
431   if (d->taskfile.lba4 & DEVH_LBA) {
432     d->taskfile.lba1 = d->offset & 0xFF;
433     d->taskfile.lba2 = (d->offset >> 8) & 0xFF;
434     d->taskfile.lba3 = (d->offset >> 16) & 0xFF;
435     d->taskfile.lba4 |= (d->offset >> 24) & DEVH_HEAD;
436   } else {
437     d->taskfile.lba1 = d->offset % d->sectors + 1;
438     d->offset /= d->sectors;
439     d->taskfile.lba4 |= d->offset / (d->cylinders * d->sectors);
440     d->offset %= (d->cylinders * d->sectors);
441     d->taskfile.lba2 = d->offset & 0xFF;
442     d->taskfile.lba3 = (d->offset >> 8) & 0xFF;
443   }
444   d->taskfile.count = d->length;
445   d->taskfile.status |= ST_ERR;
446   d->state = IDE_IDLE;
447   completed(&d->taskfile);
448 }
449
450 static int ide_read_sector(struct ide_drive *d)
451 {
452   int len;
453
454   d->dptr = d->data;
455   if ((len = read(d->fd, d->data, 512)) != 512) {
456     perror("ide_read_sector");
457     d->taskfile.status |= ST_ERR;
458     d->taskfile.status &= ~ST_DSC;
459     ide_xlate_errno(&d->taskfile, len);
460     return -1;
461   }
462 //  hexdump(d->data);
463   d->offset += 512;
464   return 0;
465 }
466
467 static int ide_write_sector(struct ide_drive *d)
468 {
469   int len;
470
471   d->dptr = d->data;
472   if ((len = write(d->fd, d->data, 512)) != 512) {
473     d->taskfile.status |= ST_ERR;
474     d->taskfile.status &= ~ST_DSC;
475     ide_xlate_errno(&d->taskfile, len);
476     return -1;
477   }
478 //  hexdump(d->data);
479   d->offset += 512;
480   return 0;
481 }
482
483 static uint16_t ide_data_in(struct ide_drive *d, int len)
484 {
485   uint16_t v;
486   if (d->state == IDE_DATA_IN) {
487     if (d->dptr == d->data + 512) {
488       if (ide_read_sector(d) < 0) {
489         ide_set_error(d);       /* Set the LBA or CHS etc */
490         return 0xFFFF;          /* and error bits set by read_sector */
491       }
492     }
493     v = *d->dptr;
494     if (!d->eightbit) {
495       if (len == 2)
496         v |= (d->dptr[1] << 8);
497       d->dptr+=2;
498     } else
499       d->dptr++;
500     d->taskfile.data = v;
501     if (d->dptr == d->data + 512) {
502       d->length--;
503       d->intrq = 1;             /* we don't yet emulate multimode */
504       if (d->length == 0) {
505         d->state = IDE_IDLE;
506         completed(&d->taskfile);
507       }
508     }
509   } else
510     ide_fault(d, "bad data read");
511
512   if (len == 1)
513     return d->taskfile.data & 0xFF;
514   return d->taskfile.data;
515 }
516
517 static void ide_data_out(struct ide_drive *d, uint16_t v, int len)
518 {
519   if (d->state != IDE_DATA_OUT) {
520     ide_fault(d, "bad data write");
521     d->taskfile.data = v;
522   } else {
523     if (d->eightbit)
524       v &= 0xFF;
525     *d->dptr++ = v;
526     d->taskfile.data = v;
527     if (!d->eightbit) {
528       *d->dptr++ = v >> 8;
529       d->taskfile.data = v >> 8;
530     }
531     if (d->dptr == d->data + 512) {
532       if (ide_write_sector(d) < 0) {
533         ide_set_error(d);
534         return; 
535       }
536       d->length--;
537       d->intrq = 1;
538       if (d->length == 0) {
539         d->state = IDE_IDLE;
540         d->taskfile.status |= ST_DSC;
541         completed(&d->taskfile);
542       }
543     }
544   }
545 }
546
547 static void ide_issue_command(struct ide_taskfile *t)
548 {
549   t->status &= ~(ST_ERR|ST_DRDY);
550   t->status |= ST_BSY;
551   t->error = 0;
552   t->drive->state = IDE_CMD;
553   
554   /* We could complete with delays but don't do so yet */
555   switch(t->command) {
556     case IDE_CMD_EDD:   /* 0x90 */
557       cmd_edd_complete(t);
558       break;
559     case IDE_CMD_IDENTIFY:      /* 0xEC */
560       cmd_identify_complete(t);
561       break;
562     case IDE_CMD_INTPARAMS:     /* 0x91 */
563       cmd_initparam_complete(t);
564       break;
565     case IDE_CMD_READ:          /* 0x20 */
566     case IDE_CMD_READ_NR:       /* 0x21 */
567       cmd_readsectors_complete(t);
568       break;
569     case IDE_CMD_SETFEATURES:   /* 0xEF */
570       cmd_setfeatures_complete(t);
571       break;
572     case IDE_CMD_VERIFY:        /* 0x40 */
573     case IDE_CMD_VERIFY_NR:     /* 0x41 */
574       cmd_verifysectors_complete(t);
575       break;
576     case IDE_CMD_WRITE:         /* 0x30 */
577     case IDE_CMD_WRITE_NR:      /* 0x31 */
578       cmd_writesectors_complete(t);
579       break;
580     default:
581       if ((t->command & 0xF0) == IDE_CMD_CALIB) /* 1x */
582         cmd_recalibrate_complete(t);
583       else if ((t->command & 0xF0) == IDE_CMD_SEEK) /* 7x */
584         cmd_seek_complete(t);
585       else {
586         /* Unknown */
587         t->status |= ST_ERR;
588         t->error |= ERR_ABRT;
589         completed(t);
590       }
591   }
592 }
593
594 /*
595  *      8bit IDE controller emulation
596  */
597
598 uint8_t ide_read8(struct ide_controller *c, uint8_t r)
599 {
600   struct ide_drive *d = &c->drive[c->selected];
601   struct ide_taskfile *t = &d->taskfile;
602   switch(r) {
603     case ide_data:
604       return ide_data_in(d, 1);
605     case ide_error_r:
606       return t->error;
607     case ide_sec_count:
608       return t->count;
609     case ide_lba_low:
610       return t->lba1;
611     case ide_lba_mid:
612       return t->lba2;
613     case ide_lba_hi:
614       return t->lba3;
615     case ide_lba_top:
616       return t->lba4;
617     case ide_status_r:
618       d->intrq = 0;             /* Acked */
619     case ide_altst_r:
620       return t->status;
621     default:
622       ide_fault(d, "bogus register");
623       return 0xFF;
624   }
625 }
626
627 void ide_write8(struct ide_controller *c, uint8_t r, uint8_t v)
628 {
629   struct ide_drive *d = &c->drive[c->selected];
630   struct ide_taskfile *t = &d->taskfile;
631
632   if (r != ide_devctrl_w) {
633     if (t->status & ST_BSY) {
634       ide_fault(d, "command written while busy");
635       return;
636     }
637     /* Not clear this is the right emulation */
638     if (d->present == 0 && r != ide_lba_top) {
639       ide_fault(d, "not present");
640       return;
641     }
642   }
643
644   switch(r) {
645     case ide_data:
646       ide_data_out(d, v, 1);
647       break;
648     case ide_feature_w:
649       t->feature = v;
650       break;
651     case ide_sec_count:
652       t->count = v;
653       break;
654     case ide_lba_low:
655       t->lba1 = v;
656       break;
657     case ide_lba_mid:
658       t->lba2 = v;
659       break;
660     case ide_lba_hi:
661       t->lba3 = v;
662       break;
663     case ide_lba_top:
664       c->selected = (v & DEVH_DEV) ? 1 : 0;
665       c->drive[c->selected].taskfile.lba4 = v & (DEVH_HEAD|DEVH_DEV|DEVH_LBA);
666       break;
667     case ide_command_w:
668       t->command = v; 
669       ide_issue_command(t);
670       break;
671     case ide_devctrl_w:
672       /* ATA: "When the Device Control register is written, both devices
673          respond to the write regardless of which device is selected" */
674       if ((v ^ t->devctrl) & DCL_SRST) {
675         if (v & DCL_SRST)
676           ide_srst_begin(c);
677         else
678           ide_srst_end(c);
679       }
680       c->drive[0].taskfile.devctrl = v; /* Check versus real h/w does this end up cleared */
681       c->drive[1].taskfile.devctrl = v;
682       break;
683   }
684 }
685
686 /*
687  *      16bit IDE controller emulation
688  */
689
690 uint16_t ide_read16(struct ide_controller *c, uint8_t r)
691 {
692   struct ide_drive *d = &c->drive[c->selected];
693   if (r == ide_data)
694     return htons(ide_data_in(d,2));
695   return ide_read8(c, r);
696 }
697
698 void ide_write16(struct ide_controller *c, uint8_t r, uint16_t v)
699 {
700   struct ide_drive *d = &c->drive[c->selected];
701   struct ide_taskfile *t = &d->taskfile;
702
703   if (r != ide_devctrl_w && (t->status & ST_BSY)) {
704     ide_fault(d, "command written while busy");
705     return;
706   }
707   if (r == ide_data)
708     ide_data_out(d, ntohs(v), 2);
709   else
710     ide_write8(c, r, v);
711 }
712
713 /*
714  *      Allocate a new IDE controller emulation
715  */
716 struct ide_controller *ide_allocate(const char *name)
717 {
718   struct ide_controller *c = calloc(1, sizeof(*c));
719   if (c == NULL)
720     return NULL;
721   c->name = strdup(name);
722   if (c->name == NULL) {
723     free(c);
724     return NULL;
725   }
726   c->drive[0].controller = c;
727   c->drive[1].controller = c;
728   c->drive[0].taskfile.drive = &c->drive[0];
729   c->drive[1].taskfile.drive = &c->drive[1];
730   return c;
731 }
732
733 /*
734  *      Attach a file to a device on the controller
735  */
736 int ide_attach(struct ide_controller *c, int drive, int fd)
737 {
738   struct ide_drive *d = &c->drive[drive];
739   if (d->present) {
740     ide_fault(d, "double attach");
741     return -1;
742   }
743   d->fd = fd;
744   if (read(d->fd, d->data, 512) != 512 ||
745       read(d->fd, d->identify, 512) != 512) {
746     ide_fault(d, "i/o error on attach");
747     return -1;
748   }
749   if (memcmp(d->data, ide_magic, 8)) {
750     ide_fault(d, "bad magic");
751     return -1;
752   }
753   d->fd = fd;
754   d->present = 1;
755   d->heads = d->identify[3];
756   d->sectors = d->identify[6];
757   d->cylinders = le16(d->identify[1]);
758   if (d->identify[49] & le16(1 << 9))
759     d->lba = 1;
760   else
761     d->lba = 0;
762   return 0;
763 }
764
765 /*
766  *      Detach an IDE device from the interface (not hot pluggable)
767  */
768 void ide_detach(struct ide_drive *d)
769 {
770   close(d->fd);
771   d->fd = -1;
772   d->present = 0;
773 }
774
775 /*
776  *      Free up and release and IDE controller
777  */  
778 void ide_free(struct ide_controller *c)
779 {
780   if (c->drive[0].present)
781     ide_detach(&c->drive[0]);
782   if (c->drive[1].present)
783     ide_detach(&c->drive[1]);
784   free((void *)c->name);
785   free(c);
786 }
787
788 /*
789  *      Emulation interface for an 8bit controller using latches on the
790  *      data register
791  */
792 uint8_t ide_read_latched(struct ide_controller *c, uint8_t reg)
793 {
794   uint16_t v;
795   if (reg == ide_data_latch)
796     return c->data_latch;
797   v = ide_read16(c, reg);
798   if (reg == ide_data) {
799     c->data_latch = v >> 8;
800     v &= 0xFF;
801   }
802   return v;
803 }
804
805 void ide_write_latched(struct ide_controller *c, uint8_t reg, uint8_t v)
806 {
807   uint16_t d = v;
808
809   if (reg == ide_data_latch) {
810     c->data_latch = v;
811     return;
812   }
813   if (reg == ide_data)
814     d |=  (c->data_latch << 8);
815   ide_write16(c, reg, d);  
816 }
817
818 static void make_ascii(uint16_t *p, const char *t, int len)
819 {
820   int i;
821   char *d = (char *)p;
822   strncpy(d, t, len);
823
824   for (i = 0; i < len; i += 2) {
825     char c = *d;
826     *d = d[1];
827     d[1] = c;
828     d += 2;
829   }  
830 }
831
832 static void make_serial(uint16_t *p)
833 {
834   char buf[21];
835   srand(getpid()^time(NULL));
836   snprintf(buf, 21, "%08d%08d%04d", rand(), rand(), rand());
837   make_ascii(p, buf, 20);
838 }
839
840 int ide_make_drive(uint8_t type, int fd)
841 {
842   uint8_t s, h;
843   uint16_t c;
844   uint32_t sectors;
845   uint16_t ident[256];
846
847   if (type < 1 || type > MAX_DRIVE_TYPE)
848     return -2;
849   
850   memset(ident, 0, 512);
851   memcpy(ident, ide_magic, 8);
852   if (write(fd, ident, 512) != 512)
853     return -1;
854
855   memset(ident, 0, 8);
856   ident[0] = le16((1 << 15) | (1 << 6));        /* Non removable */
857   make_serial(ident + 10);
858   ident[47] = 0; /* no read multi for now */
859   ident[51] = le16(240 /* PIO2 */ << 8);        /* PIO cycle time */
860   ident[53] = le16(1);          /* Geometry words are valid */
861   
862   switch(type) {
863     case ACME_ROADRUNNER:
864       /* 504MB drive with LBA support */
865       c = 1024;
866       h = 16;
867       s = 63;
868       make_ascii(ident + 23, "A001.001", 8);
869       make_ascii(ident + 27, "ACME ROADRUNNER v0.1", 40);
870       ident[49] = le16(1 << 9); /* LBA */
871       break;  
872     case ACME_ULTRASONICUS:
873       /* 40MB drive with LBA support */
874       c = 977;
875       h = 5;
876       s = 16;
877       ident[49] = le16(1 << 9); /* LBA */
878       make_ascii(ident + 23, "A001.001", 8);
879       make_ascii(ident + 27, "ACME ULTRASONICUS AD INFINITUM v0.1", 40);
880       break;
881     case ACME_NEMESIS:
882       /* 20MB drive with LBA support */
883       c = 615;
884       h = 4;
885       s = 16;
886       ident[49] = le16(1 << 9); /* LBA */
887       make_ascii(ident + 23, "A001.001", 8);
888       make_ascii(ident + 27, "ACME NEMESIS RIDICULII v0.1", 40);
889       break;
890     case ACME_COYOTE:
891       /* 20MB drive without LBA support */
892       c = 615;
893       h = 4;
894       s = 16;
895       make_ascii(ident + 23, "A001.001", 8);
896       make_ascii(ident + 27, "ACME COYOTE v0.1", 40);
897       break;  
898     case ACME_ACCELLERATTI:
899       c = 1024;
900       h = 16;
901       s = 16;
902       ident[49] = le16(1 << 9); /* LBA */
903       make_ascii(ident + 23, "A001.001", 8);
904       make_ascii(ident + 27, "ACME ACCELLERATTI INCREDIBILUS v0.1", 40);
905       break;
906     case ACME_ZIPPIBUS:
907       c = 1024;
908       h = 16;
909       s = 32;
910       ident[49] = le16(1 << 9); /* LBA */
911       make_ascii(ident + 23, "A001.001", 8);
912       make_ascii(ident + 27, "ACME ZIPPIBUS v0.1", 40);
913       break;
914   }
915   ident[1] = le16(c);
916   ident[3] = le16(h);
917   ident[6] = le16(s);
918   ident[54] = ident[1];
919   ident[55] = ident[3];
920   ident[56] = ident[6];
921   sectors = c * h * s;
922   ident[57] = le16(sectors & 0xFFFF);
923   ident[58] = le16(sectors >> 16);
924   ident[60] = ident[57];
925   ident[61] = ident[58];
926   if (write(fd, ident, 512) != 512)
927     return -1;
928   
929   memset(ident, 0xE5, 512);
930   while(sectors--)
931     if (write(fd, ident, 512) != 512)
932       return -1;  
933   return 0;
934 }