fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

8272: Add 8272 FDC emulation

Hampa Hug c7f8c3af f0a82946

+2196 -1
+3
Makefile.dep
··· 1679 1679 src/chipset/82xx/e8259.o: src/chipset/82xx/e8259.c \ 1680 1680 src/chipset/82xx/e8259.h 1681 1681 1682 + src/chipset/82xx/e8272.o: src/chipset/82xx/e8272.c \ 1683 + src/chipset/82xx/e8272.h 1684 + 1682 1685 src/chipset/clock/ds1743.o: src/chipset/clock/ds1743.c \ 1683 1686 src/chipset/clock/ds1743.h 1684 1687
+2 -1
src/chipset/82xx/Makefile.inc
··· 5 5 DIRS += $(rel) 6 6 DIST += $(rel)/Makefile.inc 7 7 8 - CS_82XX_BAS := e8237 e8250 e8253 e8255 e8259 8 + CS_82XX_BAS := e8237 e8250 e8253 e8255 e8259 e8272 9 9 CS_82XX_SRC := $(foreach f,$(CS_82XX_BAS),$(rel)/$(f).c) 10 10 CS_82XX_OBJ := $(foreach f,$(CS_82XX_BAS),$(rel)/$(f).o) 11 11 CS_82XX_HDR := $(foreach f,$(CS_82XX_BAS),$(rel)/$(f).h) ··· 18 18 $(rel)/e8253.o: $(rel)/e8253.c $(rel)/e8253.h 19 19 $(rel)/e8255.o: $(rel)/e8255.c $(rel)/e8255.h 20 20 $(rel)/e8259.o: $(rel)/e8259.c $(rel)/e8259.h 21 + $(rel)/e8272.o: $(rel)/e8272.c $(rel)/e8272.h
+2005
src/chipset/82xx/e8272.c
··· 1 + /***************************************************************************** 2 + * pce * 3 + *****************************************************************************/ 4 + 5 + /***************************************************************************** 6 + * File name: src/chipset/82xx/e8272.c * 7 + * Created: 2005-03-06 by Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2005-2010 Hampa Hug <hampa@hampa.ch> * 9 + *****************************************************************************/ 10 + 11 + /***************************************************************************** 12 + * This program is free software. You can redistribute it and / or modify it * 13 + * under the terms of the GNU General Public License version 2 as published * 14 + * by the Free Software Foundation. * 15 + * * 16 + * This program is distributed in the hope that it will be useful, but * 17 + * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 + * Public License for more details. * 20 + *****************************************************************************/ 21 + 22 + 23 + /* 24 + * FDC 8272 emulator 25 + */ 26 + 27 + #include <stdlib.h> 28 + #include <stdio.h> 29 + #include <string.h> 30 + 31 + #include "e8272.h" 32 + 33 + 34 + #ifndef E8272_DEBUG 35 + #define E8272_DEBUG 0 36 + #endif 37 + 38 + 39 + #define E8272_CMD_NONE 0 40 + #define E8272_CMD_SPECIFY 1 41 + #define E8272_CMD_SENSE_DRIVE_STATUS 2 42 + #define E8272_CMD_WRITE 3 43 + #define E8272_CMD_READ 4 44 + #define E8272_CMD_READ_TRACK 5 45 + #define E8272_CMD_RECALIBRATE 6 46 + #define E8272_CMD_SENSE_INT_STATUS 7 47 + #define E8272_CMD_READ_ID 8 48 + #define E8272_CMD_FORMAT 9 49 + #define E8272_CMD_SEEK 10 50 + 51 + #define E8272_CMD0_MT 0x80 52 + #define E8272_CMD0_MFM 0x40 53 + #define E8272_CMD0_SK 0x20 54 + 55 + #define E8272_MSR_D0B 0x01 56 + #define E8272_MSR_D1B 0x02 57 + #define E8272_MSR_D2B 0x04 58 + #define E8272_MSR_D3B 0x08 59 + #define E8272_MSR_CB 0x10 60 + #define E8272_MSR_NDM 0x20 61 + #define E8272_MSR_DIO 0x40 62 + #define E8272_MSR_RQM 0x80 63 + 64 + #define E8272_DOR_DSEL 0x01 65 + #define E8272_DOR_RESET 0x04 66 + #define E8272_DOR_DMAEN 0x08 67 + #define E8272_DOR_MOTEN0 0x10 68 + #define E8272_DOR_MOTEN1 0x20 69 + 70 + #define E8272_ST0_IC 0xc0 /* interrupt code */ 71 + #define E8272_ST0_SE 0x20 /* seek end */ 72 + 73 + #define E8272_ST1_EN 0x80 /* end of cylinder */ 74 + #define E8272_ST1_DE 0x20 /* data error */ 75 + #define E8272_ST1_OR 0x10 /* overrun */ 76 + #define E8272_ST1_ND 0x04 /* no data */ 77 + #define E8272_ST1_NW 0x02 /* not writeable */ 78 + #define E8272_ST1_MA 0x01 /* missing address mark */ 79 + 80 + #define E8272_ST2_DD 0x20 /* data field crc error */ 81 + #define E8272_ST2_WC 0x10 /* wrong cylinder */ 82 + #define E8272_ST2_BC 0x02 /* bad cylinder (ff) */ 83 + #define E8272_ST2_MD 0x01 /* missing data address mark */ 84 + 85 + #define E8272_ST3_FT 0x80 /* fault signal */ 86 + #define E8272_ST3_WP 0x40 /* write protect */ 87 + #define E8272_ST3_RDY 0x20 /* ready */ 88 + #define E8272_ST3_T0 0x10 /* track 0 */ 89 + #define E8272_ST3_TS 0x08 /* two side */ 90 + #define E8272_ST3_HD 0x04 /* head address */ 91 + #define E8272_ST3_US1 0x02 /* unit select 1 */ 92 + #define E8272_ST3_US0 0x02 /* unit select 2 */ 93 + 94 + 95 + #define E8272_RATE 250000 96 + #define E8272_RPS 5 97 + 98 + 99 + static void e8272_write_cmd (e8272_t *fdc, unsigned char val); 100 + 101 + 102 + static 103 + void e8272_drive_init (e8272_drive_t *drv, unsigned pd) 104 + { 105 + drv->d = pd; 106 + drv->c = 0; 107 + drv->h = 0; 108 + 109 + drv->ok = 0; 110 + drv->sct_cnt = 0; 111 + } 112 + 113 + void e8272_init (e8272_t *fdc) 114 + { 115 + unsigned i; 116 + 117 + fdc->dor = E8272_DOR_RESET; 118 + fdc->msr = E8272_MSR_RQM; 119 + 120 + fdc->st[0] = 0xc0; 121 + fdc->st[1] = 0x00; 122 + fdc->st[2] = 0x00; 123 + fdc->st[3] = 0x00; 124 + 125 + for (i = 0; i < 4; i++) { 126 + e8272_drive_init (&fdc->drv[i], i); 127 + } 128 + 129 + fdc->curdrv = &fdc->drv[0]; 130 + 131 + fdc->cmd_i = 0; 132 + fdc->cmd_n = 0; 133 + 134 + fdc->res_i = 0; 135 + fdc->res_n = 0; 136 + 137 + fdc->buf_i = 0; 138 + fdc->buf_n = 0; 139 + 140 + fdc->dma = 1; 141 + 142 + fdc->step_rate = 1; 143 + 144 + fdc->accurate = 0; 145 + 146 + fdc->delay_clock = 0; 147 + 148 + fdc->input_clock = 1000000; 149 + 150 + fdc->track_pos = 0; 151 + fdc->track_clk = 0; 152 + fdc->track_size = E8272_RATE / E8272_RPS; 153 + 154 + fdc->index_cnt = 0; 155 + 156 + fdc->set_data = NULL; 157 + fdc->get_data = NULL; 158 + fdc->set_tc = NULL; 159 + fdc->set_clock = NULL; 160 + 161 + fdc->blk_rd_ext = NULL; 162 + fdc->blk_rd = NULL; 163 + 164 + fdc->blk_wr_ext = NULL; 165 + fdc->blk_wr = NULL; 166 + 167 + fdc->blk_fmt_ext = NULL; 168 + fdc->blk_fmt = NULL; 169 + 170 + fdc->blk_rdid_ext = NULL; 171 + fdc->blk_rdid = NULL; 172 + 173 + fdc->irq_ext = NULL; 174 + fdc->irq_val = 0; 175 + fdc->irq = NULL; 176 + 177 + fdc->dreq_ext = NULL; 178 + fdc->dreq_val = 0; 179 + fdc->dreq = NULL; 180 + } 181 + 182 + e8272_t *e8272_new (void) 183 + { 184 + e8272_t *fdc; 185 + 186 + fdc = malloc (sizeof (e8272_t)); 187 + 188 + if (fdc == NULL) { 189 + return (NULL); 190 + } 191 + 192 + e8272_init (fdc); 193 + 194 + return (fdc); 195 + } 196 + 197 + void e8272_free (e8272_t *fdc) 198 + { 199 + } 200 + 201 + void e8272_del (e8272_t *fdc) 202 + { 203 + if (fdc != NULL) { 204 + e8272_free (fdc); 205 + free (fdc); 206 + } 207 + } 208 + 209 + 210 + void e8272_set_irq_fct (e8272_t *fdc, void *ext, void *fct) 211 + { 212 + fdc->irq = fct; 213 + fdc->irq_ext = ext; 214 + } 215 + 216 + void e8272_set_dreq_fct (e8272_t *fdc, void *ext, void *fct) 217 + { 218 + fdc->dreq = fct; 219 + fdc->dreq_ext = ext; 220 + } 221 + 222 + 223 + void e8272_set_block_read_fct (e8272_t *fdc, void *ext, void *fct) 224 + { 225 + fdc->blk_rd_ext = ext; 226 + fdc->blk_rd = fct; 227 + } 228 + 229 + void e8272_set_block_write_fct (e8272_t *fdc, void *ext, void *fct) 230 + { 231 + fdc->blk_wr_ext = ext; 232 + fdc->blk_wr = fct; 233 + } 234 + 235 + void e8272_set_block_fmt_fct (e8272_t *fdc, void *ext, void *fct) 236 + { 237 + fdc->blk_fmt_ext = ext; 238 + fdc->blk_fmt = fct; 239 + } 240 + 241 + void e8272_set_block_rdid_fct (e8272_t *fdc, void *ext, void *fct) 242 + { 243 + fdc->blk_rdid_ext = ext; 244 + fdc->blk_rdid = fct; 245 + } 246 + 247 + 248 + void e8272_set_input_clock (e8272_t *fdc, unsigned long clk) 249 + { 250 + fdc->input_clock = clk; 251 + } 252 + 253 + void e8272_set_accuracy (e8272_t *fdc, int accurate) 254 + { 255 + fdc->accurate = (accurate != 0); 256 + } 257 + 258 + /* 259 + * Set the IRQ output 260 + */ 261 + static 262 + void e8272_set_irq (e8272_t *fdc, unsigned char val) 263 + { 264 + if (fdc->irq_val != val) { 265 + #if E8272_DEBUG >= 3 266 + fprintf (stderr, "E8272: irq = %d\n", val); 267 + #endif 268 + fdc->irq_val = val; 269 + if (fdc->irq != NULL) { 270 + fdc->irq (fdc->irq_ext, val); 271 + } 272 + } 273 + } 274 + 275 + /* 276 + * Set the DREQ output 277 + */ 278 + static 279 + void e8272_set_dreq (e8272_t *fdc, unsigned char val) 280 + { 281 + if (fdc->dreq_val != val) { 282 + fdc->dreq_val = val; 283 + 284 + if (fdc->dreq != NULL) { 285 + fdc->dreq (fdc->dreq_ext, val); 286 + } 287 + } 288 + } 289 + 290 + 291 + static 292 + unsigned e8272_block_read (e8272_t *fdc, void *buf, unsigned *cnt, unsigned d, 293 + unsigned pc, unsigned ph, unsigned ps, unsigned s) 294 + { 295 + unsigned r; 296 + 297 + if (fdc->blk_rd == NULL) { 298 + return (E8272_ERR_NO_ID); 299 + } 300 + 301 + if (*cnt > 8192) { 302 + *cnt = 0; 303 + return (E8272_ERR_OTHER); 304 + } 305 + 306 + r = fdc->blk_rd (fdc->blk_rd_ext, buf, cnt, d, pc, ph, ps, s); 307 + 308 + return (r); 309 + } 310 + 311 + static 312 + unsigned e8272_block_write (e8272_t *fdc, const void *buf, unsigned *cnt, unsigned d, 313 + unsigned pc, unsigned ph, unsigned ps, unsigned s) 314 + { 315 + unsigned r; 316 + 317 + if (fdc->blk_wr == NULL) { 318 + return (E8272_ERR_NO_ID); 319 + } 320 + 321 + if (*cnt > 8192) { 322 + *cnt = 0; 323 + return (E8272_ERR_OTHER); 324 + } 325 + 326 + r = fdc->blk_wr (fdc->blk_rd_ext, buf, cnt, d, pc, ph, ps, s); 327 + 328 + return (r); 329 + } 330 + 331 + static 332 + int e8272_block_format (e8272_t *fdc, unsigned d, 333 + unsigned pc, unsigned ph, unsigned ps, 334 + unsigned lc, unsigned lh, unsigned ls, unsigned ln, unsigned fill) 335 + { 336 + int r; 337 + 338 + if (fdc->blk_fmt == NULL) { 339 + return (1); 340 + } 341 + 342 + r = fdc->blk_fmt (fdc->blk_rd_ext, d, pc, ph, ps, lc, lh, ls, ln, fill); 343 + 344 + return (r); 345 + } 346 + 347 + static 348 + int e8272_block_rdid (e8272_t *fdc, unsigned d, 349 + unsigned pc, unsigned ph, unsigned ps, 350 + unsigned *lc, unsigned *lh, unsigned *ls, unsigned *ln) 351 + { 352 + int r; 353 + 354 + if (fdc->blk_rdid == NULL) { 355 + return (1); 356 + } 357 + 358 + r = fdc->blk_rdid (fdc->blk_rdid_ext, d, pc, ph, ps, lc, lh, ls, ln); 359 + 360 + return (r); 361 + } 362 + 363 + /* 364 + * Read all the IDs on a track into fdc->curdrv->sct. 365 + */ 366 + static 367 + void e8272_read_track (e8272_t *fdc) 368 + { 369 + unsigned i; 370 + unsigned lc, lh, ls, ln; 371 + unsigned long ofs, cnt; 372 + e8272_drive_t *drv; 373 + 374 + drv = fdc->curdrv; 375 + 376 + if (drv->ok) { 377 + return; 378 + } 379 + 380 + drv->sct_cnt = 0; 381 + 382 + for (i = 0; i < E8272_MAX_SCT; i++) { 383 + if (e8272_block_rdid (fdc, drv->d, drv->c, drv->h, i, &lc, &lh, &ls, &ln)) { 384 + break; 385 + } 386 + 387 + drv->sct[i].c = lc; 388 + drv->sct[i].h = lh; 389 + drv->sct[i].s = ls; 390 + drv->sct[i].n = ln; 391 + 392 + drv->sct_cnt += 1; 393 + } 394 + 395 + ofs = 8 * 150; 396 + cnt = fdc->track_size - ofs; 397 + 398 + for (i = 0; i < drv->sct_cnt; i++) { 399 + drv->sct[i].ofs = ofs + (2UL * i * cnt) / (2UL * drv->sct_cnt + 1); 400 + } 401 + 402 + drv->ok = 1; 403 + } 404 + 405 + static 406 + void e8272_select_cylinder (e8272_t *fdc, unsigned pd, unsigned pc) 407 + { 408 + e8272_drive_t *drv; 409 + 410 + drv = &fdc->drv[pd & 3]; 411 + 412 + drv->ok = 0; 413 + drv->c = pc; 414 + drv->sct_cnt = 0; 415 + 416 + fdc->curdrv = drv; 417 + } 418 + 419 + static 420 + void e8272_select_head (e8272_t *fdc, unsigned pd, unsigned ph) 421 + { 422 + e8272_drive_t *drv; 423 + 424 + drv = &fdc->drv[pd & 3]; 425 + 426 + drv->ok = 0; 427 + drv->h = ph; 428 + drv->sct_cnt = 0; 429 + 430 + fdc->curdrv = drv; 431 + } 432 + 433 + /* 434 + * Get the last ID before the current track position. 435 + */ 436 + static 437 + unsigned e8272_get_current_id (e8272_t *fdc) 438 + { 439 + unsigned i; 440 + 441 + if (fdc->curdrv->sct_cnt == 0) { 442 + return (0); 443 + } 444 + 445 + for (i = 0; i < fdc->curdrv->sct_cnt; i++) { 446 + if (fdc->curdrv->sct[i].ofs > fdc->track_pos) { 447 + if (i == 0) { 448 + return (fdc->curdrv->sct_cnt - 1); 449 + } 450 + else { 451 + return (i - 1); 452 + } 453 + } 454 + } 455 + 456 + return (fdc->curdrv->sct_cnt - 1); 457 + } 458 + 459 + /* 460 + * Convert bits to input clock. 461 + */ 462 + static 463 + unsigned long e8272_bits_to_clock (e8272_t *fdc, unsigned long bits) 464 + { 465 + unsigned long clk; 466 + 467 + clk = ((unsigned long long) bits * fdc->input_clock) / E8272_RATE; 468 + 469 + return (clk); 470 + } 471 + 472 + static 473 + void e8272_delay_bits (e8272_t *fdc, unsigned long bits, int accurate) 474 + { 475 + if ((fdc->accurate == 0) && (accurate == 0)) { 476 + fdc->track_pos += bits; 477 + 478 + while (fdc->track_pos >= fdc->track_size) { 479 + fdc->track_pos -= fdc->track_size; 480 + fdc->index_cnt += 1; 481 + } 482 + 483 + fdc->delay_clock = 0; 484 + } 485 + else { 486 + fdc->delay_clock = e8272_bits_to_clock (fdc, bits); 487 + } 488 + } 489 + 490 + static 491 + void e8272_delay_index (e8272_t *fdc, int accurate) 492 + { 493 + e8272_delay_bits (fdc, fdc->track_size - fdc->track_pos, accurate); 494 + } 495 + 496 + static 497 + void e8272_delay_id (e8272_t *fdc, unsigned id, int accurate) 498 + { 499 + unsigned long bits, pos; 500 + 501 + if (id >= fdc->curdrv->sct_cnt) { 502 + e8272_delay_index (fdc, accurate); 503 + return; 504 + } 505 + 506 + pos = fdc->curdrv->sct[id].ofs; 507 + 508 + if (pos < fdc->track_pos) { 509 + bits = pos - fdc->track_pos + fdc->track_size; 510 + } 511 + else { 512 + bits = pos - fdc->track_pos; 513 + } 514 + 515 + bits += 128; 516 + 517 + e8272_delay_bits (fdc, bits, accurate); 518 + } 519 + 520 + static 521 + void e8272_delay_next_id (e8272_t *fdc, int accurate) 522 + { 523 + unsigned id; 524 + 525 + id = e8272_get_current_id (fdc); 526 + 527 + id += 1; 528 + 529 + if (id >= fdc->curdrv->sct_cnt) { 530 + id = 0; 531 + } 532 + 533 + e8272_delay_id (fdc, id, accurate); 534 + } 535 + 536 + 537 + /* 538 + * Move to the next sector ID for read and write commands 539 + */ 540 + static 541 + void e8272_next_id (e8272_t *fdc) 542 + { 543 + if (fdc->cmd[4] != fdc->cmd[6]) { 544 + fdc->cmd[4] += 1; 545 + return; 546 + } 547 + 548 + fdc->cmd[4] = 1; 549 + 550 + if (fdc->cmd[0] & E8272_CMD0_MT) { 551 + fdc->cmd[1] ^= 0x04; 552 + fdc->cmd[3] ^= 0x01; 553 + 554 + if ((fdc->cmd[1] & 0x04) == 0) { 555 + fdc->cmd[2] += 1; 556 + } 557 + } 558 + else { 559 + fdc->cmd[2] += 1; 560 + } 561 + } 562 + 563 + /* 564 + * Request a data transfer byte from (rd == 0) / to (rd != 0) the CPU. 565 + */ 566 + static 567 + void e8272_request_data (e8272_t *fdc, int rd) 568 + { 569 + if (rd) { 570 + fdc->msr |= E8272_MSR_DIO; 571 + } 572 + else { 573 + fdc->msr &= ~E8272_MSR_DIO; 574 + } 575 + 576 + if (fdc->dma) { 577 + fdc->msr &= ~(E8272_MSR_RQM | E8272_MSR_NDM); 578 + 579 + e8272_set_dreq (fdc, 1); 580 + } 581 + else { 582 + fdc->msr |= E8272_MSR_RQM | E8272_MSR_NDM; 583 + 584 + e8272_set_irq (fdc, 1); 585 + } 586 + 587 + fdc->msr |= E8272_MSR_CB; 588 + } 589 + 590 + /* 591 + * Request a control byte transfer from (rd == 0) / to (rd != 0) the CPU. 592 + */ 593 + static 594 + void e8272_request_control (e8272_t *fdc, int rd) 595 + { 596 + if (rd) { 597 + fdc->msr |= (E8272_MSR_DIO | E8272_MSR_CB); 598 + } 599 + else { 600 + fdc->msr &= ~(E8272_MSR_DIO | E8272_MSR_CB); 601 + } 602 + 603 + if (fdc->dma) { 604 + e8272_set_dreq (fdc, 0); 605 + } 606 + 607 + fdc->msr |= E8272_MSR_RQM; 608 + fdc->msr &= ~E8272_MSR_NDM; 609 + } 610 + 611 + 612 + /* 613 + * Ready for next command 614 + */ 615 + static 616 + void cmd_done (e8272_t *fdc) 617 + { 618 + fdc->set_data = e8272_write_cmd; 619 + fdc->get_data = NULL; 620 + fdc->set_tc = NULL; 621 + fdc->set_clock = NULL; 622 + 623 + e8272_request_control (fdc, 0); 624 + } 625 + 626 + /* 627 + * Write a command byte 628 + */ 629 + static 630 + void cmd_set_command (e8272_t *fdc, unsigned char val) 631 + { 632 + fdc->cmd[fdc->cmd_i++] = val; 633 + 634 + if (fdc->cmd_i < fdc->cmd_n) { 635 + return; 636 + } 637 + 638 + fdc->set_data = NULL; 639 + 640 + fdc->msr &= ~E8272_MSR_RQM; 641 + fdc->msr |= E8272_MSR_CB; 642 + 643 + if (fdc->start_cmd != NULL) { 644 + fdc->start_cmd (fdc); 645 + } 646 + } 647 + 648 + /* 649 + * Get a result byte 650 + */ 651 + static 652 + unsigned char cmd_get_result (e8272_t *fdc) 653 + { 654 + unsigned char val; 655 + 656 + val = fdc->res[fdc->res_i++]; 657 + 658 + if (fdc->res_i >= fdc->res_n) { 659 + cmd_done (fdc); 660 + } 661 + 662 + #if E8272_DEBUG >= 3 663 + fprintf (stderr, "E8272: get result (%02X)\n", val); 664 + #endif 665 + 666 + return (val); 667 + } 668 + 669 + /* 670 + * Enter the result phase 671 + */ 672 + static 673 + void cmd_result (e8272_t *fdc, unsigned cnt) 674 + { 675 + fdc->res_i = 0; 676 + fdc->res_n = cnt; 677 + 678 + fdc->set_data = NULL; 679 + fdc->get_data = cmd_get_result; 680 + fdc->set_tc = NULL; 681 + fdc->set_clock = NULL; 682 + 683 + e8272_request_control (fdc, 1); 684 + } 685 + 686 + 687 + /***************************************************************************** 688 + * read 689 + *****************************************************************************/ 690 + 691 + static void cmd_read_clock (e8272_t *fdc, unsigned long cnt); 692 + 693 + static 694 + void cmd_read_tc (e8272_t *fdc) 695 + { 696 + #if E8272_DEBUG >= 2 697 + fprintf (stderr, "E8272: CMD=%02X D=%u READ TC" 698 + " (pc=%u, ph=%u c=%u, h=%u, s=%u, n=%u eot=%u)\n", 699 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 700 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5], fdc->cmd[6] 701 + ); 702 + #endif 703 + 704 + /* head and unit */ 705 + fdc->st[0] = (fdc->st[0] & ~0x07) | (fdc->cmd[1] & 0x07); 706 + 707 + fdc->res[0] = fdc->st[0]; 708 + fdc->res[1] = fdc->st[1]; 709 + fdc->res[2] = fdc->st[2]; 710 + fdc->res[3] = fdc->cmd[2]; 711 + fdc->res[4] = fdc->cmd[3]; 712 + fdc->res[5] = fdc->cmd[4]; 713 + fdc->res[6] = fdc->cmd[5]; 714 + 715 + cmd_result (fdc, 7); 716 + 717 + e8272_set_irq (fdc, 1); 718 + } 719 + 720 + static 721 + void cmd_read_error (e8272_t *fdc, unsigned err) 722 + { 723 + #if E8272_DEBUG >= 1 724 + fprintf (stderr, 725 + "E8272: CMD=%02X D=%u READ ERROR" 726 + " (pc=%u, ph=%u c=%u, h=%u, s=%u, n=%u eot=%u)\n", 727 + fdc->cmd[0], fdc->cmd[1] & 3, 728 + fdc->curdrv->c, fdc->curdrv->h, 729 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5], fdc->cmd[6] 730 + ); 731 + #endif 732 + 733 + fdc->read_error = 1; 734 + 735 + /* abnormal termination */ 736 + fdc->st[0] = (fdc->st[0] & 0x3f) | 0x40; 737 + 738 + if (err & E8272_ERR_CRC_DATA) { 739 + fdc->st[1] |= E8272_ST1_DE; 740 + fdc->st[2] |= E8272_ST2_DD; 741 + } 742 + else if (err & E8272_ERR_NO_ID) { 743 + fdc->st[1] |= E8272_ST1_MA | E8272_ST1_ND; 744 + } 745 + else if (err & E8272_ERR_NO_DATA) { 746 + fdc->st[1] |= E8272_ST1_MA | E8272_ST1_ND; 747 + fdc->st[2] |= E8272_ST2_MD; 748 + } 749 + else { 750 + fdc->st[1] |= E8272_ST1_EN | E8272_ST1_ND; 751 + } 752 + } 753 + 754 + static 755 + unsigned char cmd_read_get_data (e8272_t *fdc) 756 + { 757 + unsigned char val; 758 + 759 + val = fdc->buf[fdc->buf_i++]; 760 + 761 + if (fdc->dma) { 762 + e8272_set_dreq (fdc, 0); 763 + } 764 + 765 + if (fdc->buf_i < fdc->buf_n) { 766 + e8272_request_data (fdc, 1); 767 + return (val); 768 + } 769 + 770 + fdc->msr &= ~(E8272_MSR_RQM | E8272_MSR_DIO); 771 + 772 + fdc->get_data = NULL; 773 + fdc->set_clock = cmd_read_clock; 774 + 775 + if (fdc->read_error) { 776 + cmd_read_tc (fdc); 777 + } 778 + else { 779 + e8272_next_id (fdc); 780 + } 781 + 782 + return (val); 783 + } 784 + 785 + static 786 + void cmd_read_clock (e8272_t *fdc, unsigned long cnt) 787 + { 788 + unsigned id; 789 + unsigned c, h, s, n; 790 + unsigned cnt1, cnt2; 791 + unsigned err; 792 + e8272_sct_t *sct; 793 + 794 + if (fdc->index_cnt >= 2) { 795 + cmd_read_error (fdc, E8272_ERR_NO_ID); 796 + cmd_read_tc (fdc); 797 + return; 798 + } 799 + 800 + if (fdc->delay_clock > 0) { 801 + return; 802 + } 803 + 804 + id = e8272_get_current_id (fdc); 805 + 806 + e8272_delay_next_id (fdc, 0); 807 + 808 + if ((fdc->cmd[0] & E8272_CMD0_MFM) == 0) { 809 + return; 810 + } 811 + 812 + c = fdc->cmd[2]; 813 + h = fdc->cmd[3]; 814 + s = fdc->cmd[4]; 815 + n = fdc->cmd[5]; 816 + 817 + if (id >= fdc->curdrv->sct_cnt) { 818 + return; 819 + } 820 + 821 + sct = &fdc->curdrv->sct[id]; 822 + 823 + if ((sct->c != c) || (sct->h != h) || (sct->s != s)) { 824 + /* wrong cylinder */ 825 + return; 826 + } 827 + 828 + fdc->index_cnt = 0; 829 + 830 + if (n > 6) { 831 + cmd_read_error (fdc, E8272_ERR_OTHER); 832 + cmd_read_tc (fdc); 833 + return; 834 + } 835 + 836 + if (n == 0) { 837 + cnt1 = fdc->cmd[8]; 838 + } 839 + else { 840 + cnt1 = 128 << n; 841 + } 842 + 843 + cnt2 = cnt1; 844 + 845 + err = e8272_block_read (fdc, fdc->buf, &cnt2, 846 + fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, id, s 847 + ); 848 + 849 + fdc->buf_i = 0; 850 + fdc->buf_n = cnt2; 851 + 852 + if (err) { 853 + cmd_read_error (fdc, err); 854 + } 855 + 856 + if (fdc->buf_n > 0) { 857 + e8272_request_data (fdc, 1); 858 + 859 + fdc->set_clock = NULL; 860 + fdc->get_data = cmd_read_get_data; 861 + } 862 + else { 863 + cmd_read_tc (fdc); 864 + } 865 + } 866 + 867 + static 868 + void cmd_read (e8272_t *fdc) 869 + { 870 + e8272_select_head (fdc, fdc->cmd[1] & 3, (fdc->cmd[1] >> 2) & 1); 871 + e8272_read_track (fdc); 872 + 873 + #if E8272_DEBUG >= 1 874 + fprintf (stderr, "E8272: CMD=%02X D=%u" 875 + " READ (pc=%u, ph=%u, c=%u, h=%u, s=%u, n=%u, eot=%u)\n", 876 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 877 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5], fdc->cmd[6] 878 + ); 879 + #endif 880 + 881 + fdc->st[0] = 0; 882 + fdc->st[1] = 0; 883 + fdc->st[2] = 0; 884 + 885 + fdc->read_error = 0; 886 + fdc->index_cnt = 0; 887 + 888 + e8272_delay_next_id (fdc, 0); 889 + 890 + fdc->set_clock = cmd_read_clock; 891 + fdc->set_tc = cmd_read_tc; 892 + } 893 + 894 + 895 + /***************************************************************************** 896 + * read track 897 + *****************************************************************************/ 898 + 899 + static void cmd_read_track_clock (e8272_t *fdc, unsigned long cnt); 900 + 901 + static 902 + void cmd_read_track_tc (e8272_t *fdc) 903 + { 904 + #if E8272_DEBUG >= 2 905 + fprintf (stderr, "E8272: CMD=%02X D=%u READ TRACK TC\n", 906 + fdc->cmd[0], fdc->cmd[1] & 3 907 + ); 908 + #endif 909 + 910 + /* head and unit */ 911 + fdc->st[0] = (fdc->st[0] & ~0x07) | (fdc->cmd[1] & 0x07); 912 + 913 + fdc->res[0] = fdc->st[0]; 914 + fdc->res[1] = fdc->st[1]; 915 + fdc->res[2] = fdc->st[2]; 916 + fdc->res[3] = fdc->cmd[2]; 917 + fdc->res[4] = fdc->cmd[3]; 918 + fdc->res[5] = fdc->cmd[4]; 919 + fdc->res[6] = fdc->cmd[5]; 920 + 921 + cmd_result (fdc, 7); 922 + 923 + e8272_set_irq (fdc, 1); 924 + } 925 + 926 + static 927 + void cmd_read_track_error (e8272_t *fdc, unsigned err) 928 + { 929 + #if E8272_DEBUG >= 1 930 + fprintf (stderr, "E8272: read track error (%04X)\n", err); 931 + #endif 932 + 933 + /* abnormal termination */ 934 + fdc->st[0] = (fdc->st[0] & 0x3f) | 0x40; 935 + 936 + if (err & E8272_ERR_NO_ID) { 937 + fdc->st[1] |= E8272_ST1_MA; 938 + } 939 + else { 940 + fdc->st[1] |= E8272_ST1_EN | E8272_ST1_ND; 941 + } 942 + 943 + cmd_read_track_tc (fdc); 944 + } 945 + 946 + static 947 + unsigned char cmd_read_track_get_data (e8272_t *fdc) 948 + { 949 + unsigned char val; 950 + 951 + val = fdc->buf[fdc->buf_i++]; 952 + 953 + if (fdc->dma) { 954 + e8272_set_dreq (fdc, 0); 955 + } 956 + 957 + if (fdc->buf_i < fdc->buf_n) { 958 + e8272_request_data (fdc, 1); 959 + return (val); 960 + } 961 + 962 + fdc->msr &= ~(E8272_MSR_RQM | E8272_MSR_DIO); 963 + 964 + fdc->read_track_cnt += 1; 965 + 966 + if (fdc->read_track_cnt >= fdc->cmd[6]) { 967 + cmd_read_track_tc (fdc); 968 + return (val); 969 + } 970 + 971 + fdc->get_data = NULL; 972 + fdc->set_clock = cmd_read_track_clock; 973 + 974 + return (val); 975 + } 976 + 977 + static 978 + void cmd_read_track_clock (e8272_t *fdc, unsigned long cnt) 979 + { 980 + unsigned id; 981 + unsigned bcnt, err; 982 + e8272_sct_t *sct; 983 + 984 + if (fdc->index_cnt >= 2) { 985 + cmd_read_track_error (fdc, E8272_ERR_NO_ID); 986 + return; 987 + } 988 + 989 + if (fdc->delay_clock > 0) { 990 + return; 991 + } 992 + 993 + e8272_delay_next_id (fdc, 0); 994 + 995 + if ((fdc->cmd[0] & E8272_CMD0_MFM) == 0) { 996 + return; 997 + } 998 + 999 + id = e8272_get_current_id (fdc); 1000 + 1001 + if (id >= fdc->curdrv->sct_cnt) { 1002 + return; 1003 + } 1004 + 1005 + fdc->index_cnt = 0; 1006 + 1007 + sct = &fdc->curdrv->sct[id]; 1008 + 1009 + if ((sct->c == fdc->cmd[2]) && (sct->h == fdc->cmd[3])) { 1010 + if (sct->s == fdc->cmd[4]) { 1011 + fdc->st[1] &= ~E8272_ST1_ND; 1012 + } 1013 + } 1014 + 1015 + #if E8272_DEBUG >= 1 1016 + fprintf (stderr, 1017 + "E8272: CMD=%02X D=%u READ TRACK CONT" 1018 + " (pc=%u, ph=%u, c=%u, h=%u, s=%u, n=%u eot=%u)\n", 1019 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1020 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5], fdc->cmd[6] 1021 + ); 1022 + #endif 1023 + 1024 + bcnt = 8192; 1025 + 1026 + err = e8272_block_read (fdc, fdc->buf, &bcnt, 1027 + fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1028 + id, sct->s 1029 + ); 1030 + 1031 + fdc->buf_i = 0; 1032 + fdc->buf_n = bcnt; 1033 + 1034 + err &= ~(E8272_ERR_DATALEN | E8272_ERR_CRC_DATA); 1035 + 1036 + if (err) { 1037 + cmd_read_track_error (fdc, err); 1038 + return; 1039 + } 1040 + 1041 + if (fdc->buf_n > 0) { 1042 + e8272_request_data (fdc, 1); 1043 + 1044 + fdc->set_clock = NULL; 1045 + fdc->get_data = cmd_read_track_get_data; 1046 + } 1047 + } 1048 + 1049 + static 1050 + void cmd_read_track (e8272_t *fdc) 1051 + { 1052 + e8272_select_head (fdc, fdc->cmd[1] & 3, (fdc->cmd[1] >> 2) & 1); 1053 + e8272_read_track (fdc); 1054 + 1055 + #if E8272_DEBUG >= 1 1056 + fprintf (stderr, 1057 + "E8272: CMD=%02X D=%u READ TRACK" 1058 + " (pc=%u, ph=%u, c=%u, h=%u s=%u, n=%u, eot=%u)\n", 1059 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1060 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5], fdc->cmd[6] 1061 + ); 1062 + #endif 1063 + 1064 + fdc->st[0] = 0; 1065 + fdc->st[1] = E8272_ST1_ND; 1066 + fdc->st[2] = 0; 1067 + 1068 + fdc->read_track_cnt = 0; 1069 + fdc->index_cnt = 0; 1070 + 1071 + e8272_delay_id (fdc, 0, 0); 1072 + 1073 + fdc->set_clock = cmd_read_track_clock; 1074 + fdc->set_tc = cmd_read_track_tc; 1075 + } 1076 + 1077 + 1078 + /***************************************************************************** 1079 + * read id 1080 + *****************************************************************************/ 1081 + 1082 + static 1083 + void cmd_read_id_error (e8272_t *fdc) 1084 + { 1085 + #if E8272_DEBUG >= 1 1086 + fprintf (stderr, 1087 + "E8272: CMD=%02X D=%u READ ID ERROR (pc=%u ph=%u)\n", 1088 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h 1089 + ); 1090 + #endif 1091 + 1092 + fdc->st[0] = 0x40 | (fdc->cmd[1] & 7); 1093 + fdc->st[1] |= E8272_ST1_MA | E8272_ST1_ND; 1094 + 1095 + fdc->res[0] = fdc->st[0]; 1096 + fdc->res[1] = fdc->st[1]; 1097 + fdc->res[2] = fdc->st[2]; 1098 + fdc->res[3] = 0; 1099 + fdc->res[4] = 0; 1100 + fdc->res[5] = 0; 1101 + fdc->res[6] = 0; 1102 + 1103 + cmd_result (fdc, 7); 1104 + 1105 + e8272_set_irq (fdc, 1); 1106 + } 1107 + 1108 + static 1109 + void cmd_read_id_clock (e8272_t *fdc, unsigned long cnt) 1110 + { 1111 + unsigned id; 1112 + e8272_sct_t *sct; 1113 + 1114 + if (fdc->index_cnt >= 2) { 1115 + cmd_read_id_error (fdc); 1116 + return; 1117 + } 1118 + 1119 + if (fdc->delay_clock > 0) { 1120 + return; 1121 + } 1122 + 1123 + e8272_delay_next_id (fdc, 1); 1124 + 1125 + if ((fdc->cmd[0] & E8272_CMD0_MFM) == 0) { 1126 + return; 1127 + } 1128 + 1129 + id = e8272_get_current_id (fdc); 1130 + 1131 + if (id >= fdc->curdrv->sct_cnt) { 1132 + return; 1133 + } 1134 + 1135 + sct = &fdc->curdrv->sct[id]; 1136 + 1137 + #if E8272_DEBUG >= 1 1138 + fprintf (stderr, 1139 + "E8272: CMD=%02X D=%u READ ID (pc=%u ph=%u id=[%02x %02x %02x %02x])\n", 1140 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1141 + sct->c, sct->h, sct->s, sct->n 1142 + ); 1143 + #endif 1144 + 1145 + fdc->st[0] = (fdc->st[0] & ~0x07) | (fdc->cmd[1] & 0x07); 1146 + 1147 + fdc->res[0] = fdc->st[0]; 1148 + fdc->res[1] = fdc->st[1]; 1149 + fdc->res[2] = fdc->st[2]; 1150 + fdc->res[3] = sct->c; 1151 + fdc->res[4] = sct->h; 1152 + fdc->res[5] = sct->s; 1153 + fdc->res[6] = sct->n; 1154 + 1155 + cmd_result (fdc, 7); 1156 + 1157 + e8272_set_irq (fdc, 1); 1158 + } 1159 + 1160 + static 1161 + void cmd_read_id (e8272_t *fdc) 1162 + { 1163 + e8272_select_head (fdc, fdc->cmd[1] & 3, (fdc->cmd[1] >> 2) & 1); 1164 + e8272_read_track (fdc); 1165 + 1166 + #if E8272_DEBUG >= 2 1167 + fprintf (stderr, "E8272: CMD=%02X D=%u READ ID (pc=%u, ph=%u)\n", 1168 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h 1169 + ); 1170 + #endif 1171 + 1172 + fdc->index_cnt = 0; 1173 + 1174 + fdc->st[0] = 0; 1175 + fdc->st[1] = 0; 1176 + fdc->st[2] = 0; 1177 + 1178 + e8272_delay_next_id (fdc, 1); 1179 + 1180 + fdc->set_clock = cmd_read_id_clock; 1181 + } 1182 + 1183 + 1184 + /***************************************************************************** 1185 + * write 1186 + *****************************************************************************/ 1187 + 1188 + static void cmd_write_clock (e8272_t *fdc, unsigned long cnt); 1189 + 1190 + static 1191 + void cmd_write_tc (e8272_t *fdc) 1192 + { 1193 + #if E8272_DEBUG >= 2 1194 + fprintf (stderr, "E8272: CMD=%02X D=%u WRITE TC\n", 1195 + fdc->cmd[0], fdc->cmd[1] & 3 1196 + ); 1197 + #endif 1198 + 1199 + fdc->st[0] = (fdc->st[0] & ~0x07) | (fdc->cmd[1] & 0x07); 1200 + 1201 + fdc->res[0] = fdc->st[0]; 1202 + fdc->res[1] = fdc->st[1]; 1203 + fdc->res[2] = fdc->st[2]; 1204 + fdc->res[3] = fdc->cmd[2]; 1205 + fdc->res[4] = fdc->cmd[3]; 1206 + fdc->res[5] = fdc->cmd[4]; 1207 + fdc->res[6] = fdc->cmd[5]; 1208 + 1209 + cmd_result (fdc, 7); 1210 + 1211 + e8272_set_irq (fdc, 1); 1212 + } 1213 + 1214 + static 1215 + void cmd_write_error (e8272_t *fdc, unsigned err) 1216 + { 1217 + #if E8272_DEBUG >= 1 1218 + fprintf (stderr, 1219 + "E8272: CMD=%02X D=%u WRITE ERROR" 1220 + " (pc=%u, ph=%u c=%u, h=%u, s=%u, n=%u eot=%u)\n", 1221 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1222 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5], fdc->cmd[6] 1223 + ); 1224 + #endif 1225 + 1226 + fdc->st[0] = (fdc->st[0] & 0x3f) | 0x40; 1227 + 1228 + if (err & E8272_ERR_WPROT) { 1229 + fdc->st[1] |= E8272_ST1_NW; 1230 + } 1231 + 1232 + if (err & E8272_ERR_NO_ID) { 1233 + fdc->st[1] |= E8272_ST1_MA; 1234 + } 1235 + 1236 + cmd_write_tc (fdc); 1237 + } 1238 + 1239 + static 1240 + void cmd_write_set_data (e8272_t *fdc, unsigned char val) 1241 + { 1242 + unsigned err, cnt; 1243 + 1244 + fdc->buf[fdc->buf_i++] = val; 1245 + 1246 + if (fdc->buf_i < fdc->buf_n) { 1247 + return; 1248 + } 1249 + 1250 + if (fdc->dma) { 1251 + e8272_set_dreq (fdc, 0); 1252 + } 1253 + 1254 + cnt = fdc->buf_n; 1255 + 1256 + err = e8272_block_write (fdc, fdc->buf, &cnt, 1257 + fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1258 + fdc->write_id, fdc->cmd[4] 1259 + ); 1260 + 1261 + if (err) { 1262 + cmd_write_error (fdc, err); 1263 + } 1264 + else { 1265 + e8272_next_id (fdc); 1266 + 1267 + fdc->set_data = NULL; 1268 + fdc->set_clock = cmd_write_clock; 1269 + } 1270 + } 1271 + 1272 + static 1273 + void cmd_write_clock (e8272_t *fdc, unsigned long cnt) 1274 + { 1275 + unsigned id; 1276 + unsigned c, h, s, n; 1277 + e8272_sct_t *sct; 1278 + 1279 + if (fdc->index_cnt >= 2) { 1280 + cmd_write_error (fdc, E8272_ERR_NO_ID); 1281 + return; 1282 + } 1283 + 1284 + if (fdc->delay_clock > 0) { 1285 + return; 1286 + } 1287 + 1288 + id = e8272_get_current_id (fdc); 1289 + 1290 + e8272_delay_next_id (fdc, 0); 1291 + 1292 + if ((fdc->cmd[0] & E8272_CMD0_MFM) == 0) { 1293 + return; 1294 + } 1295 + 1296 + c = fdc->cmd[2]; 1297 + h = fdc->cmd[3]; 1298 + s = fdc->cmd[4]; 1299 + n = fdc->cmd[5]; 1300 + 1301 + if (id >= fdc->curdrv->sct_cnt) { 1302 + return; 1303 + } 1304 + 1305 + sct = &fdc->curdrv->sct[id]; 1306 + 1307 + if ((sct->c != c) || (sct->h != h) || (sct->s != s)) { 1308 + return; 1309 + } 1310 + 1311 + fdc->index_cnt = 0; 1312 + 1313 + if (n > 6) { 1314 + cmd_write_error (fdc, E8272_ERR_OTHER); 1315 + return; 1316 + } 1317 + 1318 + fdc->buf_i = 0; 1319 + 1320 + if (n == 0) { 1321 + fdc->buf_n = fdc->cmd[8]; 1322 + } 1323 + else { 1324 + fdc->buf_n = 128 << n; 1325 + } 1326 + 1327 + fdc->write_id = id; 1328 + 1329 + fdc->set_data = cmd_write_set_data; 1330 + fdc->set_clock = NULL; 1331 + 1332 + e8272_request_data (fdc, 0); 1333 + } 1334 + 1335 + static 1336 + void cmd_write (e8272_t *fdc) 1337 + { 1338 + e8272_select_head (fdc, fdc->cmd[1] & 3, (fdc->cmd[1] >> 2) & 1); 1339 + e8272_read_track (fdc); 1340 + 1341 + #if E8272_DEBUG >= 1 1342 + fprintf (stderr, 1343 + "E8272: CMD=%02X D=%u WRITE" 1344 + " (pc=%u, ph=%u c=%u, h=%u, s=%u, n=%u)\n", 1345 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1346 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5] 1347 + ); 1348 + #endif 1349 + 1350 + fdc->st[0] = 0; 1351 + fdc->st[1] = 0; 1352 + fdc->st[2] = 0; 1353 + 1354 + fdc->index_cnt = 0; 1355 + 1356 + e8272_delay_next_id (fdc, 0); 1357 + 1358 + fdc->set_tc = cmd_write_tc; 1359 + fdc->set_clock = cmd_write_clock; 1360 + } 1361 + 1362 + 1363 + /***************************************************************************** 1364 + * format 1365 + *****************************************************************************/ 1366 + 1367 + static void cmd_format_clock (e8272_t *fdc, unsigned long cnt); 1368 + 1369 + static 1370 + void cmd_format_tc (e8272_t *fdc) 1371 + { 1372 + #if E8272_DEBUG >= 2 1373 + fprintf (stderr, "E8272: CMD=%02X D=%u FORMAT TC\n", 1374 + fdc->cmd[0], fdc->cmd[1] & 3 1375 + ); 1376 + #endif 1377 + 1378 + fdc->st[0] = (fdc->st[0] & ~0x07) | (fdc->cmd[1] & 0x07); 1379 + 1380 + fdc->res[0] = fdc->st[0]; 1381 + fdc->res[1] = fdc->st[1]; 1382 + fdc->res[2] = fdc->st[2]; 1383 + fdc->res[3] = fdc->curdrv->c; 1384 + fdc->res[4] = (fdc->cmd[1] >> 2) & 0x01; 1385 + fdc->res[5] = fdc->cmd[3] + 1; 1386 + fdc->res[6] = fdc->cmd[2]; 1387 + 1388 + cmd_result (fdc, 7); 1389 + 1390 + e8272_set_irq (fdc, 1); 1391 + } 1392 + 1393 + static 1394 + void cmd_format_error (e8272_t *fdc, unsigned err) 1395 + { 1396 + #if E8272_DEBUG >= 1 1397 + fprintf (stderr, "E8272: format error\n"); 1398 + #endif 1399 + 1400 + fdc->st[0] = 0x40; 1401 + 1402 + if (err & E8272_ERR_WPROT) { 1403 + fdc->st[1] |= E8272_ST1_NW; 1404 + } 1405 + 1406 + cmd_format_tc (fdc); 1407 + } 1408 + 1409 + static 1410 + void cmd_format_set_data (e8272_t *fdc, unsigned char val) 1411 + { 1412 + unsigned d, c, h, n; 1413 + unsigned lc, lh, ls, ln; 1414 + unsigned gpl, fill; 1415 + 1416 + fdc->buf[fdc->buf_i++] = val; 1417 + 1418 + if (fdc->buf_i < 4) { 1419 + return; 1420 + } 1421 + 1422 + if (fdc->dma) { 1423 + e8272_set_dreq (fdc, 0); 1424 + } 1425 + 1426 + d = fdc->curdrv->d; 1427 + c = fdc->curdrv->c; 1428 + h = fdc->curdrv->h; 1429 + n = fdc->cmd[2]; 1430 + gpl = fdc->cmd[4]; 1431 + fill = fdc->cmd[5]; 1432 + 1433 + lc = fdc->buf[0]; 1434 + lh = fdc->buf[1]; 1435 + ls = fdc->buf[2]; 1436 + ln = fdc->buf[3]; 1437 + 1438 + #if E8272_DEBUG >= 1 1439 + fprintf (stderr, 1440 + "E8272: CMD=%02X D=%u FORMAT SECTOR " 1441 + "(c=%u, h=%u, n=%u, g=%u, f=0x%02x, id=[%02x %02x %02x %02x])\n", 1442 + fdc->cmd[0], d, c, h, n, gpl, fill, lc, lh, ls, ln 1443 + ); 1444 + #endif 1445 + 1446 + fdc->curdrv->ok = 0; 1447 + 1448 + if (e8272_block_format (fdc, d, c, h, fdc->format_cnt, lc, lh, ls, ln, fill)) { 1449 + cmd_format_error (fdc, E8272_ERR_WPROT); 1450 + return; 1451 + } 1452 + 1453 + fdc->res[3] = lc; 1454 + fdc->res[4] = lh; 1455 + fdc->res[5] = ls + 1; 1456 + fdc->res[6] = ln; 1457 + 1458 + fdc->format_cnt += 1; 1459 + 1460 + if (fdc->format_cnt >= fdc->cmd[3]) { 1461 + e8272_delay_index (fdc, 0); 1462 + } 1463 + else { 1464 + e8272_delay_bits (fdc, 8UL * (62 + (128 << ln) + gpl), 0); 1465 + } 1466 + 1467 + fdc->set_data = NULL; 1468 + fdc->set_clock = cmd_format_clock; 1469 + } 1470 + 1471 + static 1472 + void cmd_format_clock (e8272_t *fdc, unsigned long cnt) 1473 + { 1474 + if (fdc->delay_clock > 0) { 1475 + return; 1476 + } 1477 + 1478 + if (fdc->format_cnt >= fdc->cmd[3]) { 1479 + cmd_format_tc (fdc); 1480 + return; 1481 + } 1482 + 1483 + fdc->buf_i = 0; 1484 + fdc->buf_n = 4; 1485 + 1486 + fdc->set_data = cmd_format_set_data; 1487 + fdc->set_clock = NULL; 1488 + 1489 + e8272_request_data (fdc, 0); 1490 + } 1491 + 1492 + static 1493 + void cmd_format (e8272_t *fdc) 1494 + { 1495 + e8272_select_head (fdc, fdc->cmd[1] & 3, (fdc->cmd[1] >> 2) & 1); 1496 + 1497 + #if E8272_DEBUG >= 1 1498 + fprintf (stderr, 1499 + "E8272: CMD=%02X D=%u FORMAT (pc=%u, ph=%u, n=%u sc=%u gpl=%u d=%02x)\n", 1500 + fdc->cmd[0], fdc->curdrv->d, fdc->curdrv->c, fdc->curdrv->h, 1501 + fdc->cmd[2], fdc->cmd[3], fdc->cmd[4], fdc->cmd[5] 1502 + ); 1503 + #endif 1504 + 1505 + fdc->st[0] = 0; 1506 + fdc->st[1] = 0; 1507 + fdc->st[2] = 0; 1508 + 1509 + if ((fdc->cmd[0] & E8272_CMD0_MFM) == 0) { 1510 + cmd_format_error (fdc, 0); 1511 + return; 1512 + } 1513 + 1514 + fdc->format_cnt = 0; 1515 + 1516 + e8272_delay_index (fdc, 0); 1517 + 1518 + fdc->set_tc = cmd_format_tc; 1519 + fdc->set_clock = cmd_format_clock; 1520 + } 1521 + 1522 + 1523 + /***************************************************************************** 1524 + * recalibrate 1525 + *****************************************************************************/ 1526 + 1527 + static 1528 + void cmd_recalibrate_clock (e8272_t *fdc, unsigned long cnt) 1529 + { 1530 + unsigned drv; 1531 + 1532 + if (fdc->delay_clock > 0) { 1533 + return; 1534 + } 1535 + 1536 + drv = fdc->cmd[1] & 0x03; 1537 + 1538 + fdc->msr &= ~(0x01 << drv); 1539 + 1540 + fdc->st[0] = (fdc->cmd[1] & 0x07) | E8272_ST0_SE; 1541 + 1542 + e8272_set_irq (fdc, 1); 1543 + 1544 + cmd_done (fdc); 1545 + } 1546 + 1547 + static 1548 + void cmd_recalibrate (e8272_t *fdc) 1549 + { 1550 + unsigned pd, steps; 1551 + 1552 + pd = fdc->cmd[1] & 0x03; 1553 + 1554 + #if E8272_DEBUG >= 1 1555 + fprintf (stderr, "E8272: CMD=%02X D=%u RECALIBRATE\n", 1556 + fdc->cmd[0], pd 1557 + ); 1558 + #endif 1559 + 1560 + steps = fdc->drv[pd].c; 1561 + 1562 + e8272_select_cylinder (fdc, pd, 0); 1563 + 1564 + fdc->msr |= 0x01 << pd; 1565 + 1566 + if (fdc->accurate) { 1567 + fdc->delay_clock = steps * ((fdc->step_rate * fdc->input_clock) / 1000); 1568 + } 1569 + else { 1570 + fdc->delay_clock = 0; 1571 + } 1572 + 1573 + fdc->set_clock = cmd_recalibrate_clock; 1574 + } 1575 + 1576 + 1577 + /***************************************************************************** 1578 + * seek 1579 + *****************************************************************************/ 1580 + static 1581 + void cmd_seek_clock (e8272_t *fdc, unsigned long cnt) 1582 + { 1583 + unsigned drv; 1584 + 1585 + if (fdc->delay_clock > 0) { 1586 + return; 1587 + } 1588 + 1589 + drv = fdc->cmd[1] & 0x03; 1590 + 1591 + fdc->msr &= ~(0x01 << drv); 1592 + 1593 + fdc->st[0] = (fdc->cmd[1] & 0x07) | E8272_ST0_SE; 1594 + 1595 + e8272_set_irq (fdc, 1); 1596 + 1597 + cmd_done (fdc); 1598 + } 1599 + 1600 + static 1601 + void cmd_seek (e8272_t *fdc) 1602 + { 1603 + unsigned pd, pc, steps; 1604 + 1605 + pd = fdc->cmd[1] & 3; 1606 + pc = fdc->cmd[2]; 1607 + 1608 + #if E8272_DEBUG >= 1 1609 + fprintf (stderr, "E8272: CMD=%02X D=%u SEEK (pc=%u)\n", 1610 + fdc->cmd[0], pd, pc 1611 + ); 1612 + #endif 1613 + 1614 + if (fdc->drv[pd].c < pc) { 1615 + steps = pc - fdc->drv[pd].c; 1616 + } 1617 + else { 1618 + steps = fdc->drv[pd].c - pc; 1619 + } 1620 + 1621 + e8272_select_cylinder (fdc, pd, pc); 1622 + 1623 + fdc->msr |= 0x01 << pd; 1624 + 1625 + if (fdc->accurate) { 1626 + fdc->delay_clock = steps * ((fdc->step_rate * fdc->input_clock) / 1000); 1627 + } 1628 + else { 1629 + fdc->delay_clock = 0; 1630 + } 1631 + 1632 + fdc->set_clock = cmd_seek_clock; 1633 + } 1634 + 1635 + 1636 + /***************************************************************************** 1637 + * sense interrupt status 1638 + *****************************************************************************/ 1639 + 1640 + static 1641 + void cmd_sense_int_status_clock (e8272_t *fdc, unsigned long cnt) 1642 + { 1643 + if (fdc->delay_clock > 0) { 1644 + return; 1645 + } 1646 + 1647 + fdc->res[0] = fdc->st[0]; 1648 + fdc->res[1] = fdc->curdrv->c; 1649 + 1650 + /* reset interrupt condition */ 1651 + fdc->st[0] &= 0x3f; 1652 + 1653 + fdc->st[0] &= ~(E8272_ST0_SE); 1654 + 1655 + e8272_set_irq (fdc, 0); 1656 + 1657 + cmd_result (fdc, 2); 1658 + } 1659 + 1660 + static 1661 + void cmd_sense_int_status (e8272_t *fdc) 1662 + { 1663 + #if E8272_DEBUG >= 1 1664 + fprintf (stderr, "E8272: CMD=%02X D=* SENSE INTERRUPT STATUS\n", 1665 + fdc->cmd[0] 1666 + ); 1667 + #endif 1668 + 1669 + fdc->delay_clock = fdc->accurate ? (fdc->input_clock / 10000) : 0; 1670 + 1671 + fdc->set_clock = cmd_sense_int_status_clock; 1672 + } 1673 + 1674 + 1675 + /***************************************************************************** 1676 + * sense drive status 1677 + *****************************************************************************/ 1678 + 1679 + static 1680 + void cmd_sense_drive_status_clock (e8272_t *fdc, unsigned long cnt) 1681 + { 1682 + unsigned d; 1683 + 1684 + if (fdc->delay_clock > 0) { 1685 + return; 1686 + } 1687 + 1688 + d = fdc->cmd[1] & 0x03; 1689 + 1690 + fdc->st[3] &= ~E8272_ST3_T0; 1691 + fdc->st[3] |= E8272_ST3_RDY | E8272_ST3_TS; 1692 + 1693 + if (fdc->drv[d].c == 0) { 1694 + fdc->st[3] |= E8272_ST3_T0; 1695 + } 1696 + 1697 + fdc->res[0] = fdc->st[3]; 1698 + 1699 + cmd_result (fdc, 1); 1700 + } 1701 + 1702 + static 1703 + void cmd_sense_drive_status (e8272_t *fdc) 1704 + { 1705 + #if E8272_DEBUG >= 1 1706 + fprintf (stderr, "E8272: CMD=%02X D=%u SENSE DRIVE STATUS\n", 1707 + fdc->cmd[0], fdc->cmd[1] & 3 1708 + ); 1709 + #endif 1710 + 1711 + fdc->delay_clock = fdc->accurate ? (fdc->input_clock / 10000) : 0; 1712 + 1713 + fdc->set_clock = cmd_sense_drive_status_clock; 1714 + } 1715 + 1716 + 1717 + /***************************************************************************** 1718 + * specify 1719 + *****************************************************************************/ 1720 + 1721 + static 1722 + void cmd_specify (e8272_t *fdc) 1723 + { 1724 + unsigned char srt, hut, hlt, nd; 1725 + 1726 + srt = 16 - ((fdc->cmd[1] >> 4) & 0x0f); 1727 + hut = 16 * (fdc->cmd[1] & 0x0f); 1728 + hlt = 2 * ((fdc->cmd[2] >> 1) & 0x7f); 1729 + nd = (fdc->cmd[2] & 0x01); 1730 + 1731 + #if E8272_DEBUG >= 1 1732 + fprintf (stderr, 1733 + "E8272: CMD=%02X D=* SPECIFY (srt=%ums, hut=%ums, hlt=%ums, dma=%d)\n", 1734 + fdc->cmd[0], srt, hut, hlt, nd == 0 1735 + ); 1736 + #endif 1737 + 1738 + fdc->dma = (nd == 0); 1739 + fdc->step_rate = srt; 1740 + 1741 + cmd_done (fdc); 1742 + } 1743 + 1744 + 1745 + /***************************************************************************** 1746 + * invalid 1747 + *****************************************************************************/ 1748 + 1749 + static 1750 + void cmd_invalid (e8272_t *fdc) 1751 + { 1752 + #if E8272_DEBUG >= 0 1753 + fprintf (stderr, "E8272: CMD=%02X D=? INVALID\n", fdc->cmd[0]); 1754 + #endif 1755 + 1756 + fdc->res[0] = 0x80; 1757 + 1758 + cmd_result (fdc, 1); 1759 + } 1760 + 1761 + 1762 + static struct { 1763 + unsigned char mask; 1764 + unsigned char val; 1765 + unsigned cnt; 1766 + void (*start_cmd) (e8272_t *fdc); 1767 + } cmd_tab[] = { 1768 + { 0x1f, 0x06, 9, cmd_read }, 1769 + { 0x1f, 0x02, 9, cmd_read_track }, 1770 + { 0xbf, 0x0a, 2, cmd_read_id }, 1771 + { 0x3f, 0x05, 9, cmd_write }, 1772 + { 0xbf, 0x0d, 6, cmd_format }, 1773 + { 0xff, 0x07, 2, cmd_recalibrate }, 1774 + { 0xff, 0x0f, 3, cmd_seek }, 1775 + { 0xff, 0x08, 1, cmd_sense_int_status }, 1776 + { 0xff, 0x04, 2, cmd_sense_drive_status }, 1777 + { 0xff, 0x03, 3, cmd_specify }, 1778 + { 0x00, 0x00, 1, cmd_invalid } 1779 + }; 1780 + 1781 + 1782 + /* 1783 + * Write the first command byte. 1784 + */ 1785 + static 1786 + void e8272_write_cmd (e8272_t *fdc, unsigned char val) 1787 + { 1788 + unsigned i, n; 1789 + 1790 + n = sizeof (cmd_tab) / sizeof (cmd_tab[0]); 1791 + 1792 + fdc->get_data = NULL; 1793 + fdc->set_data = NULL; 1794 + fdc->set_tc = NULL; 1795 + fdc->set_clock = NULL; 1796 + fdc->start_cmd = NULL; 1797 + 1798 + for (i = 0; i < n; i++) { 1799 + if ((val & cmd_tab[i].mask) == cmd_tab[i].val) { 1800 + fdc->cmd_i = 0; 1801 + fdc->cmd_n = cmd_tab[i].cnt; 1802 + fdc->set_data = cmd_set_command; 1803 + fdc->start_cmd = cmd_tab[i].start_cmd; 1804 + 1805 + fdc->set_data (fdc, val); 1806 + 1807 + return; 1808 + } 1809 + } 1810 + } 1811 + 1812 + 1813 + void e8272_reset (e8272_t *fdc) 1814 + { 1815 + #if E8272_DEBUG >= 1 1816 + fprintf (stderr, "E8272: reset\n"); 1817 + #endif 1818 + 1819 + fdc->msr = E8272_MSR_RQM; 1820 + 1821 + fdc->st[0] = 0xc0; 1822 + fdc->st[1] = 0x00; 1823 + fdc->st[2] = 0x00; 1824 + fdc->st[3] = 0x00; 1825 + 1826 + fdc->cmd_i = 0; 1827 + fdc->cmd_n = 0; 1828 + 1829 + fdc->res_i = 0; 1830 + fdc->res_n = 0; 1831 + 1832 + fdc->buf_i = 0; 1833 + fdc->buf_n = 0; 1834 + 1835 + fdc->delay_clock = 0; 1836 + 1837 + fdc->set_data = e8272_write_cmd; 1838 + fdc->get_data = NULL; 1839 + fdc->set_tc = NULL; 1840 + fdc->set_clock = NULL; 1841 + 1842 + e8272_set_irq (fdc, 0); 1843 + e8272_set_dreq (fdc, 0); 1844 + } 1845 + 1846 + static 1847 + void e8272_write_dor (e8272_t *fdc, unsigned char val) 1848 + { 1849 + if (((fdc->dor) ^ val) & E8272_DOR_RESET) { 1850 + if (val & E8272_DOR_RESET) { 1851 + e8272_set_irq (fdc, 1); 1852 + } 1853 + else { 1854 + e8272_reset (fdc); 1855 + } 1856 + } 1857 + 1858 + fdc->dor = val; 1859 + } 1860 + 1861 + void e8272_write_data (e8272_t *fdc, unsigned char val) 1862 + { 1863 + e8272_set_irq (fdc, 0); 1864 + 1865 + if ((fdc->msr & E8272_MSR_RQM) == 0) { 1866 + if (fdc->dreq_val == 0) { 1867 + return; 1868 + } 1869 + } 1870 + 1871 + if (fdc->msr & E8272_MSR_DIO) { 1872 + return; 1873 + } 1874 + 1875 + if (fdc->set_data != NULL) { 1876 + fdc->set_data (fdc, val); 1877 + } 1878 + } 1879 + 1880 + static 1881 + unsigned char e8272_read_dor (e8272_t *fdc) 1882 + { 1883 + return (fdc->dor); 1884 + } 1885 + 1886 + static 1887 + unsigned char e8272_read_msr (e8272_t *fdc) 1888 + { 1889 + return (fdc->msr); 1890 + } 1891 + 1892 + unsigned char e8272_read_data (e8272_t *fdc) 1893 + { 1894 + unsigned char val; 1895 + 1896 + e8272_set_irq (fdc, 0); 1897 + 1898 + val = 0; 1899 + 1900 + if (fdc->get_data != NULL) { 1901 + val = fdc->get_data (fdc); 1902 + } 1903 + 1904 + #if E8272_DEBUG >= 3 1905 + fprintf (stderr, "E8272: read data: %02X\n", val); 1906 + #endif 1907 + 1908 + return (val); 1909 + 1910 + return (0); 1911 + } 1912 + 1913 + unsigned char e8272_get_uint8 (e8272_t *fdc, unsigned long addr) 1914 + { 1915 + unsigned char ret; 1916 + 1917 + switch (addr) { 1918 + case 0x02: 1919 + ret = e8272_read_dor (fdc); 1920 + break; 1921 + 1922 + case 0x04: 1923 + ret = e8272_read_msr (fdc); 1924 + break; 1925 + 1926 + case 0x05: 1927 + ret = e8272_read_data (fdc); 1928 + break; 1929 + 1930 + default: 1931 + ret = 0xff; 1932 + #if E8272_DEBUG >= 1 1933 + fprintf (stderr, "E8272: get %04lx -> %02x\n", addr, ret); 1934 + #endif 1935 + break; 1936 + } 1937 + 1938 + #if E8272_DEBUG >= 3 1939 + fprintf (stderr, "E8272: get %04lx -> %02x\n", addr, ret); 1940 + #endif 1941 + 1942 + return (ret); 1943 + } 1944 + 1945 + void e8272_set_uint8 (e8272_t *fdc, unsigned long addr, unsigned char val) 1946 + { 1947 + #if E8272_DEBUG >= 3 1948 + fprintf (stderr, "E8272: set %04lx <- %02x\n", addr, val); 1949 + #endif 1950 + 1951 + switch (addr) { 1952 + case 0x02: 1953 + e8272_write_dor (fdc, val); 1954 + break; 1955 + 1956 + case 0x05: 1957 + e8272_write_data (fdc, val); 1958 + break; 1959 + 1960 + default: 1961 + #if E8272_DEBUG >= 1 1962 + fprintf (stderr, "E8272: set %04lx <- %02x\n", addr, val); 1963 + #endif 1964 + break; 1965 + } 1966 + } 1967 + 1968 + void e8272_set_tc (e8272_t *fdc, unsigned char val) 1969 + { 1970 + if (val == 0) { 1971 + return; 1972 + } 1973 + 1974 + #if E8272_DEBUG >= 2 1975 + fprintf (stderr, "E8272: TC\n"); 1976 + #endif 1977 + 1978 + if (fdc->set_tc != NULL) { 1979 + fdc->set_tc (fdc); 1980 + } 1981 + } 1982 + 1983 + void e8272_clock (e8272_t *fdc, unsigned long n) 1984 + { 1985 + fdc->track_clk += E8272_RATE * n; 1986 + 1987 + fdc->track_pos += fdc->track_clk / fdc->input_clock; 1988 + fdc->track_clk %= fdc->input_clock; 1989 + 1990 + if (fdc->track_pos >= fdc->track_size) { 1991 + fdc->track_pos -= fdc->track_size; 1992 + fdc->index_cnt += 1; 1993 + } 1994 + 1995 + if (n < fdc->delay_clock) { 1996 + fdc->delay_clock -= n; 1997 + } 1998 + else { 1999 + fdc->delay_clock = 0; 2000 + } 2001 + 2002 + if (fdc->set_clock != NULL) { 2003 + fdc->set_clock (fdc, n); 2004 + } 2005 + }
+186
src/chipset/82xx/e8272.h
··· 1 + /***************************************************************************** 2 + * pce * 3 + *****************************************************************************/ 4 + 5 + /***************************************************************************** 6 + * File name: src/chipset/82xx/e8272.h * 7 + * Created: 2005-03-06 by Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2005-2010 Hampa Hug <hampa@hampa.ch> * 9 + *****************************************************************************/ 10 + 11 + /***************************************************************************** 12 + * This program is free software. You can redistribute it and / or modify it * 13 + * under the terms of the GNU General Public License version 2 as published * 14 + * by the Free Software Foundation. * 15 + * * 16 + * This program is distributed in the hope that it will be useful, but * 17 + * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 + * Public License for more details. * 20 + *****************************************************************************/ 21 + 22 + 23 + #ifndef PCE_E8272_H 24 + #define PCE_E8272_H 1 25 + 26 + 27 + #define E8272_ERR_OK 0x00 28 + #define E8272_ERR_OTHER 0x01 29 + #define E8272_ERR_NO_ID 0x02 30 + #define E8272_ERR_NO_DATA 0x04 31 + #define E8272_ERR_CRC_ID 0x08 32 + #define E8272_ERR_CRC_DATA 0x10 33 + #define E8272_ERR_DATALEN 0x20 34 + #define E8272_ERR_WPROT 0x40 35 + 36 + #define E8272_MAX_SCT 128 37 + 38 + 39 + typedef struct { 40 + unsigned char c; 41 + unsigned char h; 42 + unsigned char s; 43 + unsigned short n; 44 + unsigned short ofs; 45 + } e8272_sct_t; 46 + 47 + 48 + typedef struct { 49 + unsigned d; 50 + unsigned c; 51 + unsigned h; 52 + 53 + char ok; 54 + unsigned sct_cnt; 55 + e8272_sct_t sct[E8272_MAX_SCT]; 56 + } e8272_drive_t; 57 + 58 + 59 + typedef struct e8272_t { 60 + unsigned char dor; 61 + unsigned char msr; 62 + 63 + unsigned char st[4]; 64 + 65 + e8272_drive_t drv[4]; 66 + e8272_drive_t *curdrv; 67 + 68 + unsigned cmd_i; 69 + unsigned cmd_n; 70 + unsigned char cmd[16]; 71 + 72 + unsigned res_i; 73 + unsigned res_n; 74 + unsigned char res[16]; 75 + 76 + unsigned buf_i; 77 + unsigned buf_n; 78 + unsigned char buf[8192]; 79 + 80 + char dma; 81 + 82 + unsigned short step_rate; 83 + 84 + char accurate; 85 + 86 + unsigned long delay_clock; 87 + 88 + unsigned long input_clock; 89 + 90 + unsigned long track_pos; 91 + unsigned long track_clk; 92 + unsigned long track_size; 93 + 94 + unsigned short index_cnt; 95 + 96 + char read_error; 97 + unsigned short read_track_cnt; 98 + unsigned short write_id; 99 + unsigned short format_cnt; 100 + 101 + void (*set_data) (struct e8272_t *fdc, unsigned char val); 102 + unsigned char (*get_data) (struct e8272_t *fdc); 103 + void (*set_tc) (struct e8272_t *fdc); 104 + void (*set_clock) (struct e8272_t *fdc, unsigned long cnt); 105 + void (*start_cmd) (struct e8272_t *fdc); 106 + 107 + void *blk_rd_ext; 108 + unsigned (*blk_rd) (void *ext, void *buf, unsigned *cnt, unsigned d, 109 + unsigned pc, unsigned ph, unsigned ps, unsigned s 110 + ); 111 + 112 + void *blk_wr_ext; 113 + unsigned (*blk_wr) (void *ext, const void *buf, unsigned *cnt, unsigned d, 114 + unsigned pc, unsigned ph, unsigned ps, unsigned s 115 + ); 116 + 117 + void *blk_fmt_ext; 118 + int (*blk_fmt) (void *ext, unsigned d, 119 + unsigned pc, unsigned ph, unsigned ps, 120 + unsigned lc, unsigned lh, unsigned ls, unsigned ln, 121 + unsigned fill 122 + ); 123 + 124 + void *blk_rdid_ext; 125 + int (*blk_rdid) (void *ext, unsigned d, 126 + unsigned pc, unsigned ph, unsigned ps, 127 + unsigned *lc, unsigned *lh, unsigned *ls, unsigned *ln 128 + ); 129 + 130 + /* the interrupt function */ 131 + void *irq_ext; 132 + unsigned char irq_val; 133 + void (*irq) (void *ext, unsigned char val); 134 + 135 + void *dreq_ext; 136 + unsigned char dreq_val; 137 + void (*dreq) (void *ext, unsigned char val); 138 + } e8272_t; 139 + 140 + 141 + void e8272_init (e8272_t *fdc); 142 + 143 + e8272_t *e8272_new (void); 144 + 145 + void e8272_free (e8272_t *fdc); 146 + 147 + void e8272_del (e8272_t *fdc); 148 + 149 + 150 + void e8272_set_irq_fct (e8272_t *fdc, void *ext, void *fct); 151 + 152 + void e8272_set_dreq_fct (e8272_t *fdc, void *ext, void *fct); 153 + 154 + 155 + void e8272_set_block_read_fct (e8272_t *fdc, void *ext, void *fct); 156 + 157 + void e8272_set_block_write_fct (e8272_t *fdc, void *ext, void *fct); 158 + 159 + void e8272_set_block_fmt_fct (e8272_t *fdc, void *ext, void *fct); 160 + 161 + void e8272_set_block_rdid_fct (e8272_t *fdc, void *ext, void *fct); 162 + 163 + 164 + void e8272_set_input_clock (e8272_t *fdc, unsigned long clk); 165 + 166 + void e8272_set_accuracy (e8272_t *fdc, int accurate); 167 + 168 + 169 + void e8272_write_data (e8272_t *fdc, unsigned char val); 170 + 171 + unsigned char e8272_read_data (e8272_t *fdc); 172 + 173 + 174 + unsigned char e8272_get_uint8 (e8272_t *fdc, unsigned long addr); 175 + 176 + void e8272_set_uint8 (e8272_t *fdc, unsigned long addr, unsigned char val); 177 + 178 + 179 + void e8272_reset (e8272_t *fdc); 180 + 181 + void e8272_set_tc (e8272_t *fdc, unsigned char val); 182 + 183 + void e8272_clock (e8272_t *fdc, unsigned long n); 184 + 185 + 186 + #endif