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)
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS)
sleep 10
sleep 2
strip "86Box.exe"
sleep 10
sleep 2
all : 86Box.exe

View File

@@ -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))

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[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
View File

@@ -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
View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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: