From 6b86549b7ec92a3dd7c61d0b83f4ea4dfb5dcadd Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 19:41:42 +0100 Subject: [PATCH] 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. --- src/Makefile.mingw | 4 +- src/buslogic.c | 1 + src/cdrom.c | 62 +++++++++++++----- src/ide.c | 159 ++++++++++++++++++++++++++++----------------- src/mem.c | 138 +++++++++++++++++++-------------------- src/pc.rc | 26 ++++++++ src/resources.h | 12 ++++ src/win.c | 24 +++++++ 8 files changed, 280 insertions(+), 146 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index f7032d7d0..371cb1713 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -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 diff --git a/src/buslogic.c b/src/buslogic.c index f0948bc4c..c7d121606 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -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)) diff --git a/src/cdrom.c b/src/cdrom.c index bf5d7da7c..3e9e30d22 100644 --- a/src/cdrom.c +++ b/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 diff --git a/src/ide.c b/src/ide.c index 4d24a1314..c0d98f3a6 100644 --- a/src/ide.c +++ b/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); diff --git a/src/mem.c b/src/mem.c index acc1280cf..8c16fd33e 100644 --- a/src/mem.c +++ b/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) diff --git a/src/pc.rc b/src/pc.rc index 925da15fc..c90783586 100644 --- a/src/pc.rc +++ b/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 diff --git a/src/resources.h b/src/resources.h index 931b5a8b0..0c70ea07b 100644 --- a/src/resources.h +++ b/src/resources.h @@ -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 diff --git a/src/win.c b/src/win.c index ccfc70858..921102401 100644 --- a/src/win.c +++ b/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: