--- previous/src/floppy.c 2018/04/24 19:29:59 1.1.1.1 +++ previous/src/floppy.c 2018/04/24 19:31:25 1.1.1.2 @@ -50,6 +50,8 @@ struct { FILE* dsk; Uint32 floppysize; + Uint32 seekoffset; + bool spinning; bool protected; @@ -207,7 +209,7 @@ void FLP_Select_Write(void) { void set_floppy_select(Uint8 sel, bool osp) { if (sel) { - Log_Printf(LOG_WARN,"[%s] Selecting floppy controller",osp?"OSP":"Floppy"); + Log_Printf(LOG_DEBUG,"[%s] Selecting floppy controller",osp?"OSP":"Floppy"); floppy_select = 1; } else { Log_Printf(LOG_FLP_REG_LEVEL,"[%s] Selecting SCSI controller",osp?"OSP":"Floppy"); @@ -276,9 +278,9 @@ void floppy_reset(bool hard) { flp.st[0]=flp.st[1]=flp.st[2]=flp.st[3]=0; flp.pcn=0; } else { - /* Single poll interrupt after reset (FIXME: delay should be 250 ms) */ + /* Single poll interrupt after reset (delay = 250 ms) */ flp_io_state = FLP_STATE_INTERRUPT; - CycInt_AddRelativeInterrupt(1000000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(250*1000, 0, INTERRUPT_FLP_IO); } } @@ -326,7 +328,7 @@ Uint8 cmd_data[8]; int result_size = 0; -void floppy_interrupt(void) { +static void floppy_interrupt(void) { Log_Printf(LOG_FLP_CMD_LEVEL,"[Floppy] Interrupt."); if (result_size>0) { @@ -351,7 +353,7 @@ void floppy_interrupt(void) { #define NUM_CYLINDERS 80 #define TRACKS_PER_CYL 2 -Uint32 physical_to_logical_sector(Uint8 c, Uint8 h, Uint8 s, int drive) { +static Uint32 physical_to_logical_sector(Uint8 c, Uint8 h, Uint8 s, int drive) { Uint32 disksize = flpdrv[drive].floppysize; Uint32 blocksize = 0x80<(NUM_CYLINDERS-1)) /* CHECK: does this cause an error? */ c=(NUM_CYLINDERS-1); flp.st[0] |= ST0_SE; + + flpdrv[drive].seekoffset = (flpdrv[drive].cyl < c) ? (c - flpdrv[drive].cyl) : (flpdrv[drive].cyl - c); flpdrv[drive].cyl = c; flpdrv[drive].head = h; } +/* Timings */ +#define FLP_SEEK_TIME 200000 /* 200 ms */ + +static int get_sector_time(int drive) { + switch (flpdrv[drive].floppysize) { + case SIZE_720K: return 22000; + case SIZE_1440K: return 11000; + case SIZE_2880K: return 5500; + default: return 1000; + } +} + +static int get_seek_time(int drive) { + if (flpdrv[drive].seekoffset > NUM_CYLINDERS) { + return FLP_SEEK_TIME; + } + + return (flpdrv[drive].seekoffset * FLP_SEEK_TIME / NUM_CYLINDERS); +} + /* Media IDs for control register */ #define MEDIA_ID_NONE 0 #define MEDIA_ID_720K 3 @@ -400,7 +424,7 @@ void floppy_seek_track(Uint8 c, Uint8 h, #define MEDIA_ID_2880K 1 #define MEDIA_ID_MSK 3 -Uint8 get_media_id(int drive) { +static Uint8 get_media_id(int drive) { if (!flpdrv[drive].inserted) { return MEDIA_ID_NONE; } else { @@ -418,7 +442,7 @@ Uint8 get_media_id(int drive) { #define CCR_RATE500 0x00 #define CCR_RATE1000 0x03 -void check_data_rate(int drive) { +static void check_data_rate(int drive) { switch (flpdrv[drive].floppysize) { case SIZE_720K: if ((flp.ccr&CCR_RATE_MASK)==CCR_RATE250) { @@ -444,7 +468,7 @@ void check_data_rate(int drive) { flp.st[1] |= ST1_ND; } -void send_rw_status(int drive) { +static void send_rw_status(int drive) { flp.st[0] |= drive|(flpdrv[drive].head<<2); flp.fifo[0] = flp.st[0]; flp.fifo[1] = flp.st[1]; @@ -458,7 +482,7 @@ void send_rw_status(int drive) { /* -- Floppy commands -- */ -void floppy_read(void) { +static void floppy_read(void) { int drive = cmd_data[0]&0x03; int head = (cmd_data[0]&0x04)>>2; Uint8 c = cmd_data[1]; @@ -509,10 +533,10 @@ void floppy_read(void) { flp_io_drv = drive; flp_io_state = FLP_STATE_READ; } - CycInt_AddRelativeInterrupt(1000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(get_seek_time(drive) + get_sector_time(drive), 100, INTERRUPT_FLP_IO); } -void floppy_write(void) { +static void floppy_write(void) { int drive = cmd_data[0]&0x03; int head = (cmd_data[0]&0x04)>>2; Uint8 c = cmd_data[1]; @@ -566,10 +590,10 @@ void floppy_write(void) { flp_io_drv = drive; flp_io_state = FLP_STATE_WRITE; } - CycInt_AddRelativeInterrupt(1000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(get_seek_time(drive) + get_sector_time(drive), 100, INTERRUPT_FLP_IO); } -void floppy_format(void) { +static void floppy_format(void) { int drive = cmd_data[0]&0x03; int head = (cmd_data[0]&0x04)>>2; @@ -591,11 +615,11 @@ void floppy_format(void) { flp_buffer.limit = 4; flp_io_drv = drive; flp_io_state = FLP_STATE_FORMAT; - CycInt_AddRelativeInterrupt(100000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(get_seek_time(drive) + get_sector_time(drive), 100, INTERRUPT_FLP_IO); } } -void floppy_read_id(void) { +static void floppy_read_id(void) { int drive = cmd_data[0]&0x03; int head = (cmd_data[0]&0x04)>>2; @@ -613,10 +637,10 @@ void floppy_read_id(void) { send_rw_status(drive); flp_io_state = FLP_STATE_INTERRUPT; - CycInt_AddRelativeInterrupt(1000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(get_seek_time(drive), 100, INTERRUPT_FLP_IO); } -void floppy_recalibrate(void) { +static void floppy_recalibrate(void) { int drive = cmd_data[0]&0x03; Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Command: Drive = %i",drive); @@ -627,17 +651,18 @@ void floppy_recalibrate(void) { flpdrv[drive].cyl = flp.pcn = 0; flp.st[0] = flp.st[1] = flp.st[2] = 0; + floppy_seek_track(0, 0, drive); /* Done */ flp.st[0] = IC_NORMAL|ST0_SE; flp.sra &= ~SRA_TRK0_N; flp_io_state = FLP_STATE_INTERRUPT; - CycInt_AddRelativeInterrupt(1000000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(get_seek_time(drive), 100, INTERRUPT_FLP_IO); } } -void floppy_seek(Uint8 relative) { +static void floppy_seek(Uint8 relative) { int drive = cmd_data[0]&0x03; int head = (cmd_data[0]&0x04)>>2; flp.st[0] = flp.st[1] = flp.st[2] = 0; @@ -656,10 +681,10 @@ void floppy_seek(Uint8 relative) { } flp_io_state = FLP_STATE_INTERRUPT; - CycInt_AddRelativeInterrupt(1000000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(get_seek_time(drive), 100, INTERRUPT_FLP_IO); } -void floppy_interrupt_status(void) { +static void floppy_interrupt_status(void) { /* Release interrupt */ set_interrupt(INT_PHONE, RELEASE_INT); flp.sra &= ~SRA_INT; @@ -671,7 +696,7 @@ void floppy_interrupt_status(void) { result_size = 2; } -void floppy_specify(void) { +static void floppy_specify(void) { Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Specify: %02X %02X",cmd_data[0],cmd_data[1]); if (cmd_data[1]&0x01) { @@ -682,7 +707,7 @@ void floppy_specify(void) { flp.msr |= STAT_RQM; } -void floppy_configure(void) { +static void floppy_configure(void) { Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Configure: %02X %02X %02X",cmd_data[0],cmd_data[1],cmd_data[2]); flp.eis = cmd_data[1]&0x40; /* Enable or disable implied seek */ @@ -700,22 +725,22 @@ void floppy_configure(void) { flp.msr |= STAT_RQM; } -void floppy_perpendicular(void) { +static void floppy_perpendicular(void) { Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Perpendicular: %02X",cmd_data[0]); flp.msr |= STAT_RQM; } -void floppy_unimplemented(void) { +static void floppy_unimplemented(void) { flp.st[0] = IC_INV_CMD; flp.fifo[0] = flp.st[0]; result_size = 1; flp_io_state = FLP_STATE_INTERRUPT; - CycInt_AddRelativeInterrupt(10000, INT_CPU_CYCLE, INTERRUPT_FLP_IO); + CycInt_AddRelativeInterruptUs(1000, 100, INTERRUPT_FLP_IO); } -void floppy_execute_cmd(void) { +static void floppy_execute_cmd(void) { Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Command: Executing %02X",command); switch (command&CMD_OPCODE_MSK) { @@ -916,7 +941,7 @@ Uint8 floppy_sra_read(void) { /* -- Floppy I/O functions -- */ -void floppy_rw_nodata(void) { +static void floppy_rw_nodata(void) { Log_Printf(LOG_WARN, "[Floppy] Write: No more data from DMA. Stopping."); /* Stop transfer */ flp_sector_counter=0; @@ -925,7 +950,7 @@ void floppy_rw_nodata(void) { send_rw_status(flp_io_drv); } -void floppy_format_done(void) { +static void floppy_format_done(void) { int drive = flp_io_drv; Log_Printf(LOG_WARN, "[Floppy] Format: No more data from DMA. Done."); @@ -934,7 +959,7 @@ void floppy_format_done(void) { send_rw_status(drive); } -void floppy_read_sector(void) { +static void floppy_read_sector(void) { int drive = flp_io_drv; /* Read from image */ @@ -951,8 +976,7 @@ void floppy_read_sector(void) { Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Read sector at offset %i",logical_sec); flp_buffer.size = flp_buffer.limit = sec_size; - fseek(flpdrv[drive].dsk, logical_sec*sec_size, SEEK_SET); - fread(flp_buffer.data, flp_buffer.size, 1, flpdrv[drive].dsk); + File_Read(flp_buffer.data, flp_buffer.size, logical_sec*sec_size, flpdrv[drive].dsk); flpdrv[drive].sector++; flp_sector_counter--; } @@ -964,7 +988,7 @@ void floppy_read_sector(void) { } } -void floppy_write_sector(void) { +static void floppy_write_sector(void) { int drive = flp_io_drv; /* Write to image */ @@ -980,8 +1004,7 @@ void floppy_write_sector(void) { } else { Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Write sector at offset %i",logical_sec); - fseek(flpdrv[drive].dsk, logical_sec*sec_size, SEEK_SET); - fwrite(flp_buffer.data, flp_buffer.size, 1, flpdrv[drive].dsk); + File_Write(flp_buffer.data, flp_buffer.size, logical_sec*sec_size, flpdrv[drive].dsk); flp_buffer.size = 0; flp_buffer.limit = sec_size; flpdrv[drive].sector++; @@ -995,7 +1018,7 @@ void floppy_write_sector(void) { } } -void floppy_format_sector(void) { +static void floppy_format_sector(void) { int drive = flp_io_drv; Uint8 c = flp_buffer.data[0]; Uint8 h = flp_buffer.data[1]; @@ -1024,15 +1047,14 @@ void floppy_format_sector(void) { } else { Log_Printf(LOG_FLP_CMD_LEVEL, "[Floppy] Format sector at offset %i (%i/%i/%i), blocksize: %i", logical_sec,c,h,s,sec_size); - fseek(flpdrv[drive].dsk, logical_sec*sec_size, SEEK_SET); - fwrite(flp_buffer.data, flp_buffer.size, 1, flpdrv[drive].dsk); + File_Write(flp_buffer.data, flp_buffer.size, logical_sec*sec_size, flpdrv[drive].dsk); flp_buffer.size = 0; flp_buffer.limit = 4; } } -Uint32 old_size; +static Uint32 old_size; void FLP_IO_Handler(void) { CycInt_AcknowledgeInterrupt(); @@ -1042,15 +1064,18 @@ void FLP_IO_Handler(void) { if (flp_buffer.size==flp_buffer.limit) { floppy_write_sector(); if (flp_sector_counter==0) { /* done */ - flp_io_state = FLP_STATE_INTERRUPT; + floppy_interrupt(); + flp_io_state = FLP_STATE_DONE; + return; } } else if (flp_buffer.size