Revision caed8802 hw/fdc.c

b/hw/fdc.c
85 85
    uint8_t ro;               /* Is read-only           */
86 86
} fdrive_t;
87 87

  
88
static void fd_init (fdrive_t *drv)
88
static void fd_init (fdrive_t *drv, BlockDriverState *bs)
89 89
{
90 90
    /* Drive */
91
    drv->bs = NULL;
92
//    drv->drive = FDRIVE_DRV_288;
93
    drv->drive = FDRIVE_DRV_144;
91
    drv->bs = bs;
92
    if (bs)
93
        drv->drive = FDRIVE_DRV_144;
94
    else
95
        drv->drive = FDRIVE_DRV_NONE;
94 96
    drv->motor = 0;
95 97
    drv->perpendicular = 0;
96 98
    drv->rv = 0;
......
157 159
}
158 160

  
159 161
/* Revalidate a disk drive after a disk change */
160
static void fd_revalidate (fdrive_t *drv, int ro)
162
static void fd_revalidate (fdrive_t *drv)
161 163
{
162 164
    int64_t nb_sectors;
163 165

  
164 166
    FLOPPY_DPRINTF("revalidate\n");
165 167
    drv->rv = 0;
166
    if (drv->bs != NULL) {
168
    /* if no drive present, cannot do more */
169
    if (!drv->bs)
170
        return;
171
        
172
    if (bdrv_is_inserted(drv->bs)) {
167 173
        bdrv_get_geometry(drv->bs, &nb_sectors);
168 174
#if 1
169 175
        if (nb_sectors > 2880) 
......
186 192
            drv->max_track = 80;
187 193
#endif
188 194
        }
195
        drv->ro = bdrv_is_read_only(drv->bs);
189 196
    } else {
190 197
        drv->disk = FDRIVE_DISK_NONE;
191 198
        drv->last_sect = 1; /* Avoid eventual divide by 0 bugs */
199
        drv->ro = 0;
192 200
    }
193
    drv->ro = ro;
194 201
    drv->rv = 1;
195 202
}
196 203

  
204
static void fd_change_cb (void *opaque)
205
{
206
    fdrive_t *drv = opaque;
207
    fd_revalidate(drv);
208
}
209

  
197 210
/* Motor control */
198 211
static void fd_start (fdrive_t *drv)
199 212
{
......
220 233
static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size);
221 234
static void fdctrl_raise_irq (uint8_t status);
222 235

  
223
static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg);
224
static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg);
225
static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value);
226
static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg);
227
static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value);
228
static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg);
229
static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value);
230
static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg);
231
static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value);
232
static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg);
236
static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg);
237
static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg);
238
static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value);
239
static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg);
240
static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value);
241
static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg);
242
static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value);
243
static uint32_t fdctrl_read_data (void *opaque, uint32_t reg);
244
static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value);
245
static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg);
233 246

  
234 247
enum {
235 248
    FD_CTRL_ACTIVE = 0x01,
......
295 308
static fdctrl_t fdctrl;
296 309

  
297 310
void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base,
298
                  char boot_device)
311
                  BlockDriverState **fds)
299 312
{
300 313
//    int io_mem;
301 314
    int i;
......
312 325
    } else {
313 326
        fdctrl.dma_en = 0;
314 327
    }
315
    for (i = 0; i < MAX_FD; i++)
316
        fd_init(&fdctrl.drives[i]);
328
    for (i = 0; i < MAX_FD; i++) {
329
        fd_init(&fdctrl.drives[i], fds[i]);
330
        if (fds[i])
331
            bdrv_set_change_cb(fds[i], fd_change_cb, &fdctrl.drives[i]);
332
    }
317 333
    fdctrl_reset(0);
318 334
    fdctrl.state = FD_CTRL_ACTIVE;
319 335
    if (mem_mapped) {
......
323 339
        cpu_register_physical_memory(base, 0x08, io_mem);
324 340
#endif
325 341
    } else {
326
        register_ioport_read(base + 0x01, 1, fdctrl_read_statusB, 1);
327
        register_ioport_read(base + 0x02, 1, fdctrl_read_dor, 1);
328
        register_ioport_write(base + 0x02, 1, fdctrl_write_dor, 1);
329
        register_ioport_read(base + 0x03, 1, fdctrl_read_tape, 1);
330
        register_ioport_write(base + 0x03, 1, fdctrl_write_tape, 1);
331
        register_ioport_read(base + 0x04, 1, fdctrl_read_main_status, 1);
332
        register_ioport_write(base + 0x04, 1, fdctrl_write_rate, 1);
333
        register_ioport_read(base + 0x05, 1, fdctrl_read_data, 1);
334
        register_ioport_write(base + 0x05, 1, fdctrl_write_data, 1);
335
        register_ioport_read(base + 0x07, 1, fdctrl_read_dir, 1);
342
        register_ioport_read(base + 0x01, 1, 1, fdctrl_read_statusB, NULL);
343
        register_ioport_read(base + 0x02, 1, 1, fdctrl_read_dor, NULL);
344
        register_ioport_write(base + 0x02, 1, 1, fdctrl_write_dor, NULL);
345
        register_ioport_read(base + 0x03, 1, 1, fdctrl_read_tape, NULL);
346
        register_ioport_write(base + 0x03, 1, 1, fdctrl_write_tape, NULL);
347
        register_ioport_read(base + 0x04, 1, 1, fdctrl_read_main_status, NULL);
348
        register_ioport_write(base + 0x04, 1, 1, fdctrl_write_rate, NULL);
349
        register_ioport_read(base + 0x05, 1, 1, fdctrl_read_data, NULL);
350
        register_ioport_write(base + 0x05, 1, 1, fdctrl_write_data, NULL);
351
        register_ioport_read(base + 0x07, 1, 1, fdctrl_read_dir, NULL);
336 352
    }
337
    if (boot_device == 'b')
338
        fdctrl.bootsel = 1;
339
    else
340
        fdctrl.bootsel = 0;
341
#if defined (TARGET_I386)
342
    cmos_register_fd(fdctrl.drives[0].drive, fdctrl.drives[1].drive);
343
#endif
344
}
345

  
346
int fdctrl_disk_change (int idx, const unsigned char *filename, int ro)
347
{
348
    fdrive_t *drv;
353
    fdctrl.bootsel = 0;
349 354
    
350
    if (idx < 0 || idx > 1)
351
        return -1;
352
    FLOPPY_DPRINTF("disk %d change: %s (%s)\n", idx, filename,
353
                   ro == 0 ? "rw" : "ro");
354
    drv = &fdctrl.drives[idx];
355
    if (fd_table[idx] != NULL) {
356
        bdrv_close(fd_table[idx]);
357
        fd_table[idx] = NULL;
355
    for (i = 0; i < MAX_FD; i++) {
356
        fd_revalidate(&fdctrl.drives[i]);
358 357
    }
359
    fd_table[idx] = bdrv_open(filename, ro);
360
    drv->bs = fd_table[idx];
361
    if (fd_table[idx] == NULL)
362
        return -1;
363
    fd_revalidate(drv, ro);
364
#if 0
365
    fd_recalibrate(drv);
366
    fdctrl_reset_fifo();
367
    fdctrl_raise_irq(0x20);
368
#endif
358
}
369 359

  
370
    return 0;
360
int fdctrl_get_drive_type(int drive_num)
361
{
362
    return fdctrl.drives[drive_num].drive;
371 363
}
372 364

  
373 365
/* Change IRQ state */
......
411 403
}
412 404

  
413 405
/* Status B register : 0x01 (read-only) */
414
static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg)
406
static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg)
415 407
{
416 408
    fdctrl_reset_irq();
417 409
    FLOPPY_DPRINTF("status register: 0x00\n");
......
420 412
}
421 413

  
422 414
/* Digital output register : 0x02 */
423
static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg)
415
static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg)
424 416
{
425 417
    fdrive_t *cur_drv, *drv0, *drv1;
426 418
    uint32_t retval = 0;
......
442 434
    return retval;
443 435
}
444 436

  
445
static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value)
437
static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value)
446 438
{
447 439
    fdrive_t *drv0, *drv1;
448 440
    
......
489 481
}
490 482

  
491 483
/* Tape drive register : 0x03 */
492
static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg)
484
static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg)
493 485
{
494 486
    uint32_t retval = 0;
495 487

  
......
502 494
    return retval;
503 495
}
504 496

  
505
static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value)
497
static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value)
506 498
{
507 499
    fdctrl_reset_irq();
508 500
    /* Reset mode */
......
517 509
}
518 510

  
519 511
/* Main status register : 0x04 (read) */
520
static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg)
512
static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg)
521 513
{
522 514
    uint32_t retval = 0;
523 515

  
......
541 533
}
542 534

  
543 535
/* Data select rate register : 0x04 (write) */
544
static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value)
536
static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value)
545 537
{
546 538
    fdctrl_reset_irq();
547 539
    /* Reset mode */
......
566 558
}
567 559

  
568 560
/* Digital input register : 0x07 (read-only) */
569
static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg)
561
static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg)
570 562
{
571 563
    fdrive_t *drv0, *drv1;
572 564
    uint32_t retval = 0;
......
872 864
}
873 865

  
874 866
/* Data register : 0x05 */
875
static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg)
867
static uint32_t fdctrl_read_data (void *opaque, uint32_t reg)
876 868
{
877 869
    fdrive_t *cur_drv, *drv0, *drv1;
878 870
    uint32_t retval = 0;
......
914 906
    return retval;
915 907
}
916 908

  
917
static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value)
909
static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value)
918 910
{
919 911
    fdrive_t *cur_drv, *drv0, *drv1;
920 912

  

Also available in: Unified diff