--- previous/src/mo.c 2018/04/24 19:29:55 1.1.1.2 +++ previous/src/mo.c 2018/04/24 19:31:18 1.1.1.3 @@ -170,7 +170,7 @@ int dnum; #define MO_SECTORSIZE_DATA 1024 /* size of decoded sector, like handled by software */ -Uint32 get_logical_sector(Uint32 sector_id) { +static Uint32 get_logical_sector(Uint32 sector_id) { Sint32 tracknum = (sector_id&0xFFFF00)>>8; Uint8 sectornum = sector_id&0x0F; @@ -198,47 +198,61 @@ void MO_Init(void); void MO_Uninit(void); /* Experimental */ -#define SECTOR_IO_DELAY 2500 -#define CMD_DELAY 1000 +#define SECTOR_IO_DELAY 1250 +#define CMD_DELAY 40 -void mo_set_signals(bool complete, bool attn, int delay); -void mo_push_signals(bool complete, bool attn, int drive); -void osp_poll_mo_signals(void); - -void ecc_read(void); -void ecc_write(void); -void ecc_verify(void); - -void mo_read_sector(Uint32 sector_id); -void mo_write_sector(Uint32 sector_id); -void mo_erase_sector(Uint32 sector_id); -void mo_verify_sector(Uint32 sector_id); - -void mo_seek(Uint16 command); -void mo_high_order_seek(Uint16 command); -void mo_jump_head(Uint16 command); -void mo_recalibrate(void); -void mo_return_drive_status(void); -void mo_return_track_addr(void); -void mo_return_extended_status(void); -void mo_return_hardware_status(void); -void mo_return_version(void); -void mo_select_head(int head); -void mo_reset_attn_status(void); -void mo_stop_spinning(void); -void mo_start_spinning(void); -void mo_eject_disk(int drv); -void mo_start_spiraling(void); -void mo_stop_spiraling(void); -void mo_self_diagnostic(void); +#define SEEK_TIMING 1 -void mo_unimplemented_cmd(void); +static void mo_set_signals(bool complete, bool attn, int delay); +static void mo_push_signals(bool complete, bool attn, int drive); +static void osp_poll_mo_signals(void); + +static void ecc_read(void); +static void ecc_write(void); +static void ecc_verify(void); + +static void mo_read_sector(Uint32 sector_id); +static void mo_write_sector(Uint32 sector_id); +static void mo_erase_sector(Uint32 sector_id); +static void mo_verify_sector(Uint32 sector_id); + +static void mo_seek(Uint16 command); +static void mo_high_order_seek(Uint16 command); +static void mo_jump_head(Uint16 command); +static void mo_recalibrate(void); +static void mo_return_drive_status(void); +static void mo_return_track_addr(void); +static void mo_return_extended_status(void); +static void mo_return_hardware_status(void); +static void mo_return_version(void); +static void mo_select_head(int head); +static void mo_reset_attn_status(void); +static void mo_stop_spinning(void); +static void mo_start_spinning(void); +static void mo_eject_disk(int drv); +static void mo_start_spiraling(void); +static void mo_stop_spiraling(void); +static void mo_self_diagnostic(void); + +static Uint32 get_logical_sector(Uint32 sector_id); +static void fmt_sector_done(void); +static bool fmt_match_id(Uint32 sector_id); +static void fmt_io(Uint32 sector_id); +static void ecc_toggle_buffer(void); +static void ecc_clear_buffer(void); +static void ecc_decode(void); +static void ecc_encode(void); +static void ecc_sequence_done(void); +static bool mo_drive_empty(void); +static bool mo_protected(void); +static void mo_unimplemented_cmd(void); +static void mo_spiraling_operation(void); +static Uint32 get_logical_sector(Uint32 sector_id); +static void mo_insert_disk(int drv); -void mo_spiraling_operation(void); +static int sector_increment = 0; -int sector_increment = 0; - -void osp_interrupt(Uint8 interrupt); +static void osp_interrupt(Uint8 interrupt); /* ------------------------ OPTICAL STORAGE PROCESSOR ------------------------ */ @@ -472,8 +486,9 @@ void MO_Flag6_Write(void) { Log_Printf(LOG_MO_REG_LEVEL,"[MO] Flag 6 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc()); } +#if 0 /* Register debugging */ -void print_regs(void) { +static void print_regs(void) { int i; Log_Printf(LOG_WARN,"sector ID: %02X%02X%02X",mo.tracknumh,mo.tracknuml,mo.sector_num); Log_Printf(LOG_WARN,"head pos: %04X",modrv[dnum].head_pos); @@ -493,6 +508,7 @@ void print_regs(void) { Log_Printf(LOG_WARN,"flag %i: %02X",i+1,mo.flag[i]); } } +#endif void osp_interrupt(Uint8 interrupt) { mo.intstatus|=interrupt; @@ -864,7 +880,7 @@ void ecc_write(void) { } ecc_buffer[eccin].size=0; /* FIXME: find a better place for this */ ecc_buffer[eccin].limit=MO_SECTORSIZE_DATA; /* and this */ - CycInt_AddRelativeInterrupt(ECC_DELAY, INT_CPU_CYCLE, INTERRUPT_ECC_IO); + CycInt_AddRelativeInterruptUsCycles(ECC_DELAY, 80, INTERRUPT_ECC_IO); } void ecc_read(void) { if (ecc_state!=ECC_STATE_DONE) { @@ -876,7 +892,7 @@ void ecc_read(void) { if (mo.ctrlr_csr2&MOCSR2_ECC_BLOCKS) { ecc_repeat=true; } - CycInt_AddRelativeInterrupt(ECC_DELAY, INT_CPU_CYCLE, INTERRUPT_ECC_IO); + CycInt_AddRelativeInterruptUsCycles(ECC_DELAY, 80, INTERRUPT_ECC_IO); } void ecc_verify(void) { if (ecc_state!=ECC_STATE_DONE) { @@ -885,7 +901,7 @@ void ecc_verify(void) { } ecc_mode=ECC_MODE_VERIFY; ecc_state=ECC_STATE_ECCING; - CycInt_AddRelativeInterrupt(ECC_DELAY, INT_CPU_CYCLE, INTERRUPT_ECC_IO); + CycInt_AddRelativeInterruptUsCycles(ECC_DELAY, 80, INTERRUPT_ECC_IO); } void ecc_sequence_done(void) { if (ecc_repeat==true) { @@ -896,7 +912,7 @@ void ecc_sequence_done(void) { } else { ecc_state=ECC_STATE_ECCING; } - CycInt_AddRelativeInterrupt(ECC_DELAY, INT_CPU_CYCLE, INTERRUPT_ECC_IO); + CycInt_AddRelativeInterruptUsCycles(ECC_DELAY, 80, INTERRUPT_ECC_IO); return; } @@ -998,7 +1014,7 @@ void ECC_IO_Handler(void) { return; } - CycInt_AddRelativeInterrupt(ECC_DELAY, INT_CPU_CYCLE, INTERRUPT_ECC_IO); + CycInt_AddRelativeInterruptUsCycles(ECC_DELAY, 80, INTERRUPT_ECC_IO); } @@ -1012,9 +1028,7 @@ void mo_read_sector(Uint32 sector_id) { Log_Printf(LOG_MO_IO_LEVEL, "MO disk %i: Read sector at offset %i (%i sectors remaining)", dnum, sector_num, sector_counter-1); - /* seek to the position */ - fseek(modrv[dnum].dsk, sector_num*MO_SECTORSIZE_DISK, SEEK_SET); - fread(ecc_buffer[eccin].data, MO_SECTORSIZE_DISK, 1, modrv[dnum].dsk); + File_Read(ecc_buffer[eccin].data, MO_SECTORSIZE_DISK, sector_num*MO_SECTORSIZE_DISK, modrv[dnum].dsk); ecc_buffer[eccin].limit = ecc_buffer[eccin].size = MO_SECTORSIZE_DISK; } @@ -1026,9 +1040,7 @@ void mo_write_sector(Uint32 sector_id) { dnum, sector_num, sector_counter-1); if (ecc_buffer[eccout].limit==MO_SECTORSIZE_DISK) { - /* seek to the position */ - fseek(modrv[dnum].dsk, sector_num*MO_SECTORSIZE_DISK, SEEK_SET); - fwrite(ecc_buffer[eccout].data, MO_SECTORSIZE_DISK, 1, modrv[dnum].dsk); + File_Write(ecc_buffer[eccout].data, MO_SECTORSIZE_DISK, sector_num*MO_SECTORSIZE_DISK, modrv[dnum].dsk); ecc_buffer[eccout].size = 0; ecc_buffer[eccout].limit = MO_SECTORSIZE_DATA; @@ -1048,9 +1060,7 @@ void mo_erase_sector(Uint32 sector_id) { Uint8 erase_buf[MO_SECTORSIZE_DISK]; memset(erase_buf, 0xFF, MO_SECTORSIZE_DISK); - /* seek to the position */ - fseek(modrv[dnum].dsk, sector_num*MO_SECTORSIZE_DISK, SEEK_SET); - fwrite(erase_buf, MO_SECTORSIZE_DISK, 1, modrv[dnum].dsk); + File_Write(erase_buf, MO_SECTORSIZE_DISK, sector_num*MO_SECTORSIZE_DISK, modrv[dnum].dsk); } void mo_verify_sector(Uint32 sector_id) { @@ -1059,9 +1069,7 @@ void mo_verify_sector(Uint32 sector_id) Log_Printf(LOG_MO_IO_LEVEL, "MO disk %i: Verify sector at offset %i (%i sectors remaining)", dnum, sector_num, sector_counter-1); - /* seek to the position */ - fseek(modrv[dnum].dsk, sector_num*MO_SECTORSIZE_DISK, SEEK_SET); - fread(ecc_buffer[eccin].data, MO_SECTORSIZE_DISK, 1, modrv[dnum].dsk); + File_Read(ecc_buffer[eccin].data, MO_SECTORSIZE_DISK, sector_num*MO_SECTORSIZE_DISK, modrv[dnum].dsk); ecc_buffer[eccin].limit = ecc_buffer[eccin].size = MO_SECTORSIZE_DISK; } @@ -1300,7 +1308,6 @@ bool mo_protected(void) { return false; } -#define SEEK_TIMING 0 void mo_seek(Uint16 command) { #if SEEK_TIMING int seek_time=modrv[dnum].head_pos; @@ -1316,11 +1323,12 @@ void mo_seek(Uint16 command) { } else { seek_time=modrv[dnum].head_pos-seek_time; } - seek_time*=20; - if (seek_time>180000) { - seek_time=180000; + if (seek_time>95000) { + seek_time=95000; } - mo_set_signals(true, false, 20000+seek_time); + seek_time+=5000; + + mo_set_signals(true, false, seek_time); #else mo_set_signals(true, false, CMD_DELAY); #endif @@ -1383,7 +1391,7 @@ void mo_jump_head(Uint16 command) { return; } #if SEEK_TIMING - mo_set_signals(true, false, 10000); + mo_set_signals(true, false, 1600); #else mo_set_signals(true, false, CMD_DELAY); #endif @@ -1465,7 +1473,7 @@ void mo_start_spinning(void) { Statusbar_AddMessage("Spin-up magneto-optical disk.", 0); modrv[dnum].dstat &= ~DS_STOPPED; modrv[dnum].spinning=true; - mo_set_signals(true, false, 30000000); + mo_set_signals(true, false, 1600000); } void mo_eject_disk(int drv) { @@ -1495,14 +1503,39 @@ void mo_insert_disk(int drv) { if (ConfigureParams.MO.drive[drv].bWriteProtected) { modrv[drv].dsk = File_Open(ConfigureParams.MO.drive[drv].szImageName, "rb"); - modrv[drv].protected=true; + if (modrv[drv].dsk == NULL) { + Log_Printf(LOG_WARN, "MO Disk%i: Cannot open image file %s\n", + drv, ConfigureParams.MO.drive[drv].szImageName); + modrv[drv].inserted=false; + modrv[drv].protected=false; + Statusbar_AddMessage("Cannot insert magneto-optical disk.", 0); + return; + } else { + modrv[drv].inserted=true; + modrv[drv].protected=true; + } } else { modrv[drv].dsk = File_Open(ConfigureParams.MO.drive[drv].szImageName, "rb+"); - modrv[drv].protected=false; + if (modrv[drv].dsk == NULL) { + modrv[drv].dsk = File_Open(ConfigureParams.MO.drive[drv].szImageName, "rb"); + if (modrv[drv].dsk == NULL) { + Log_Printf(LOG_WARN, "MO Disk%i: Cannot open image file %s\n", + drv, ConfigureParams.MO.drive[drv].szImageName); + modrv[drv].inserted=false; + modrv[drv].protected=false; + Statusbar_AddMessage("Cannot insert magneto-optical disk.", 0); + return; + } else { + modrv[drv].inserted=true; + modrv[drv].protected=true; + } + } else { + modrv[drv].inserted=true; + modrv[drv].protected=false; + } } - + Statusbar_AddMessage("Inserting magneto-optical disk.", 0); - modrv[drv].inserted=true; modrv[drv].dstat&=~DS_EMPTY; modrv[drv].dstat|=DS_INSERT; modrv[drv].spinning=false; @@ -1521,7 +1554,7 @@ void mo_start_spiraling(void) { } if (!modrv[0].spiraling && !modrv[1].spiraling) { /* periodic disk operation already active? */ - CycInt_AddRelativeInterrupt(SECTOR_IO_DELAY, INT_CPU_CYCLE, INTERRUPT_MO_IO); + CycInt_AddRelativeInterruptUsCycles(SECTOR_IO_DELAY, 400, INTERRUPT_MO_IO); } modrv[dnum].spiraling=true; @@ -1556,7 +1589,7 @@ void mo_spiraling_operation(void) { modrv[i].sec_offset%=MO_SEC_PER_TRACK; } } - CycInt_AddRelativeInterrupt(SECTOR_IO_DELAY, INT_CPU_CYCLE, INTERRUPT_MO_IO); + CycInt_AddRelativeInterruptUsCycles(SECTOR_IO_DELAY, 400, INTERRUPT_MO_IO); } void mo_self_diagnostic(void) { @@ -1654,7 +1687,7 @@ void mo_set_signals(bool complete, bool delayed_drive=dnum; delayed_compl=complete; delayed_attn=attn; - CycInt_AddRelativeInterrupt(delay, INT_CPU_CYCLE, INTERRUPT_MO); + CycInt_AddRelativeInterruptUsCycles(delay, CMD_DELAY, INTERRUPT_MO); } else { mo_push_signals(complete, attn, dnum); } @@ -1687,13 +1720,34 @@ void MO_Init(void) { modrv[i].dstat=modrv[i].estat=modrv[i].hstat=0; if (ConfigureParams.MO.drive[i].bDiskInserted && File_Exists(ConfigureParams.MO.drive[i].szImageName)) { - modrv[i].inserted=true; if (ConfigureParams.MO.drive[i].bWriteProtected) { modrv[i].dsk = File_Open(ConfigureParams.MO.drive[i].szImageName, "rb"); - modrv[i].protected=true; + if (modrv[i].dsk == NULL) { + Log_Printf(LOG_WARN, "MO Disk%i: Cannot open image file %s\n", + i, ConfigureParams.MO.drive[i].szImageName); + modrv[i].inserted=false; + modrv[i].protected=false; + } else { + modrv[i].inserted=true; + modrv[i].protected=true; + } } else { modrv[i].dsk = File_Open(ConfigureParams.MO.drive[i].szImageName, "rb+"); - modrv[i].protected=false; + if (modrv[i].dsk == NULL) { + modrv[i].dsk = File_Open(ConfigureParams.MO.drive[i].szImageName, "rb"); + if (modrv[i].dsk == NULL) { + Log_Printf(LOG_WARN, "MO Disk%i: Cannot open image file %s\n", + i, ConfigureParams.MO.drive[i].szImageName); + modrv[i].inserted=false; + modrv[i].protected=false; + } else { + modrv[i].inserted=true; + modrv[i].protected=true; + } + } else { + modrv[i].inserted=true; + modrv[i].protected=false; + } } } else { modrv[i].dsk = NULL;