AltairZ80: Make WD179X device more robust and fix Coverity issue

This commit is contained in:
Peter Schorn 2019-02-23 13:22:52 +01:00
parent 314a1da988
commit 86114729de

View file

@ -197,6 +197,8 @@ static int32 wd179xdev(const int32 port, const int32 io, const int32 data);
static t_stat wd179x_reset(DEVICE *dptr); static t_stat wd179x_reset(DEVICE *dptr);
static const char* wd179x_description(DEVICE *dptr); static const char* wd179x_description(DEVICE *dptr);
uint8 floorlog2(unsigned int n); uint8 floorlog2(unsigned int n);
static uint8 computeSectorSize(const WD179X_DRIVE_INFO *pDrive);
static uint8 testMode(const WD179X_DRIVE_INFO *pDrive);
WD179X_INFO wd179x_info_data = { { 0x0, 0, 0x30, 4 } }; WD179X_INFO wd179x_info_data = { { 0x0, 0, 0x30, 4 } };
WD179X_INFO *wd179x_info = &wd179x_info_data; WD179X_INFO *wd179x_info = &wd179x_info_data;
@ -453,6 +455,14 @@ uint8 floorlog2(unsigned int n)
return ((n == 0) ? (0xFF) : r); /* 0xFF is error return value */ return ((n == 0) ? (0xFF) : r); /* 0xFF is error return value */
} }
static uint8 computeSectorSize(const WD179X_DRIVE_INFO *pDrive) {
return pDrive->track < MAX_CYL ? floorlog2(pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].sectsize) - 7 : 0xF8;
}
static uint8 testMode(const WD179X_DRIVE_INFO *pDrive) {
return pDrive->track < MAX_CYL ? IMD_MODE_MFM(pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].mode) != (wd179x_info->ddens) : 0;
}
uint8 WD179X_Read(const uint32 Addr) uint8 WD179X_Read(const uint32 Addr)
{ {
uint8 cData; uint8 cData;
@ -525,8 +535,7 @@ uint8 WD179X_Read(const uint32 Addr)
} else { } else {
/* Compute Sector Size */ /* Compute Sector Size */
wd179x_info->fdc_sec_len = floorlog2( wd179x_info->fdc_sec_len = computeSectorSize(pDrive);
pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].sectsize) - 7;
if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */ if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */
sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT " Invalid sector size!\n", wd179x_info->sel_drive, PCX); sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT " Invalid sector size!\n", wd179x_info->sel_drive, PCX);
wd179x_info->fdc_sec_len = 0; wd179x_info->fdc_sec_len = 0;
@ -571,6 +580,7 @@ uint8 WD179X_Read(const uint32 Addr)
return (cData); return (cData);
} }
/* /*
* Command processing happens in three stages: * Command processing happens in three stages:
* 1. Flags and initial conditions are set up based on the Type of the command. * 1. Flags and initial conditions are set up based on the Type of the command.
@ -676,7 +686,7 @@ static uint8 Do1793Command(uint8 cCommand)
" CMD=STEP_U dir=%d\n", wd179x_info->sel_drive, " CMD=STEP_U dir=%d\n", wd179x_info->sel_drive,
PCX, wd179x_info->step_dir); PCX, wd179x_info->step_dir);
if(wd179x_info->step_dir == 1) { if(wd179x_info->step_dir == 1) {
if (pDrive->track < 255) if (pDrive->track < MAX_CYL - 1)
pDrive->track++; pDrive->track++;
} else if (wd179x_info->step_dir == -1) { } else if (wd179x_info->step_dir == -1) {
if (pDrive->track > 0) if (pDrive->track > 0)
@ -692,7 +702,7 @@ static uint8 Do1793Command(uint8 cCommand)
" CMD=STEP_IN\n", wd179x_info->sel_drive, PCX); " CMD=STEP_IN\n", wd179x_info->sel_drive, PCX);
break; break;
case WD179X_STEP_IN_U: case WD179X_STEP_IN_U:
if (pDrive->track < 255) if (pDrive->track < MAX_CYL - 1)
pDrive->track++; pDrive->track++;
wd179x_info->step_dir = 1; wd179x_info->step_dir = 1;
sim_debug(SEEK_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT sim_debug(SEEK_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT
@ -714,8 +724,7 @@ static uint8 Do1793Command(uint8 cCommand)
case WD179X_READ_REC: case WD179X_READ_REC:
case WD179X_READ_RECS: case WD179X_READ_RECS:
/* Compute Sector Size */ /* Compute Sector Size */
wd179x_info->fdc_sec_len = floorlog2( wd179x_info->fdc_sec_len = computeSectorSize(pDrive);
pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].sectsize) - 7;
if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */ if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */
sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT
" Invalid sector size!\n", wd179x_info->sel_drive, PCX); " Invalid sector size!\n", wd179x_info->sel_drive, PCX);
@ -735,7 +744,7 @@ static uint8 Do1793Command(uint8 cCommand)
wd179x_info->fdc_multiple ? "Multiple" : "Single", wd179x_info->fdc_multiple ? "Multiple" : "Single",
wd179x_info->ddens ? "DD" : "SD", 128 << wd179x_info->fdc_sec_len); wd179x_info->ddens ? "DD" : "SD", 128 << wd179x_info->fdc_sec_len);
if(IMD_MODE_MFM(pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].mode) != (wd179x_info->ddens)) { if(testMode(pDrive)) {
wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */
wd179x_info->fdc_status &= ~WD179X_STAT_BUSY; wd179x_info->fdc_status &= ~WD179X_STAT_BUSY;
wd179x_info->intrq = 1; wd179x_info->intrq = 1;
@ -777,8 +786,7 @@ static uint8 Do1793Command(uint8 cCommand)
break; break;
case WD179X_WRITE_REC: case WD179X_WRITE_REC:
/* Compute Sector Size */ /* Compute Sector Size */
wd179x_info->fdc_sec_len = floorlog2( wd179x_info->fdc_sec_len = computeSectorSize(pDrive);
pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].sectsize) - 7;
if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */ if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */
sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT
" Invalid sector size!\n", wd179x_info->sel_drive, PCX); " Invalid sector size!\n", wd179x_info->sel_drive, PCX);
@ -809,15 +817,14 @@ static uint8 Do1793Command(uint8 cCommand)
pDrive->track=0; pDrive->track=0;
/* Compute Sector Size */ /* Compute Sector Size */
wd179x_info->fdc_sec_len = floorlog2( wd179x_info->fdc_sec_len = computeSectorSize(pDrive);
pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].sectsize) - 7;
if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */ if((wd179x_info->fdc_sec_len == 0xF8) || (wd179x_info->fdc_sec_len > WD179X_MAX_SEC_LEN)) { /* Error calculating N or N too large */
sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT sim_debug(ERROR_MSG, &wd179x_dev, "WD179X[%d]: " ADDRESS_FORMAT
" Invalid sector size!\n", wd179x_info->sel_drive, PCX); " Invalid sector size!\n", wd179x_info->sel_drive, PCX);
wd179x_info->fdc_sec_len = 0; wd179x_info->fdc_sec_len = 0;
} }
if(IMD_MODE_MFM(pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].mode) != (wd179x_info->ddens)) { if(testMode(pDrive)) {
wd179x_info->fdc_status = WD179X_STAT_NOT_FOUND; /* Sector not found */ wd179x_info->fdc_status = WD179X_STAT_NOT_FOUND; /* Sector not found */
wd179x_info->intrq = 1; wd179x_info->intrq = 1;
} else { } else {
@ -918,7 +925,7 @@ static uint8 Do1793Command(uint8 cCommand)
if(sectSeek(pDrive->imd, pDrive->track, wd179x_info->fdc_head) != SCPE_OK) { if(sectSeek(pDrive->imd, pDrive->track, wd179x_info->fdc_head) != SCPE_OK) {
sim_debug(SEEK_MSG, &wd179x_dev, "FAILED\n"); sim_debug(SEEK_MSG, &wd179x_dev, "FAILED\n");
wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND;
} else if(IMD_MODE_MFM(pDrive->imd->track[pDrive->track][wd179x_info->fdc_head].mode) != (wd179x_info->ddens)) { } else if(testMode(pDrive)) {
wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */ wd179x_info->fdc_status |= WD179X_STAT_NOT_FOUND; /* Sector not found */
sim_debug(SEEK_MSG, &wd179x_dev, "NOT FOUND\n"); sim_debug(SEEK_MSG, &wd179x_dev, "NOT FOUND\n");
} else { } else {