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:
@@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9
|
||||
|
||||
86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ)
|
||||
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS)
|
||||
sleep 10
|
||||
sleep 2
|
||||
strip "86Box.exe"
|
||||
sleep 10
|
||||
sleep 2
|
||||
|
||||
all : 86Box.exe
|
||||
|
||||
|
@@ -1706,6 +1706,7 @@ void *BuslogicInit()
|
||||
|
||||
io_sethandler(scsi_base, 0x0004, BuslogicRead, NULL, NULL, BuslogicWrite, NULL, NULL, Buslogic);
|
||||
|
||||
BuslogicLog("Building CD-ROM map...\n");
|
||||
build_scsi_cdrom_map();
|
||||
|
||||
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id))
|
||||
|
62
src/cdrom.c
62
src/cdrom.c
@@ -304,6 +304,7 @@ void cdrom_init(int id, int cdb_len_setting, int bus_type)
|
||||
cdrom[id].sense[0] = 0xf0;
|
||||
cdrom[id].sense[7] = 10;
|
||||
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)
|
||||
{
|
||||
cdrom_set_signature(id);
|
||||
@@ -772,7 +773,26 @@ static void cdrom_command_common(uint8_t id)
|
||||
cdrom[id].status = BUSY_STAT;
|
||||
cdrom[id].phase = 1;
|
||||
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)
|
||||
@@ -807,6 +827,15 @@ static void cdrom_command_write_dma(uint8_t 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -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_is_media_access(id))
|
||||
{
|
||||
SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len;
|
||||
}
|
||||
SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len;
|
||||
}
|
||||
if (direction == 0)
|
||||
{
|
||||
@@ -1150,7 +1172,7 @@ int cdrom_read_blocks(uint8_t id, int *len, int first_batch)
|
||||
if (!cdrom[id].sector_len)
|
||||
{
|
||||
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);
|
||||
@@ -1754,7 +1776,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
}
|
||||
|
||||
ret = cdrom_read_blocks(id, &alloc_length, 1);
|
||||
if (!ret)
|
||||
if (ret <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2465,13 +2487,20 @@ int cdrom_block_check(uint8_t id)
|
||||
if (cdrom_is_media_access(id))
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
cdrom_log("CD-ROM %i: %i bytes read, current block finished\n", id, cdrom[id].total_read);
|
||||
/* Read the next block. */
|
||||
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. */
|
||||
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[id].status = READY_STAT;
|
||||
cdrom[id].phase = 3;
|
||||
cdrom[id].packet_status = 0xFF;
|
||||
return 1;
|
||||
case CDROM_PHASE_DATA_OUT:
|
||||
// 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 (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)
|
||||
{
|
||||
/* 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: 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;
|
||||
}
|
||||
else
|
||||
|
159
src/ide.c
159
src/ide.c
@@ -59,8 +59,10 @@
|
||||
#define WIN_READ_DMA 0xC8
|
||||
#define WIN_WRITE_DMA 0xCA
|
||||
#define WIN_STANDBYNOW1 0xE0
|
||||
#define WIN_IDLENOW1 0xE1
|
||||
#define WIN_SETIDLE1 0xE3
|
||||
#define WIN_CHECKPOWERMODE1 0xE5
|
||||
#define WIN_SLEEP1 0xE6
|
||||
#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */
|
||||
#define WIN_SET_FEATURES 0xEF
|
||||
#define WIN_READ_NATIVE_MAX 0xF8
|
||||
@@ -373,8 +375,11 @@ static void ide_identify(IDE *ide)
|
||||
// ide->buffer[63] = 7; /*Multiword DMA*/
|
||||
if (ide->board < 2)
|
||||
{
|
||||
ide->buffer[53] = 2;
|
||||
ide->buffer[62] = ide->dma_identify_data[0];
|
||||
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[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->buffer[49] = 0x200; /* LBA supported */
|
||||
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))
|
||||
{
|
||||
ide->buffer[49] |= 0x100; /* DMA supported */
|
||||
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
||||
ide->buffer[53] = 2;
|
||||
ide->buffer[62] = ide->dma_identify_data[0];
|
||||
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)
|
||||
{
|
||||
uint8_t cdrom_id = cur_ide[ide->board];
|
||||
|
||||
uint8_t features = 0;
|
||||
|
||||
uint8_t sf_data = 0;
|
||||
uint8_t val = 0;
|
||||
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
val = cdrom[cdrom_id].phase & 7;
|
||||
features = cdrom[cdrom_id].features;
|
||||
sf_data = cdrom[cdrom_id].phase;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = ide->secount & 7;
|
||||
features = ide->cylprecomp;
|
||||
sf_data = ide->secount;
|
||||
}
|
||||
|
||||
val = sf_data & 7;
|
||||
|
||||
if (ide->type == IDE_NONE) return 0;
|
||||
|
||||
switch(ide->cylprecomp)
|
||||
switch(features)
|
||||
{
|
||||
case 0x02:
|
||||
case 0x82:
|
||||
@@ -612,17 +630,21 @@ int ide_set_features(IDE *ide)
|
||||
case 0xc2:
|
||||
return 1;
|
||||
case 0x03:
|
||||
#if 0
|
||||
if (ide->type == IDE_CDROM)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch(ide->secount >> 3)
|
||||
#endif
|
||||
switch(sf_data >> 3)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
ide->dma_identify_data[0] = ide->dma_identify_data[1] = 7;
|
||||
ide->dma_identify_data[2] = 0x3f;
|
||||
break;
|
||||
case 1:
|
||||
/* We do not (yet) emulate flow control, so return with error if this is attempted. */
|
||||
return 0;
|
||||
case 2:
|
||||
if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2))
|
||||
{
|
||||
@@ -722,6 +744,9 @@ void resetide(void)
|
||||
{
|
||||
cur_ide[d] = d << 1;
|
||||
}
|
||||
|
||||
ide_ter_disable_cond();
|
||||
ide_qua_disable_cond();
|
||||
}
|
||||
|
||||
int idetimes = 0;
|
||||
@@ -741,9 +766,6 @@ void ide_write_data(int ide_board, uint8_t val)
|
||||
#endif
|
||||
|
||||
// ide_log("Write IDEw %04X\n",val);
|
||||
idebufferb[ide->pos] = val;
|
||||
ide->pos++;
|
||||
|
||||
if (ide->command == WIN_PACKETCMD)
|
||||
{
|
||||
if (!ide_drive_is_cdrom(ide))
|
||||
@@ -761,6 +783,9 @@ void ide_write_data(int ide_board, uint8_t val)
|
||||
}
|
||||
else
|
||||
{
|
||||
idebufferb[ide->pos] = val;
|
||||
ide->pos++;
|
||||
|
||||
if (ide->pos>=512)
|
||||
{
|
||||
ide->pos=0;
|
||||
@@ -962,19 +987,31 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
||||
case 0x1F7: /* Command register */
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
ide->error=1;
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
cdrom[atapi_cdrom_drives[ide->channel]].error = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
if (ide_drive_is_cdrom(ide_other))
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
#if 0
|
||||
ide_log("Write CD-ROM ATA command: %02X\n", val);
|
||||
}
|
||||
#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->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_NOP:
|
||||
case WIN_STANDBYNOW1:
|
||||
case WIN_IDLENOW1:
|
||||
case WIN_SETIDLE1: /* Idle */
|
||||
case WIN_CHECKPOWERMODE1:
|
||||
case WIN_SLEEP1:
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
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;
|
||||
|
||||
temp = idebufferb[ide->pos];
|
||||
|
||||
ide->pos++;
|
||||
|
||||
if (ide->command == WIN_PACKETCMD)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = idebufferb[ide->pos];
|
||||
ide->pos++;
|
||||
}
|
||||
if (ide->pos>=512 && ide->command != WIN_PACKETCMD)
|
||||
{
|
||||
ide->pos=0;
|
||||
@@ -1324,19 +1364,6 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
addr|=0x90;
|
||||
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)
|
||||
{
|
||||
case 0x1F0: /* Data */
|
||||
@@ -1349,7 +1376,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
case 0x1F1: /* Error */
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = 1;
|
||||
temp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1378,32 +1405,18 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
0 1 0 Data from host
|
||||
1 0 1 Status. */
|
||||
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
|
||||
{
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = ide->secount;
|
||||
}
|
||||
temp = ide->secount;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1F3: /* Sector */
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (uint8_t)ide->sector;
|
||||
}
|
||||
temp = (uint8_t)ide->sector;
|
||||
break;
|
||||
|
||||
case 0x1F4: /* Cylinder low */
|
||||
@@ -1443,7 +1456,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
break;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1457,6 +1470,10 @@ uint8_t readide(int ide_board, uint16_t addr)
|
||||
DF (drive fault). */
|
||||
case 0x1F7: /* Status */
|
||||
ide_irq_lower(ide);
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
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 */
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
temp = DSC_STAT;
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
@@ -1614,6 +1630,7 @@ void callbackide(int ide_board)
|
||||
}
|
||||
case WIN_NOP:
|
||||
case WIN_STANDBYNOW1:
|
||||
case WIN_IDLENOW1:
|
||||
case WIN_SETIDLE1:
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
@@ -1627,9 +1644,11 @@ void callbackide(int ide_board)
|
||||
return;
|
||||
|
||||
case WIN_CHECKPOWERMODE1:
|
||||
case WIN_SLEEP1:
|
||||
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->atastat = READY_STAT | DSC_STAT;
|
||||
@@ -1854,10 +1873,13 @@ void callbackide(int ide_board)
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
cdrom[cdrom_id].status = 0;
|
||||
cdrom[cdrom_id].error = 1;
|
||||
ide_irq_raise(ide);
|
||||
}
|
||||
else
|
||||
{
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
ide->error = 1;
|
||||
ide_irq_raise(ide);
|
||||
}
|
||||
return;
|
||||
@@ -1930,6 +1952,8 @@ void callbackide(int ide_board)
|
||||
if (ide->type == IDE_NONE)
|
||||
{
|
||||
ide_set_signature(ide);
|
||||
cdrom[cdrom_id].status = READY_STAT | ERR_STAT | DSC_STAT;
|
||||
cdrom[cdrom_id].pos = 0;
|
||||
goto abort_cmd;
|
||||
}
|
||||
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;
|
||||
ide_log("IDE callback now: %i\n", idecallback[ide_board]);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0xFF:
|
||||
goto abort_cmd;
|
||||
}
|
||||
|
||||
abort_cmd:
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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
138
src/mem.c
@@ -948,95 +948,93 @@ int pctrans=0;
|
||||
|
||||
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 addr2;
|
||||
uint32_t temp,temp2,temp3;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
// pclog("Translate recursive abort\n");
|
||||
return -1;
|
||||
}
|
||||
/* if ((addr&~0xFFFFF)==0x77f00000) pclog("Do translate %08X %i %08X %08X\n",addr,rw,EAX,cpu_state.pc);
|
||||
if (addr==0x77f61000) output = 3;
|
||||
if (addr==0x77f62000) { dumpregs(); exit(-1); }
|
||||
if (addr==0x77f9a000) { dumpregs(); exit(-1); }*/
|
||||
addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
temp=temp2=((uint32_t *)ram)[addr2>>2];
|
||||
// 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)))
|
||||
uint32_t pde_addr;
|
||||
uint32_t section_flags;
|
||||
uint32_t temp_section_flags;
|
||||
uint32_t masked_flags;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
// pclog("Translate recursive abort\n");
|
||||
return -1;
|
||||
}
|
||||
pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2];
|
||||
// if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, section_flags);
|
||||
if (!(section_flags & 1))// || !(section_flags & 4) && mem_cpl3_check()) || (rw && !(section_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);
|
||||
|
||||
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;
|
||||
temp&=1;
|
||||
if (CPL==3) temp|=4;
|
||||
if (rw) temp|=2;
|
||||
cpu_state.abrt = ABRT_PF;
|
||||
abrt_error = temp;
|
||||
/* if (addr == 0x70046D)
|
||||
{
|
||||
dumpregs();
|
||||
exit(-1);
|
||||
}*/
|
||||
return -1;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
// pclog("%04X\n",cpu_state.abrt);
|
||||
return -1;
|
||||
}
|
||||
mmu_perm = section_flags & 4;
|
||||
((uint32_t *)ram)[pde_addr >> 2] |= 0x20;
|
||||
((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);
|
||||
|
||||
// dumpregs();
|
||||
// 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);
|
||||
return (section_flags & ~0xFFF) + (addr & 0xFFF);
|
||||
}
|
||||
|
||||
uint32_t mmutranslate_noabrt(uint32_t addr, int rw)
|
||||
{
|
||||
uint32_t addr2;
|
||||
uint32_t temp,temp2,temp3;
|
||||
uint32_t pde_addr;
|
||||
uint32_t section_flags;
|
||||
uint32_t temp_section_flags;
|
||||
uint32_t masked_flags;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
return -1;
|
||||
|
||||
addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
temp=temp2=((uint32_t *)ram)[addr2>>2];
|
||||
pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2];
|
||||
|
||||
if (!(temp&1))
|
||||
if (!(section_flags & 1))
|
||||
return -1;
|
||||
|
||||
temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2];
|
||||
temp3=temp&temp2;
|
||||
section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF)+((addr >> 10) & 0xFFC)) >> 2];
|
||||
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 (temp&~0xFFF)+(addr&0xFFF);
|
||||
return (section_flags & ~0xFFF) + (addr & 0xFFF);
|
||||
}
|
||||
|
||||
void mmu_invalidate(uint32_t addr)
|
||||
|
26
src/pc.rc
26
src/pc.rc
@@ -293,14 +293,28 @@ BEGIN
|
||||
END
|
||||
MENUITEM "&Status", IDM_STATUS
|
||||
#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
|
||||
#endif
|
||||
#ifdef ENABLE_BUSLOGIC_LOG
|
||||
MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC
|
||||
#endif
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
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
|
||||
#endif
|
||||
#ifdef ENABLE_FDC_LOG
|
||||
MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC
|
||||
#endif
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE
|
||||
#endif
|
||||
#ifdef ENABLE_NE2000_LOG
|
||||
MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ENABLE_LOG_BREAKPOINT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT
|
||||
@@ -311,13 +325,25 @@ END
|
||||
MainAccel ACCELERATORS
|
||||
BEGIN
|
||||
#ifdef ENABLE_LOG_TOGGLES
|
||||
#ifdef ENABLE_BUSLOGIC_LOG
|
||||
VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_D86F_LOG
|
||||
VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_FDC_LOG
|
||||
VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_NE2000_LOG
|
||||
VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ENABLE_LOG_BREAKPOINT
|
||||
VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY
|
||||
#endif
|
||||
|
@@ -188,13 +188,25 @@
|
||||
#define IDM_SCSI_DMA6 45406
|
||||
#define IDM_SCSI_DMA7 45407
|
||||
#ifdef ENABLE_LOG_TOGGLES
|
||||
#ifdef ENABLE_BUSLOGIC_LOG
|
||||
#define IDM_LOG_BUSLOGIC 51200
|
||||
#endif
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
#define IDM_LOG_CDROM 51201
|
||||
#endif
|
||||
#ifdef ENABLE_D86F_LOG
|
||||
#define IDM_LOG_D86F 51202
|
||||
#endif
|
||||
#ifdef ENABLE_FDC_LOG
|
||||
#define IDM_LOG_FDC 51203
|
||||
#endif
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
#define IDM_LOG_IDE 51204
|
||||
#endif
|
||||
#ifdef ENABLE_NE2000_LOG
|
||||
#define IDM_LOG_NE2000 51205
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ENABLE_LOG_BREAKPOINT
|
||||
#define IDM_LOG_BREAKPOINT 51206
|
||||
#endif
|
||||
|
24
src/win.c
24
src/win.c
@@ -733,12 +733,24 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
||||
CheckMenuItem(menu, IDM_SCSI_DMA5 - 5 + scsi_dma, MF_CHECKED);
|
||||
|
||||
#ifdef ENABLE_LOG_TOGGLES
|
||||
#ifdef ENABLE_BUSLOGIC_LOG
|
||||
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);
|
||||
#endif
|
||||
#ifdef ENABLE_D86F_LOG
|
||||
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);
|
||||
#endif
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
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);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
#ifdef ENABLE_LOG_TOGGLES
|
||||
#ifdef ENABLE_BUSLOGIC_LOG
|
||||
case IDM_LOG_BUSLOGIC:
|
||||
buslogic_do_log ^= 1;
|
||||
CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
case IDM_LOG_CDROM:
|
||||
cdrom_do_log ^= 1;
|
||||
CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_D86F_LOG
|
||||
case IDM_LOG_D86F:
|
||||
d86f_do_log ^= 1;
|
||||
CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FDC_LOG
|
||||
case IDM_LOG_FDC:
|
||||
fdc_do_log ^= 1;
|
||||
CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
case IDM_LOG_IDE:
|
||||
ide_do_log ^= 1;
|
||||
CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NE2000_LOG
|
||||
case IDM_LOG_NE2000:
|
||||
ne2000_do_log ^= 1;
|
||||
CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_LOG_BREAKPOINT
|
||||
case IDM_LOG_BREAKPOINT:
|
||||
|
Reference in New Issue
Block a user