/* */ #include #include #include #include #define FLOPPY 0x3F0 /* default floppy */ #define FLOPPY_DOR (FLOPPY + 0x2) #define FLOPPY_DIR (FLOPPY + 0x7) #define FDOR_MOTEA 0x10 #define FDOR_MOTEB 0x20 #define FDOR_DSEL0 0x01 #define FDOR_DSEL1 0x02 #define FDIR_DCHNG 0x80 #define SCL FDOR_MOTEA #define SDA FDOR_MOTEB #define SDA_IN FDIR_DCHNG #define LO_INV (SDA|SCL) #define LI_INV (SDA_IN) static unsigned char dor = (SCL | SDA); static unsigned int delay = 500; static unsigned int level = 1; #define udelay(a) do { } while (0) #define dprintf(l, f, x...) do { \ if (level >= l) printf(f , ##x); \ } while (0) void out_dor(unsigned char data) { outb(data ^ LO_INV, FLOPPY_DOR); dprintf(5, " > SCL=%d SDA=%d\n", (data & SCL) ? 1 : 0, (data & SDA) ? 1 : 0); } unsigned char in_dir(void) { unsigned char in = inb(FLOPPY_DIR) ^ LI_INV; dprintf(5, " < SDA=%d\n", (in & SDA_IN) ? 1 : 0); return in; } unsigned char pulse_scl(void) { /* take SCL high */ dor |= SCL; out_dor(dor); udelay(delay); /* read back data */ unsigned char bit = in_dir() & SDA_IN; udelay(delay); /* take SCL low again */ dor &= ~SCL; out_dor(dor); /* return value */ return bit ? 1 : 0; } void out_start(void) { /* clear SDA with SCL high */ dor &= ~SDA; out_dor(dor); udelay(delay); /* take SCL low */ dor &= ~SCL; out_dor(dor); udelay(delay); } void out_stop(void) { /* take SDA low */ dor &= ~SDA; out_dor(dor); udelay(delay); /* pull SCL high */ dor |= SCL; out_dor(dor); udelay(delay); /* take SDA high */ dor |= SDA; out_dor(dor); udelay(delay); } unsigned char out_bit(unsigned char bit) { /* output data bit */ dor = (dor & ~SDA) | (bit ? SDA : 0); out_dor(dor); udelay(delay); /* pulse and readback */ unsigned char ret = pulse_scl(); udelay(delay); return ret; } unsigned char in_bit(void) { /* take SDA high for readback */ dor |= SDA; out_dor(dor); udelay(delay); /* pulse and readback */ unsigned char bit = pulse_scl(); udelay(delay); return bit; } void out_byte(unsigned char byte) { int i; unsigned char val = 0; for (i=7; i>=0; i--) { int bit = (byte & (1 << i)) ? 1 : 0; int ret = out_bit(bit); val = val << 1 | ret; dprintf(3, "[O%d] %d %d\n", i, bit, ret); } int ack = in_bit(); dprintf(2, "[A*] %d\n", ack); dprintf(1, "[O*] >%02X <%02X %d\n", byte, val, ack); } int main(int argc, char *argv[]) { int i; /* Get access to the ports */ if (ioperm(FLOPPY, 8, 1)) { perror("ioperm"); exit(1); } /* initial state */ out_dor(dor); usleep(5000); out_start(); for (i=1; i> 2) << 4 | (i & 3)), FLOPPY_DOR); /* Sleep for a while (100 ms) */ usleep(500000); /* Read from the status port (BASE+1) and display the result */ printf("status: %d\n", inb(FLOPPY_DIR)); } #endif /* We don't need the ports anymore */ if (ioperm(FLOPPY, 8, 0)) { perror("ioperm"); exit(1); } exit(0); }