3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
12 #include <hw/vga/vga.h>
13 #include <hw/pci/pci.h>
14 #include <hw/dos/dos.h>
15 #include <hw/8254/8254.h> /* 8254 timer */
16 #include <hw/8259/8259.h> /* 8259 PIC interrupts */
17 #include <hw/vga/vgagui.h>
18 #include <hw/vga/vgatty.h>
19 #include <hw/ide/idelib.h>
23 unsigned char sanitizechar(unsigned char c) {
24 if (c < 32) return '.';
28 int wait_for_enter_or_escape() {
33 if (c == 0) c = getch() << 8;
34 } while (!(c == 13 || c == 27));
39 /* construct ATAPI/SCSI-MMC READ command according to user's choice, either READ(10) or READ(12) */
40 void do_construct_atapi_scsi_mmc_read(unsigned char *buf/*must be 12 bytes*/,uint32_t sector,uint32_t tlen_sect,unsigned char read_mode) {
42 if (read_mode == 12) {
43 /* command: READ(12) */
46 /* fill in the Logical Block Address */
47 buf[2] = sector >> 24;
48 buf[3] = sector >> 16;
52 buf[6] = tlen_sect >> 24UL;
53 buf[7] = tlen_sect >> 16UL;
54 buf[8] = tlen_sect >> 8UL;
58 /* command: READ(10) */
61 /* fill in the Logical Block Address */
62 buf[2] = sector >> 24;
63 buf[3] = sector >> 16;
67 buf[7] = tlen_sect >> 8;
72 /* check for another possible case where 16-bit PIO word is in lower half of 32-bit read, junk in upper */
73 int ide_memcmp_every_other_word(unsigned char *pio16,unsigned char *pio32,unsigned int words) {
75 uint16_t a = *((uint16_t*)pio16);
76 uint16_t b = (uint16_t)(*((uint32_t*)pio32) & 0xFFFF);
77 if (a != b) return (int)(a-b);
86 /* return 0 if all bytes are 0xFF */
87 int ide_memcmp_all_FF(unsigned char *d,unsigned int bytes) {
89 if (*d != 0xFF) return 1;
97 /* A warning to people who may write their own IDE code: If a drive
98 * has been put to sleep, or put through a host reset, the "drive ready"
99 * bit will NEVER come up. If you are naive, your code will loop forever
100 * waiting for drive ready. To get drive ready to come up you have to
101 * send it a NO-OP command, which it will reply with an error, but it
102 * will then signal readiness.
104 * Now, in this case the Status register (0x1F7/0x3F6) will always
105 * read back 0x00, but 0x00 is also what would be read back if no
106 * such device existed. How do we tell the two scenarios apart?
107 * Well it turns out that if the device is there, then anything you
108 * read/write from ports 0x1F2-0x1F5 will read back the same value.
109 * If the IDE device does not exist, then ports 0x1F2-0x1F5 will
110 * always return 0x00 (or 0xFF?) no matter what we write.
112 * Once we know the device is there, we can then "trick" the device
113 * into reporting readiness by issuing ATA NO-OP, which the device
114 * will respond to with an error, but more importantly, it will set
115 * the Device Ready bit. */
116 /* NOTE: The caller must have already gone through the process of writing the
117 * head & drive select and waiting for controller readiness. if the
118 * caller doesn't do that, this routine will probably end up running through
119 * the routine on the wrong IDE device */
120 int do_ide_controller_atapi_device_check_post_host_reset(struct ide_controller *ide) {
121 idelib_controller_update_status(ide);
122 if (idelib_controller_is_busy(ide)) return -1; /* YOU'RE SUPPOSED TO WAIT FOR CONTROLLER NOT-BUSY! */
123 if (idelib_controller_is_drive_ready(ide)) return 0; /* Drive indicates readiness, nothing to do */
125 if ((ide->last_status&0xC1) == 0) { /* <- typical post-reset state. VirtualBox/QEMU never raises Drive Ready bit */
126 struct ide_taskfile *tsk = idelib_controller_get_taskfile(ide,-1/*selected drive*/);
128 /* OK: If I write things to 0x1F2-0x1F5 can I read them back? */
129 tsk->sector_count = 0x55;
133 idelib_controller_apply_taskfile(ide,0x1C/*regs 2-4*/,IDELIB_TASKFILE_LBA48_UPDATE/*clear*/);
134 tsk->sector_count = tsk->lba0_3 = tsk->lba1_4 = 0; /* DEBUG: just to be sure */
135 idelib_controller_update_taskfile(ide,0x1C/*regs 2-4*/,0);
137 if (tsk->sector_count != 0x55 || tsk->lba0_3 != 0xAA || tsk->lba1_4 != 0x3F)
138 return -1; /* Nope. IDE device is not there (also possibly the device is fucked up) */
140 idelib_controller_update_status(ide);
142 if ((ide->last_status&0xC1) == 0) { /* <- if the first test did not trigger drive ready, then whack the command port with ATA NO-OP */
143 idelib_controller_write_command(ide,0x00);
144 t8254_wait(t8254_us2ticks(100000)); /* <- give it 100ms to respond */
145 idelib_controller_update_status(ide);
147 if ((ide->last_status&0xC1) == 0) { /* <- if the NO-OP test didn't work, then forget it, I'm out of ideas */
151 idelib_controller_ack_irq(ide);