45 #define DEV_WDC_LENGTH 8
46 #define WDC_TICK_SHIFT 14
47 #define WDC_MAX_SECTORS 512
48 #define WDC_INBUF_SIZE (512*(WDC_MAX_SECTORS+1))
98 #define COMMAND_RESET 0x100
132 static void wdc_addtoinbuf(
struct wdc_data *d,
int c)
138 fatal(
"[ wdc_addtoinbuf(): WARNING! wdc inbuf overrun!"
139 " Increase WDC_MAX_SECTORS. ]\n");
148 static uint64_t wdc_get_inbuf(
struct wdc_data *d)
153 fatal(
"[ wdc: WARNING! someone is reading too much from the "
155 return (uint64_t) -1;
166 static void wdc_initialize_identify_struct(
struct cpu *
cpu,
struct wdc_data *d)
169 int flags, cdrom = 0;
211 for (i=0; i<
sizeof(namebuf); i++)
212 if (namebuf[i] == 0) {
213 for (; i<
sizeof(namebuf); i++)
220 "Fake GXemul IDE disk ", 40);
268 #define MAX_SECTORS_PER_CHUNK 64
273 uint64_t offset = 512 * (d->
sector - 1
280 offset = 512 * (((d->
head & 0xf) << 24) + (cyl << 8)
282 printf(
"WDC read from offset %lli\n", (
long long)offset);
286 int to_read = count > max_sectors_per_chunk?
287 max_sectors_per_chunk : count;
301 for (i=0; i<512 * to_read; i++)
302 wdc_addtoinbuf(d, buf[i]);
305 offset += 512 * to_read;
320 uint64_t offset = 512 * (d->
sector - 1
326 offset = 512 * (((d->
head & 0xf) << 24) +
328 printf(
"WDC write to offset %lli\n", (
long long)offset);
367 uint64_t idata = 0, odata = 0;
372 odata = status_byte(d,
cpu);
375 debug(
"[ wdc: read from ALTSTATUS: 0x%02x ]\n",
378 debug(
"[ wdc: write to ALT. CTRL: 0x%02x ]\n",
411 debug(
"[ wdc: command 0x%02x drive %i, but no disk image ]\n",
419 debug(
"[ wdc: IDENTIFY drive %i, but it is an ATAPI "
432 debug(
"[ wdc: READ from drive %i, head %i, cyl %i, "
433 "sector %i, nsecs %i ]\n", d->
drive, d->
head,
441 debug(
"[ wdc: WRITE to drive %i, head %i, cyl %i, "
442 "sector %i, nsecs %i ]\n", d->
drive, d->
head,
448 debug(
"[ wdc: IDP drive %i (TODO) ]\n", d->
drive);
454 debug(
"[ wdc: SET_FEATURES drive %i (TODO), feature 0x%02x ]\n",
459 debug(
"[ wdc: WDSF_SET_MODE drive %i, pio/dma flags "
477 wdc_initialize_identify_struct(
cpu, d);
487 debug(
"[ wdc: IDLE_IMMED drive %i ]\n", d->
drive);
493 debug(
"[ wdc: SETMULTI drive %i ]\n", d->
drive);
499 debug(
"[ wdc: ATAPI_SOFT_RESET drive %i ]\n", d->
drive);
505 debug(
"[ wdc: ATAPI_PKT_CMD drive %i ]\n", d->
drive);
513 debug(
"[ wdc: WDCC_DIAGNOSE drive %i: TODO ]\n", d->
drive);
531 fatal(
"[ wdc: WARNING! Unimplemented command 0x%02x (drive %i,"
532 " head %i, cyl %i, sector %i, nsecs %i) ]\n",
542 uint64_t idata = 0, odata = 0;
555 fatal(
"[ wdc: WARNING! non-8-bit access on WRITE! ]\n");
560 switch (relative_addr) {
564 odata = wdc_get_inbuf(d);
568 odata += (wdc_get_inbuf(d) << 8);
570 odata += (wdc_get_inbuf(d) << 16);
571 odata += (wdc_get_inbuf(d) << 24);
575 odata = (odata << 8) + wdc_get_inbuf(d);
577 odata = (odata << 8) + wdc_get_inbuf(d);
578 odata = (odata << 8) + wdc_get_inbuf(d);
583 const char *s =
"0x%04" PRIx64
" ]\n";
585 s =
"0x%02" PRIx64
" ]\n";
587 s =
"0x%08" PRIx64
" ]\n";
589 s =
"0x%016" PRIx64
" ]\n";
590 debug(
"[ wdc: read from DATA: ");
591 debug(s, (uint64_t) odata);
624 const char *s =
"0x%04" PRIx64
" ]\n";
626 s =
"0x%02" PRIx64
" ]\n";
628 s =
"0x%08" PRIx64
" ]\n";
630 s =
"0x%016" PRIx64
" ]\n";
631 debug(
"[ wdc: write to DATA: ");
632 debug(s, (uint64_t) idata);
636 fatal(
"[ wdc: write to DATA, but not "
637 "expecting any? (len=%i): 0x%08lx ]\n",
638 (
int)len, (
long)idata);
643 case 4: wdc_addtoinbuf(d, idata & 0xff);
644 wdc_addtoinbuf(d, (idata >> 8) & 0xff);
645 wdc_addtoinbuf(d, (idata >> 16) & 0xff);
646 wdc_addtoinbuf(d, (idata >> 24) & 0xff);
648 case 2: wdc_addtoinbuf(d, idata & 0xff);
649 wdc_addtoinbuf(d, (idata >> 8) & 0xff);
651 case 1: wdc_addtoinbuf(d, idata);
break;
652 default:
fatal(
"wdc: unimplemented write "
658 case 4: wdc_addtoinbuf(d, (idata >> 24) & 0xff);
659 wdc_addtoinbuf(d, (idata >> 16) & 0xff);
660 wdc_addtoinbuf(d, (idata >> 8) & 0xff);
661 wdc_addtoinbuf(d, idata & 0xff);
663 case 2: wdc_addtoinbuf(d, (idata >> 8) & 0xff);
664 wdc_addtoinbuf(d, idata & 0xff);
666 case 1: wdc_addtoinbuf(d, idata);
break;
667 default:
fatal(
"wdc: unimplemented write "
674 while (inbuf_len < 0)
678 unsigned char *scsi_cmd;
687 debug(
"[ wdc: ATAPI command ]\n");
689 while (inbuf_len > 0) {
690 scsi_cmd[x++] = wdc_get_inbuf(d);
707 fatal(
"WDC: ATAPI scsi error?\n");
728 fatal(
"wdc atapi Dataout? TODO\n");
740 inbuf_len % 512 == 0) ) {
743 unsigned char *buf, *b;
753 for (i=0; i<512 * count; i++)
754 buf[i] = wdc_get_inbuf(d);
777 debug(
"[ wdc: read from ERROR: 0x%02x ]\n", (
int)odata);
780 debug(
"[ wdc: write to PRECOMP: 0x%02x ]\n",(
int)idata);
790 debug(
"[ wdc: read from SECCNT: 0x%02x ]\n",(
int)odata);
793 debug(
"[ wdc: write to SECCNT: 0x%02x ]\n", (
int)idata);
800 debug(
"[ wdc: read from SECTOR: 0x%02x ]\n",(
int)odata);
803 debug(
"[ wdc: write to SECTOR: 0x%02x ]\n", (
int)idata);
820 debug(
"[ wdc: read from CYL_LO: 0x%02x ]\n",(
int)odata);
823 debug(
"[ wdc: write to CYL_LO: 0x%02x ]\n", (
int)idata);
838 odata = (x >> 8) & 255;
840 debug(
"[ wdc: read from CYL_HI: 0x%02x ]\n",(
int)odata);
843 debug(
"[ wdc: write to CYL_HI: 0x%02x ]\n", (
int)idata);
851 debug(
"[ wdc: read from SDH: 0x%02x (sectorsize %i,"
852 " lba=%i, drive %i, head %i) ]\n", (
int)odata,
856 d->
lba = (idata >> 5) & 1;
857 d->
drive = (idata >> 4) & 1;
858 d->
head = idata & 0xf;
859 debug(
"[ wdc: write to SDH: 0x%02x (sectorsize %i,"
860 " lba=%i, drive %i, head %i) ]\n", (
int)idata,
867 odata = status_byte(d,
cpu);
869 debug(
"[ wdc: read from STATUS: 0x%02x ]\n",
874 debug(
"[ wdc: write to COMMAND: 0x%02x ]\n",(
int)idata);
881 debug(
"[ wdc: read from 0x%02x ]\n",
884 debug(
"[ wdc: write to 0x%02x: 0x%02x ]\n",
885 (
int)relative_addr, (
int)idata);
889 dev_wdc_tick(
cpu, extra);
897 fatal(
"[ wdc: WARNING! non-8-bit access on READ! ]\n");
909 uint64_t alt_status_addr;
913 memset(d, 0,
sizeof(
struct wdc_data));
938 alt_status_addr = 0x14000386;
954 alt_status_addr, 2, dev_wdc_altstatus_access, d,
DM_DEFAULT, NULL);