int floppy_seek_track(uint_t drive, uint_t track) { if (drive >= MAX_DRIVES) { return -1; } if (track == floppy_drives[drive].track) { return 0; } floppy_motor_on(drive); prepare_wait_irq(FLOPPY_IRQ); floppy_command(SEEK); floppy_command(drive); floppy_command(track); wait_irq(FLOPPY_IRQ); floppy_drive_seeked = drive; floppy_sense_interrupt(); if (track != floppy_drives[drive].track) { kprintf("FDD: ERROR: fd%u couldn't seek\n", drive); floppy_prepare_motor_off(drive); return -2; } /*kprintf("FDD: fd%u: Seeked track succesfully\n", drive);*/ floppy_prepare_motor_off(drive); return 0; }
// floppy commands static void cmd_floppy(void) { u08 cmd; u08 exit = 0; while((cmd = get_char()) != 0) { switch(cmd) { case 'e': floppy_select_on(); set_result(STATUS_OK); break; case 'd': floppy_select_off(); set_result(STATUS_OK); break; case 'o': floppy_motor_on(); set_result(STATUS_OK); break; case 'f': floppy_motor_off(); set_result(STATUS_OK); break; case 'w': // write protected? { // ensure floppy is selected u08 did_sel = floppy_select_on(); set_result(floppy_low_is_write_protected()); if(did_sel) { floppy_select_off(); } } break; case '?': set_result(floppy_status()); break; default: set_result(ERROR_SYNTAX); case '.': exit = 1; break; } if(exit) break; } }
int floppy_rw_sector(uint_t drive, uint8_t sector, uint8_t head, uint8_t cylinder, uintptr_t buffer, int write) { int a; alku: if (drive >= MAX_DRIVES || !floppy_drives[drive].type) { return -1; } if (inportb(FLOPPY_FIRST + DIGITAL_INPUT_REGISTER) & 0x80) { /* disk was changed */ floppy_seek_track(drive, 1); floppy_calibrate(drive); floppy_motor_off(drive); if (inportb(FLOPPY_FIRST + DIGITAL_INPUT_REGISTER) & 0x80) { kprintf("FDD: No floppy in fd%u\n", drive); return -2; } else { kprintf("FDD: Floppy changed, trying again...\n"); goto alku; } } if (floppy_seek_track(drive, cylinder)) if (floppy_seek_track(drive, cylinder)) if (floppy_seek_track(drive, cylinder)) { return -1; /* three seeks? */ } /* floppy_seek_track actually starts motor already, but... */ floppy_motor_on(drive); if (!(inportb(FLOPPY_FIRST + MAIN_STATUS_REGISTER) & 0x20)) { panic("Non-dma floppy transfer?\n"); } /* block size */ floppy_init_dma(buffer, 512, write); kwait(0, 1000 * floppy_params.head_settle_time); floppy_wait(); prepare_wait_irq(FLOPPY_IRQ); floppy_command(write ? WRITE_DATA : READ_DATA); floppy_command((head << 2) | drive); floppy_command(cylinder); floppy_command(head); floppy_command(sector); floppy_command(floppy_params.bytes_per_sector); /*sector size = 128*2^size*/ floppy_command(floppy_params.sectors_per_track); /*last sector*/ floppy_command(floppy_params.gap_length); /*27 default gap3 value*/ floppy_command(floppy_params.data_length); /*default value for data length*/ //kprintf("FDD: BPS: %u, SPT: %u, GL: %u, DL: %u\n", floppy_params.bytes_per_sector, floppy_params.sectors_per_track, floppy_params.gap_length, floppy_params.data_length); wait_irq(FLOPPY_IRQ); //kprintf("We got values "); for (a = 0; a < 7; a++) { /* TODO: Put these values somewhere? */ floppy_wait_data(); inportb(FLOPPY_FIRST + DATA_FIFO); //kprintf("%d ", inportb(FLOPPY_FIRST + DATA_FIFO)); } //kprintf(" from floppy controller after reading\n"); floppy_prepare_motor_off(drive); return 0; }
// sampler commands static void cmd_sampler(void) { u08 cmd, res; u08 exit = 0; while((cmd = get_char()) != 0) { switch(cmd) { case 'm': // read track to spi ram { u08 sel = floppy_select_on(); u08 mot = floppy_motor_on(); track_init(); res = trk_read_to_spiram(parse_hex_byte(1)); if(mot) floppy_motor_off(); if(sel) floppy_select_off(); set_result(res); } break; case 'f': // fake read track (only to spi ram) res = trk_read_sim(parse_hex_byte(1)); set_result(res); break; case 'v': // verify track with spi ram res = trk_check_spiram(parse_hex_byte(1)); set_result(res); break; // ----- checks ----- case 'i': // index check { u08 sel = floppy_select_on(); u08 mot = floppy_motor_on(); track_init(); res = trk_read_count_index(); if(mot) floppy_motor_off(); if(sel) floppy_select_off(); set_result(res); } break; case 'd': // read data check { u08 sel = floppy_select_on(); u08 mot = floppy_motor_on(); track_init(); res = trk_read_count_data(); if(mot) floppy_motor_off(); if(sel) floppy_select_off(); set_result(res); } break; case 's': // read data spectrum { u08 sel = floppy_select_on(); u08 mot = floppy_motor_on(); track_init(); res = trk_read_data_spectrum(parse_hex_byte(0)); if(mot) floppy_motor_off(); if(sel) floppy_select_off(); set_result(res); } break; default: set_result(ERROR_SYNTAX); case '.': exit = 1; break; } if(exit) break; } }