Modified empty IDE channel handling, should hopefully reduce problems;

Fixed several ATAPI CD-ROM bugs;
Added some missing CPL override checks to the MMU translate functions;
Tertiary and quaternary IDE controllers are now automatically disabled if not a single device is attached to them;
Changed sleep time on compile from 10 seconds to 2 seconds.
This commit is contained in:
OBattler
2017-01-17 19:41:42 +01:00
parent e961f43cbf
commit 6b86549b7e
8 changed files with 280 additions and 146 deletions

View File

@@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9
86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ)
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS)
sleep 10 sleep 2
strip "86Box.exe" strip "86Box.exe"
sleep 10 sleep 2
all : 86Box.exe all : 86Box.exe

View File

@@ -1706,6 +1706,7 @@ void *BuslogicInit()
io_sethandler(scsi_base, 0x0004, BuslogicRead, NULL, NULL, BuslogicWrite, NULL, NULL, Buslogic); io_sethandler(scsi_base, 0x0004, BuslogicRead, NULL, NULL, BuslogicWrite, NULL, NULL, Buslogic);
BuslogicLog("Building CD-ROM map...\n");
build_scsi_cdrom_map(); build_scsi_cdrom_map();
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id)) if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id))

View File

@@ -304,6 +304,7 @@ void cdrom_init(int id, int cdb_len_setting, int bus_type)
cdrom[id].sense[0] = 0xf0; cdrom[id].sense[0] = 0xf0;
cdrom[id].sense[7] = 10; cdrom[id].sense[7] = 10;
cdrom_drives[id].bus_mode = cdrom_drives[id].bus_type ? 2 : 3; cdrom_drives[id].bus_mode = cdrom_drives[id].bus_type ? 2 : 3;
cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", id, cdrom_drives[id].bus_type, cdrom_drives[id].bus_mode);
if (!cdrom_drives[id].bus_type) if (!cdrom_drives[id].bus_type)
{ {
cdrom_set_signature(id); cdrom_set_signature(id);
@@ -772,7 +773,26 @@ static void cdrom_command_common(uint8_t id)
cdrom[id].status = BUSY_STAT; cdrom[id].status = BUSY_STAT;
cdrom[id].phase = 1; cdrom[id].phase = 1;
cdrom[id].pos = 0; cdrom[id].pos = 0;
cdrom[id].callback = 60 * CDROM_TIME; if (cdrom[id].packet_status == CDROM_PHASE_COMPLETE)
{
cdrom[id].callback = 20 * CDROM_TIME;
}
else if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN)
{
if (cdrom[id].current_cdb[0] == 0x42)
{
cdrom_log("CD-ROM %i: READ SUBCHANNEL\n");
cdrom[id].callback = 1000 * CDROM_TIME;
}
else
{
cdrom[id].callback = 60 * CDROM_TIME;
}
}
else
{
cdrom[id].callback = 60 * CDROM_TIME;
}
} }
static void cdrom_command_complete(uint8_t id) static void cdrom_command_complete(uint8_t id)
@@ -807,6 +827,15 @@ static void cdrom_command_write_dma(uint8_t id)
cdrom_command_common(id); cdrom_command_common(id);
} }
static int cdrom_request_length_is_zero(uint8_t id)
{
if ((cdrom[id].request_length == 0) && !cdrom_drives[id].bus_type)
{
return 1;
}
return 0;
}
static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction)
{ {
cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, cdrom[id].current_cdb[0], len, block_len, alloc_len, direction, cdrom[id].request_length); cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, cdrom[id].current_cdb[0], len, block_len, alloc_len, direction, cdrom[id].request_length);
@@ -818,7 +847,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al
len = alloc_len; len = alloc_len;
} }
} }
if ((len == 0) || (cdrom_current_mode(id) == 0)) if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0))
{ {
cdrom_command_complete(id); cdrom_command_complete(id);
} }
@@ -828,14 +857,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al
{ {
if (cdrom_drives[id].bus_type) if (cdrom_drives[id].bus_type)
{ {
if (cdrom_is_media_access(id)) SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len;
{
SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len;
}
else
{
SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len;
}
} }
if (direction == 0) if (direction == 0)
{ {
@@ -1150,7 +1172,7 @@ int cdrom_read_blocks(uint8_t id, int *len, int first_batch)
if (!cdrom[id].sector_len) if (!cdrom[id].sector_len)
{ {
cdrom_command_complete(id); cdrom_command_complete(id);
return 0; return -1;
} }
cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos); cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos);
@@ -1754,7 +1776,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
} }
ret = cdrom_read_blocks(id, &alloc_length, 1); ret = cdrom_read_blocks(id, &alloc_length, 1);
if (!ret) if (ret <= 0)
{ {
return; return;
} }
@@ -2465,13 +2487,20 @@ int cdrom_block_check(uint8_t id)
if (cdrom_is_media_access(id)) if (cdrom_is_media_access(id))
{ {
/* We have finished the current block. */ /* We have finished the current block. */
cdrom_log("CD-ROM %i: %i bytes total read, %i bytes all total\n", cdrom[id].total_read, cdrom[id].all_blocks_total); cdrom_log("CD-ROM %i: %i bytes total read, %i bytes all total\n", id, cdrom[id].total_read, cdrom[id].all_blocks_total);
if (cdrom[id].total_read >= cdrom[id].all_blocks_total) if (cdrom[id].total_read >= cdrom[id].all_blocks_total)
{ {
cdrom_log("CD-ROM %i: %i bytes read, current block finished\n", id, cdrom[id].total_read); cdrom_log("CD-ROM %i: %i bytes read, current block finished\n", id, cdrom[id].total_read);
/* Read the next block. */ /* Read the next block. */
ret = cdrom_read_blocks(id, &alloc_length, 0); ret = cdrom_read_blocks(id, &alloc_length, 0);
if (!ret) if (ret == -1)
{
/* Return value is -1 - there are no further blocks to read. */
cdrom_log("CD-ROM %i: %i bytes read, no further blocks to read\n", id, cdrom[id].total_read);
cdrom[id].status = BUSY_STAT;
return 1;
}
else if (ret == 0)
{ {
/* Return value is 0 - an error has occurred. */ /* Return value is 0 - an error has occurred. */
cdrom_log("CD-ROM %i: %i bytes read, error while reading blocks\n", id, cdrom[id].total_read); cdrom_log("CD-ROM %i: %i bytes read, error while reading blocks\n", id, cdrom[id].total_read);
@@ -2746,6 +2775,7 @@ int cdrom_phase_callback(uint8_t id)
// cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); // cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id);
cdrom[id].status = READY_STAT; cdrom[id].status = READY_STAT;
cdrom[id].phase = 3; cdrom[id].phase = 3;
cdrom[id].packet_status = 0xFF;
return 1; return 1;
case CDROM_PHASE_DATA_OUT: case CDROM_PHASE_DATA_OUT:
// cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id);
@@ -2809,7 +2839,7 @@ uint8_t cdrom_read(uint8_t channel)
/* If the block check has returned 0, this means all the requested blocks have been read, therefore the command has finished. */ /* If the block check has returned 0, this means all the requested blocks have been read, therefore the command has finished. */
if (ret) if (ret)
{ {
cdrom_log("CD-ROM %i: Return value is 1\n", id); cdrom_log("CD-ROM %i: Return value is 1 (request length: %i)\n", id, cdrom[id].request_length);
if (cdrom[id].request_pos >= cdrom[id].request_length) if (cdrom[id].request_pos >= cdrom[id].request_length)
{ {
/* Time for a DRQ. */ /* Time for a DRQ. */
@@ -2825,7 +2855,7 @@ uint8_t cdrom_read(uint8_t channel)
{ {
cdrom_log("CD-ROM %i: Return value is 0\n", id); cdrom_log("CD-ROM %i: Return value is 0\n", id);
} }
cdrom_log("CD-ROM %i: Returning: %04X (buffer position: %i, request position: %i, total: %i)\n", id, temp, cdrom[id].pos, cdrom[id].request_pos, cdrom[id].total_read); cdrom_log("CD-ROM %i: Returning: %02X (buffer position: %i, request position: %i, total: %i)\n", id, temp, cdrom[id].pos, cdrom[id].request_pos, cdrom[id].total_read);
return temp; return temp;
} }
else else

159
src/ide.c
View File

@@ -59,8 +59,10 @@
#define WIN_READ_DMA 0xC8 #define WIN_READ_DMA 0xC8
#define WIN_WRITE_DMA 0xCA #define WIN_WRITE_DMA 0xCA
#define WIN_STANDBYNOW1 0xE0 #define WIN_STANDBYNOW1 0xE0
#define WIN_IDLENOW1 0xE1
#define WIN_SETIDLE1 0xE3 #define WIN_SETIDLE1 0xE3
#define WIN_CHECKPOWERMODE1 0xE5 #define WIN_CHECKPOWERMODE1 0xE5
#define WIN_SLEEP1 0xE6
#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ #define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */
#define WIN_SET_FEATURES 0xEF #define WIN_SET_FEATURES 0xEF
#define WIN_READ_NATIVE_MAX 0xF8 #define WIN_READ_NATIVE_MAX 0xF8
@@ -373,8 +375,11 @@ static void ide_identify(IDE *ide)
// ide->buffer[63] = 7; /*Multiword DMA*/ // ide->buffer[63] = 7; /*Multiword DMA*/
if (ide->board < 2) if (ide->board < 2)
{ {
ide->buffer[53] = 2;
ide->buffer[62] = ide->dma_identify_data[0]; ide->buffer[62] = ide->dma_identify_data[0];
ide->buffer[63] = ide->dma_identify_data[1]; ide->buffer[63] = ide->dma_identify_data[1];
ide->buffer[65] = 150;
ide->buffer[66] = 150;
ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/
ide->buffer[88] = ide->dma_identify_data[2]; ide->buffer[88] = ide->dma_identify_data[2];
} }
@@ -398,14 +403,19 @@ static void ide_atapi_identify(IDE *ide)
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[49] = 0x200; /* LBA supported */
ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[51] = 2 << 8; /*PIO timing mode*/
ide->buffer[73] = 6;
ide->buffer[73] = 9;
if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2))
{ {
ide->buffer[49] |= 0x100; /* DMA supported */ ide->buffer[49] |= 0x100; /* DMA supported */
ide->buffer[52] = 2 << 8; /*DMA timing mode*/ ide->buffer[52] = 2 << 8; /*DMA timing mode*/
ide->buffer[53] = 2;
ide->buffer[62] = ide->dma_identify_data[0]; ide->buffer[62] = ide->dma_identify_data[0];
ide->buffer[63] = ide->dma_identify_data[1]; ide->buffer[63] = ide->dma_identify_data[1];
ide->buffer[88] = ide->dma_identify_data[2]; ide->buffer[65] = 150;
ide->buffer[66] = 150;
// ide->buffer[88] = ide->dma_identify_data[2];
} }
} }
@@ -580,20 +590,28 @@ int ide_cdrom_is_pio_only(IDE *ide)
int ide_set_features(IDE *ide) int ide_set_features(IDE *ide)
{ {
uint8_t cdrom_id = cur_ide[ide->board]; uint8_t cdrom_id = cur_ide[ide->board];
uint8_t features = 0;
uint8_t sf_data = 0;
uint8_t val = 0; uint8_t val = 0;
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
{ {
val = cdrom[cdrom_id].phase & 7; features = cdrom[cdrom_id].features;
sf_data = cdrom[cdrom_id].phase;
} }
else else
{ {
val = ide->secount & 7; features = ide->cylprecomp;
sf_data = ide->secount;
} }
val = sf_data & 7;
if (ide->type == IDE_NONE) return 0; if (ide->type == IDE_NONE) return 0;
switch(ide->cylprecomp) switch(features)
{ {
case 0x02: case 0x02:
case 0x82: case 0x82:
@@ -612,17 +630,21 @@ int ide_set_features(IDE *ide)
case 0xc2: case 0xc2:
return 1; return 1;
case 0x03: case 0x03:
#if 0
if (ide->type == IDE_CDROM) if (ide->type == IDE_CDROM)
{ {
return 0; return 0;
} }
switch(ide->secount >> 3) #endif
switch(sf_data >> 3)
{ {
case 0: case 0:
case 1:
ide->dma_identify_data[0] = ide->dma_identify_data[1] = 7; ide->dma_identify_data[0] = ide->dma_identify_data[1] = 7;
ide->dma_identify_data[2] = 0x3f; ide->dma_identify_data[2] = 0x3f;
break; break;
case 1:
/* We do not (yet) emulate flow control, so return with error if this is attempted. */
return 0;
case 2: case 2:
if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2)) if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2))
{ {
@@ -722,6 +744,9 @@ void resetide(void)
{ {
cur_ide[d] = d << 1; cur_ide[d] = d << 1;
} }
ide_ter_disable_cond();
ide_qua_disable_cond();
} }
int idetimes = 0; int idetimes = 0;
@@ -741,9 +766,6 @@ void ide_write_data(int ide_board, uint8_t val)
#endif #endif
// ide_log("Write IDEw %04X\n",val); // ide_log("Write IDEw %04X\n",val);
idebufferb[ide->pos] = val;
ide->pos++;
if (ide->command == WIN_PACKETCMD) if (ide->command == WIN_PACKETCMD)
{ {
if (!ide_drive_is_cdrom(ide)) if (!ide_drive_is_cdrom(ide))
@@ -761,6 +783,9 @@ void ide_write_data(int ide_board, uint8_t val)
} }
else else
{ {
idebufferb[ide->pos] = val;
ide->pos++;
if (ide->pos>=512) if (ide->pos>=512)
{ {
ide->pos=0; ide->pos=0;
@@ -962,19 +987,31 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
case 0x1F7: /* Command register */ case 0x1F7: /* Command register */
if (ide->type == IDE_NONE) if (ide->type == IDE_NONE)
{ {
ide->error=1;
if (ide_drive_is_cdrom(ide))
{
cdrom[atapi_cdrom_drives[ide->channel]].error = 1;
}
return; return;
} }
#if 0 if (ide_drive_is_cdrom(ide))
if (ide_drive_is_cdrom(ide_other))
{ {
#if 0
ide_log("Write CD-ROM ATA command: %02X\n", val); ide_log("Write CD-ROM ATA command: %02X\n", val);
}
#endif #endif
switch(val)
{
case WIN_SRST:
case WIN_CHECKPOWERMODE1:
case WIN_DRIVE_DIAGNOSTICS:
case WIN_IDLENOW1:
case WIN_PACKETCMD:
case WIN_PIDENTIFY:
case WIN_IDENTIFY:
case WIN_SET_FEATURES:
case WIN_SLEEP1:
case WIN_STANDBYNOW1:
break;
default:
val = 0xFF;
break;
}
}
ide_irq_lower(ide); ide_irq_lower(ide);
ide->command=val; ide->command=val;
@@ -1146,8 +1183,10 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/
case WIN_NOP: case WIN_NOP:
case WIN_STANDBYNOW1: case WIN_STANDBYNOW1:
case WIN_IDLENOW1:
case WIN_SETIDLE1: /* Idle */ case WIN_SETIDLE1: /* Idle */
case WIN_CHECKPOWERMODE1: case WIN_CHECKPOWERMODE1:
case WIN_SLEEP1:
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
{ {
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
@@ -1260,10 +1299,6 @@ uint8_t ide_read_data(int ide_board)
uint8_t *idebufferb = (uint8_t *) ide->buffer; uint8_t *idebufferb = (uint8_t *) ide->buffer;
temp = idebufferb[ide->pos];
ide->pos++;
if (ide->command == WIN_PACKETCMD) if (ide->command == WIN_PACKETCMD)
{ {
if (!ide_drive_is_cdrom(ide)) if (!ide_drive_is_cdrom(ide))
@@ -1277,6 +1312,11 @@ uint8_t ide_read_data(int ide_board)
idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback;
} }
} }
else
{
temp = idebufferb[ide->pos];
ide->pos++;
}
if (ide->pos>=512 && ide->command != WIN_PACKETCMD) if (ide->pos>=512 && ide->command != WIN_PACKETCMD)
{ {
ide->pos=0; ide->pos=0;
@@ -1324,19 +1364,6 @@ uint8_t readide(int ide_board, uint16_t addr)
addr|=0x90; addr|=0x90;
addr&=0xFFF7; addr&=0xFFF7;
if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7 || addr == 0x3f6))
{
if ((addr == 0x1f7) || (addr == 0x3f6))
{
/* This is apparently required for an empty ID channel. */
ide_log("Reading port %04X on empty IDE channel, returning 0x30...\n", addr);
// return 0x20;
return 0x20 | DSC_STAT;
}
ide_log("Reading port %04X on empty IDE channel, returning zero...\n", addr);
return 0;
}
switch (addr) switch (addr)
{ {
case 0x1F0: /* Data */ case 0x1F0: /* Data */
@@ -1349,7 +1376,7 @@ uint8_t readide(int ide_board, uint16_t addr)
case 0x1F1: /* Error */ case 0x1F1: /* Error */
if (ide->type == IDE_NONE) if (ide->type == IDE_NONE)
{ {
temp = 1; temp = 0;
} }
else else
{ {
@@ -1378,32 +1405,18 @@ uint8_t readide(int ide_board, uint16_t addr)
0 1 0 Data from host 0 1 0 Data from host
1 0 1 Status. */ 1 0 1 Status. */
case 0x1F2: /* Sector count */ case 0x1F2: /* Sector count */
if (ide->type == IDE_NONE) if (ide_drive_is_cdrom(ide))
{ {
temp = 1; temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase;
} }
else else
{ {
if (ide_drive_is_cdrom(ide)) temp = ide->secount;
{
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase;
}
else
{
temp = ide->secount;
}
} }
break; break;
case 0x1F3: /* Sector */ case 0x1F3: /* Sector */
if (ide->type == IDE_NONE) temp = (uint8_t)ide->sector;
{
temp = 1;
}
else
{
temp = (uint8_t)ide->sector;
}
break; break;
case 0x1F4: /* Cylinder low */ case 0x1F4: /* Cylinder low */
@@ -1443,7 +1456,7 @@ uint8_t readide(int ide_board, uint16_t addr)
break; break;
case 0x1F6: /* Drive/Head */ case 0x1F6: /* Drive/Head */
if (ide->type == IDE_NONE) if (ide_drive_is_cdrom(ide))
{ {
temp = (uint8_t)(((cur_ide[ide_board] & 1) ? 0x10 : 0) | 0xa0); temp = (uint8_t)(((cur_ide[ide_board] & 1) ? 0x10 : 0) | 0xa0);
} }
@@ -1457,6 +1470,10 @@ uint8_t readide(int ide_board, uint16_t addr)
DF (drive fault). */ DF (drive fault). */
case 0x1F7: /* Status */ case 0x1F7: /* Status */
ide_irq_lower(ide); ide_irq_lower(ide);
if (ide->type == IDE_NONE)
{
return 0;
}
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
{ {
temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0);
@@ -1471,8 +1488,7 @@ uint8_t readide(int ide_board, uint16_t addr)
case 0x3F6: /* Alternate Status */ case 0x3F6: /* Alternate Status */
if (ide->type == IDE_NONE) if (ide->type == IDE_NONE)
{ {
temp = DSC_STAT; return 0;
break;
} }
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
{ {
@@ -1614,6 +1630,7 @@ void callbackide(int ide_board)
} }
case WIN_NOP: case WIN_NOP:
case WIN_STANDBYNOW1: case WIN_STANDBYNOW1:
case WIN_IDLENOW1:
case WIN_SETIDLE1: case WIN_SETIDLE1:
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
{ {
@@ -1627,9 +1644,11 @@ void callbackide(int ide_board)
return; return;
case WIN_CHECKPOWERMODE1: case WIN_CHECKPOWERMODE1:
case WIN_SLEEP1:
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
{ {
goto abort_cmd; cdrom[cdrom_id].phase = 0xFF;
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
} }
ide->secount = 0xFF; ide->secount = 0xFF;
ide->atastat = READY_STAT | DSC_STAT; ide->atastat = READY_STAT | DSC_STAT;
@@ -1854,10 +1873,13 @@ void callbackide(int ide_board)
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
{ {
cdrom[cdrom_id].status = 0; cdrom[cdrom_id].status = 0;
cdrom[cdrom_id].error = 1;
ide_irq_raise(ide);
} }
else else
{ {
ide->atastat = READY_STAT | DSC_STAT; ide->atastat = READY_STAT | DSC_STAT;
ide->error = 1;
ide_irq_raise(ide); ide_irq_raise(ide);
} }
return; return;
@@ -1930,6 +1952,8 @@ void callbackide(int ide_board)
if (ide->type == IDE_NONE) if (ide->type == IDE_NONE)
{ {
ide_set_signature(ide); ide_set_signature(ide);
cdrom[cdrom_id].status = READY_STAT | ERR_STAT | DSC_STAT;
cdrom[cdrom_id].pos = 0;
goto abort_cmd; goto abort_cmd;
} }
if (ide_drive_is_cdrom(ide)) if (ide_drive_is_cdrom(ide))
@@ -1959,7 +1983,10 @@ void callbackide(int ide_board)
idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback;
ide_log("IDE callback now: %i\n", idecallback[ide_board]); ide_log("IDE callback now: %i\n", idecallback[ide_board]);
return; return;
}
case 0xFF:
goto abort_cmd;
}
abort_cmd: abort_cmd:
ide->command = 0; ide->command = 0;
@@ -2141,6 +2168,14 @@ void ide_ter_disable()
io_removehandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); io_removehandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL);
} }
void ide_ter_disable_cond()
{
if ((ide_drives[4].type == IDE_NONE) && (ide_drives[5].type == IDE_NONE))
{
ide_ter_disable();
}
}
void ide_ter_init() void ide_ter_init()
{ {
ide_ter_enable(); ide_ter_enable();
@@ -2154,6 +2189,14 @@ void ide_qua_enable()
io_sethandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); io_sethandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL);
} }
void ide_qua_disable_cond()
{
if ((ide_drives[6].type == IDE_NONE) && (ide_drives[7].type == IDE_NONE))
{
ide_qua_disable();
}
}
void ide_qua_disable() void ide_qua_disable()
{ {
io_removehandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); io_removehandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL);

138
src/mem.c
View File

@@ -948,95 +948,93 @@ int pctrans=0;
extern uint32_t testr[9]; extern uint32_t testr[9];
int mem_cpl3_check()
{
if ((CPL == 3) && !cpl_override)
{
return 1;
}
return 0;
}
/* The relevant page table entry bits are:
0 = P (1 = page is present, 0 = page is not present);
1 = R/W (0 = read-only for user, 1 = writable for user);
2 = U/S (0 = system page, 1 = user page). */
uint32_t mmutranslatereal(uint32_t addr, int rw) uint32_t mmutranslatereal(uint32_t addr, int rw)
{ {
uint32_t addr2; uint32_t pde_addr;
uint32_t temp,temp2,temp3; uint32_t section_flags;
uint32_t temp_section_flags;
if (cpu_state.abrt) uint32_t masked_flags;
{
// pclog("Translate recursive abort\n"); if (cpu_state.abrt)
return -1; {
} // pclog("Translate recursive abort\n");
/* if ((addr&~0xFFFFF)==0x77f00000) pclog("Do translate %08X %i %08X %08X\n",addr,rw,EAX,cpu_state.pc); return -1;
if (addr==0x77f61000) output = 3; }
if (addr==0x77f62000) { dumpregs(); exit(-1); } pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
if (addr==0x77f9a000) { dumpregs(); exit(-1); }*/ section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2];
addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); // if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, section_flags);
temp=temp2=((uint32_t *)ram)[addr2>>2]; if (!(section_flags & 1))// || !(section_flags & 4) && mem_cpl3_check()) || (rw && !(section_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))))
// if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, temp); {
if (!(temp&1))// || (CPL==3 && !(temp&4) && !cpl_override) || (rw && !(temp&2) && (CPL==3 || cr0&WP_FLAG))) // if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,cpu_state.pc,CPL,rw);
cr2 = addr;
section_flags &= 1;
if (CPL==3) section_flags |= 4;
if (rw) section_flags |= 2;
cpu_state.abrt = ABRT_PF;
abrt_error = section_flags;
return -1;
}
section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC))>>2];
masked_flags = section_flags & temp_section_flags;
// if (output == 3) pclog("Do translate %08X %08X\n", section_flags, temp3);
if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))))
{ {
// if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,cpu_state.pc,CPL,rw); // if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,section_flags,opcode,opcode2,frame,rmdat32, CS,cpu_state.pc,SS,ESP,ins,CPL,rw);
cr2=addr; cr2 = addr;
temp&=1; section_flags &= 1;
if (CPL==3) temp|=4; if (CPL==3) section_flags |= 4;
if (rw) temp|=2; if (rw) section_flags |= 2;
cpu_state.abrt = ABRT_PF; cpu_state.abrt = ABRT_PF;
abrt_error = temp; abrt_error = section_flags;
/* if (addr == 0x70046D) // pclog("%04X\n",cpu_state.abrt);
{ return -1;
dumpregs(); }
exit(-1); mmu_perm = section_flags & 4;
}*/ ((uint32_t *)ram)[pde_addr >> 2] |= 0x20;
return -1; ((uint32_t *)ram)[((temp_section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC)) >> 2] |= (rw ? 0x60 : 0x20);
} // /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),section_flags,cs,cpu_state.pc,EDI);
temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2];
temp3=temp&temp2;
// if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3);
if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG)))
{
// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,cpu_state.pc,SS,ESP,ins,CPL,rw);
// dumpregs(); return (section_flags & ~0xFFF) + (addr & 0xFFF);
// exit(-1);
// if (addr == 0x815F6E90) output = 3;
/* if (addr == 0x10ADE020) output = 3;*/
/* if (addr == 0x10150010 && !nopageerrors)
{
dumpregs();
exit(-1);
}*/
cr2=addr;
temp&=1;
if (CPL==3) temp|=4;
if (rw) temp|=2;
cpu_state.abrt = ABRT_PF;
abrt_error = temp;
// pclog("%04X\n",cpu_state.abrt);
return -1;
}
mmu_perm=temp&4;
((uint32_t *)ram)[addr2>>2]|=0x20;
((uint32_t *)ram)[((temp2&~0xFFF)+((addr>>10)&0xFFC))>>2]|=(rw?0x60:0x20);
// /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),temp,cs,cpu_state.pc,EDI);
return (temp&~0xFFF)+(addr&0xFFF);
} }
uint32_t mmutranslate_noabrt(uint32_t addr, int rw) uint32_t mmutranslate_noabrt(uint32_t addr, int rw)
{ {
uint32_t addr2; uint32_t pde_addr;
uint32_t temp,temp2,temp3; uint32_t section_flags;
uint32_t temp_section_flags;
uint32_t masked_flags;
if (cpu_state.abrt) if (cpu_state.abrt)
return -1; return -1;
addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
temp=temp2=((uint32_t *)ram)[addr2>>2]; section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2];
if (!(temp&1)) if (!(section_flags & 1))
return -1; return -1;
temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF)+((addr >> 10) & 0xFFC)) >> 2];
temp3=temp&temp2; masked_flags = section_flags & temp_section_flags;
if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))))
return -1; return -1;
return (temp&~0xFFF)+(addr&0xFFF); return (section_flags & ~0xFFF) + (addr & 0xFFF);
} }
void mmu_invalidate(uint32_t addr) void mmu_invalidate(uint32_t addr)

View File

@@ -293,14 +293,28 @@ BEGIN
END END
MENUITEM "&Status", IDM_STATUS MENUITEM "&Status", IDM_STATUS
#ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_LOG_TOGGLES
#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG
MENUITEM SEPARATOR MENUITEM SEPARATOR
#endif
#ifdef ENABLE_BUSLOGIC_LOG
MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC
#endif
#ifdef ENABLE_CDROM_LOG
MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM
#endif
#ifdef ENABLE_D86F_LOG
MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F
#endif
#ifdef ENABLE_FDC_LOG
MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC
#endif
#ifdef ENABLE_IDE_LOG
MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE
#endif
#ifdef ENABLE_NE2000_LOG
MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000
#endif #endif
#endif
#ifdef ENABLE_LOG_BREAKPOINT #ifdef ENABLE_LOG_BREAKPOINT
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT
@@ -311,13 +325,25 @@ END
MainAccel ACCELERATORS MainAccel ACCELERATORS
BEGIN BEGIN
#ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_LOG_TOGGLES
#ifdef ENABLE_BUSLOGIC_LOG
VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY
#endif
#ifdef ENABLE_CDROM_LOG
VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY
#endif
#ifdef ENABLE_D86F_LOG
VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY
#endif
#ifdef ENABLE_FDC_LOG
VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY
#endif
#ifdef ENABLE_IDE_LOG
VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY
#endif
#ifdef ENABLE_NE2000_LOG
VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY
#endif #endif
#endif
#ifdef ENABLE_LOG_BREAKPOINT #ifdef ENABLE_LOG_BREAKPOINT
VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY
#endif #endif

View File

@@ -188,13 +188,25 @@
#define IDM_SCSI_DMA6 45406 #define IDM_SCSI_DMA6 45406
#define IDM_SCSI_DMA7 45407 #define IDM_SCSI_DMA7 45407
#ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_LOG_TOGGLES
#ifdef ENABLE_BUSLOGIC_LOG
#define IDM_LOG_BUSLOGIC 51200 #define IDM_LOG_BUSLOGIC 51200
#endif
#ifdef ENABLE_CDROM_LOG
#define IDM_LOG_CDROM 51201 #define IDM_LOG_CDROM 51201
#endif
#ifdef ENABLE_D86F_LOG
#define IDM_LOG_D86F 51202 #define IDM_LOG_D86F 51202
#endif
#ifdef ENABLE_FDC_LOG
#define IDM_LOG_FDC 51203 #define IDM_LOG_FDC 51203
#endif
#ifdef ENABLE_IDE_LOG
#define IDM_LOG_IDE 51204 #define IDM_LOG_IDE 51204
#endif
#ifdef ENABLE_NE2000_LOG
#define IDM_LOG_NE2000 51205 #define IDM_LOG_NE2000 51205
#endif #endif
#endif
#ifdef ENABLE_LOG_BREAKPOINT #ifdef ENABLE_LOG_BREAKPOINT
#define IDM_LOG_BREAKPOINT 51206 #define IDM_LOG_BREAKPOINT 51206
#endif #endif

View File

@@ -733,12 +733,24 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
CheckMenuItem(menu, IDM_SCSI_DMA5 - 5 + scsi_dma, MF_CHECKED); CheckMenuItem(menu, IDM_SCSI_DMA5 - 5 + scsi_dma, MF_CHECKED);
#ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_LOG_TOGGLES
#ifdef ENABLE_BUSLOGIC_LOG
CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED);
#endif
#ifdef ENABLE_CDROM_LOG
CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED);
#endif
#ifdef ENABLE_D86F_LOG
CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED);
#endif
#ifdef ENABLE_FDC_LOG
CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED);
#endif
#ifdef ENABLE_IDE_LOG
CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED);
#endif
#ifdef ENABLE_NE2000_LOG
CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED);
#endif
#endif #endif
CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED);
@@ -1510,36 +1522,48 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
break; break;
#ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_LOG_TOGGLES
#ifdef ENABLE_BUSLOGIC_LOG
case IDM_LOG_BUSLOGIC: case IDM_LOG_BUSLOGIC:
buslogic_do_log ^= 1; buslogic_do_log ^= 1;
CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED);
break; break;
#endif
#ifdef ENABLE_CDROM_LOG
case IDM_LOG_CDROM: case IDM_LOG_CDROM:
cdrom_do_log ^= 1; cdrom_do_log ^= 1;
CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED);
break; break;
#endif
#ifdef ENABLE_D86F_LOG
case IDM_LOG_D86F: case IDM_LOG_D86F:
d86f_do_log ^= 1; d86f_do_log ^= 1;
CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED);
break; break;
#endif
#ifdef ENABLE_FDC_LOG
case IDM_LOG_FDC: case IDM_LOG_FDC:
fdc_do_log ^= 1; fdc_do_log ^= 1;
CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED);
break; break;
#endif
#ifdef ENABLE_IDE_LOG
case IDM_LOG_IDE: case IDM_LOG_IDE:
ide_do_log ^= 1; ide_do_log ^= 1;
CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED);
break; break;
#endif
#ifdef ENABLE_NE2000_LOG
case IDM_LOG_NE2000: case IDM_LOG_NE2000:
ne2000_do_log ^= 1; ne2000_do_log ^= 1;
CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED);
break; break;
#endif #endif
#endif
#ifdef ENABLE_LOG_BREAKPOINT #ifdef ENABLE_LOG_BREAKPOINT
case IDM_LOG_BREAKPOINT: case IDM_LOG_BREAKPOINT: