From 1f11f9f9a145f74fb8bc8e43b4eeb6ca36f876b8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 15 Mar 2018 23:32:07 +0100 Subject: [PATCH 1/3] IDE buffers are now allocated on IDE reset, only for attached devices (and sector buffers only for hard disks). --- src/disk/hdc_ide.c | 50 ++++++++++++++++++++++++++++++++++++++-------- src/disk/hdc_ide.h | 7 ++++--- src/pc.c | 4 +++- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 3d572d035..b2743528b 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.33 2018/03/15 + * Version: @(#)hdc_ide.c 1.0.34 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -20,10 +20,11 @@ #define __USE_LARGEFILE64 #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE +#include #include #include +#include #include -#include #include #include #define HAVE_STDARG_H @@ -793,6 +794,24 @@ void ide_ter_disable_cond(); void ide_qua_disable_cond(); +void ide_destroy_buffers(void) +{ + int d; + + for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++) + { + if (ide_drives[d].buffer) { + free(ide_drives[d].buffer); + ide_drives[d].buffer = NULL; + } + + if (ide_drives[d].sector_buffer) { + free(ide_drives[d].sector_buffer); + ide_drives[d].sector_buffer = NULL; + } + } +} + void ide_reset(void) { int c, d; @@ -818,8 +837,18 @@ void ide_reset(void) ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; ide_drives[d].board = d >> 1; + + if (ide_drives[d].buffer) { + free(ide_drives[d].buffer); + ide_drives[d].buffer = NULL; + } + + if (ide_drives[d].sector_buffer) { + free(ide_drives[d].sector_buffer); + ide_drives[d].sector_buffer = NULL; + } } - + idecallback[0]=idecallback[1]=0LL; idecallback[2]=idecallback[3]=0LL; idecallback[4]=0LL; @@ -832,12 +861,16 @@ void ide_reset(void) { ide_log("Found IDE hard disk on channel %i\n", hdd[d].ide_channel); loadhd(&ide_drives[hdd[d].ide_channel], d, hdd[d].fn); + ide_drives[hdd[d].ide_channel].sector_buffer = NULL; /* Important, makes sure malloc does not reuse an existing pointer from elsewhere. */ + ide_drives[hdd[d].ide_channel].sector_buffer = (uint8_t *) malloc(256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } if ((hdd[d].bus==HDD_BUS_XTIDE) && (hdd[d].xtide_channel < XTIDE_NUM)) { ide_log("Found XT IDE hard disk on channel %i\n", hdd[d].xtide_channel); loadhd(&ide_drives[hdd[d].xtide_channel | 8], d, hdd[d].fn); + ide_drives[hdd[d].xtide_channel | 8].sector_buffer = NULL; /* Important, makes sure malloc does not reuse an existing pointer from elsewhere. */ + ide_drives[hdd[d].xtide_channel | 8].sector_buffer = (uint8_t *) malloc(256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } } @@ -845,13 +878,14 @@ void ide_reset(void) for (d = 0; d < IDE_NUM; d++) { - if (ide_drive_is_zip(&ide_drives[d]) && (ide_drives[d].type != IDE_HDD)) - { + if (ide_drive_is_zip(&ide_drives[d]) && (ide_drives[d].type == IDE_NONE)) ide_drives[d].type = IDE_ZIP; - } - else if (ide_drive_is_cdrom(&ide_drives[d]) && (ide_drives[d].type != IDE_HDD)) - { + else if (ide_drive_is_cdrom(&ide_drives[d]) && (ide_drives[d].type == IDE_NONE)) ide_drives[d].type = IDE_CDROM; + + if (ide_drives[d].type != IDE_NONE) { + ide_drives[d].buffer = NULL; /* Important, makes sure malloc does not reuse an existing pointer from elsewhere. */ + ide_drives[d].buffer = (uint16_t *) malloc(65536); } ide_set_signature(&ide_drives[d]); diff --git a/src/disk/hdc_ide.h b/src/disk/hdc_ide.h index ce3cd8436..74e938b2e 100644 --- a/src/disk/hdc_ide.h +++ b/src/disk/hdc_ide.h @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdd_ide.h 1.0.6 2018/02/14 + * Version: @(#)hdd_ide.h 1.0.7 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -36,7 +36,7 @@ typedef struct { int packetstatus; uint8_t asc; int reset; - uint16_t buffer[65536]; + uint16_t *buffer; int irqstat; int service; int lba; @@ -49,7 +49,7 @@ typedef struct { int hdd_num; uint8_t specify_success; int mdma_mode; - uint8_t sector_buffer[256*512]; + uint8_t *sector_buffer; int do_initial_read; int sector_pos; } IDE; @@ -104,6 +104,7 @@ extern void ide_set_callback(uint8_t channel, int64_t callback); extern void secondary_ide_check(void); extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src); +extern void ide_destroy_buffers(void); extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); diff --git a/src/pc.c b/src/pc.c index 8ec023651..3aec78258 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.63 2018/03/13 + * Version: @(#)pc.c 1.0.64 2018/03/15 * * Authors: Sarah Walker, * Miran Grca, @@ -968,6 +968,8 @@ pc_close(thread_t *ptr) sound_cd_thread_end(); mem_destroy_pages(); + + ide_destroy_buffers(); } From 78515537efb7791ad8a448d69bd08916d31bb8cd Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Mar 2018 00:08:43 +0100 Subject: [PATCH 2/3] Changed the way PS/2 Model 80 split mapping is handled (but OS/2 2.x still runs on it); The pages array are no longer allocated for the entire memory of space if memory size + 384 is above 16 MB (turns out it was not needed at all), further significantly reduces the emulator's RAM usage; Made greatpsycho's revised SVGA status handling specific to ATI cards, while the generic (S)VGA code uses the old handling - fixes error 2401 on PS/2 Model 80. --- src/machine/m_ps2_mca.c | 63 +++++++++++++++++++++++++++++--- src/mem.c | 75 ++++---------------------------------- src/mem.h | 3 -- src/video/vid_ati18800.c | 35 +++++++++++++++++- src/video/vid_ati28800.c | 35 +++++++++++++++++- src/video/vid_ati_mach64.c | 35 +++++++++++++++++- src/video/vid_svga.c | 34 +---------------- 7 files changed, 167 insertions(+), 113 deletions(-) diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index e9c74935a..f85a06c0b 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -40,8 +40,9 @@ static struct uint8_t io_id; mem_mapping_t shadow_mapping; + mem_mapping_t split_mapping; mem_mapping_t expansion_mapping; - mem_mapping_t cache_mapping; + mem_mapping_t cache_mapping; uint8_t (*planar_read)(uint16_t port); void (*planar_write)(uint16_t port, uint8_t val); @@ -49,11 +50,12 @@ static struct uint8_t mem_regs[3]; uint32_t split_addr, split_size; + uint32_t split_phys; uint8_t mem_pos_regs[8]; uint8_t mem_2mb_pos_regs[8]; - int pending_cache_miss; + int pending_cache_miss; } ps2; /*The model 70 type 3/4 BIOS performs cache testing. Since 86Box doesn't have any @@ -173,6 +175,37 @@ static void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv) mem_write_raml(addr, val, priv); } +static uint8_t ps2_read_split_ram(uint32_t addr, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + return mem_read_ram(addr, priv); +} +static uint16_t ps2_read_split_ramw(uint32_t addr, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + return mem_read_ramw(addr, priv); +} +static uint32_t ps2_read_split_raml(uint32_t addr, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + return mem_read_raml(addr, priv); +} +static void ps2_write_split_ram(uint32_t addr, uint8_t val, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + mem_write_ram(addr, val, priv); +} +static void ps2_write_split_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + mem_write_ramw(addr, val, priv); +} +static void ps2_write_split_raml(uint32_t addr, uint32_t val, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + mem_write_raml(addr, val, priv); +} + #define PS2_SETUP_IO 0x80 #define PS2_SETUP_VGA 0x20 @@ -839,7 +872,7 @@ static void ps2_mca_board_model_55sx_init() static void mem_encoding_update() { - mem_split_disable(ps2.split_size, ps2.split_addr); + mem_mapping_disable(&ps2.split_mapping); ps2.split_addr = ((uint32_t) (ps2.mem_regs[0] & 0xf)) << 20; @@ -861,12 +894,16 @@ static void mem_encoding_update() if (!(ps2.mem_regs[1] & 8)) { - if (ps2.mem_regs[1] & 4) + if (ps2.mem_regs[1] & 4) { ps2.split_size = 384; - else + ps2.split_phys = 0x80000; + } else { ps2.split_size = 256; + ps2.split_phys = 0xa0000; + } - mem_split_enable(ps2.split_size, ps2.split_addr); + mem_mapping_set_exec(&ps2.split_mapping, &ram[ps2.split_phys]); + mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, ps2.split_size << 10); /* pclog("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr); */ } /* else { @@ -1108,6 +1145,20 @@ static void ps2_mca_board_model_80_type2_init(int is486) ps2.mem_regs[0] |= ((mem_size/1024) & 0x0f); + mem_mapping_add(&ps2.split_mapping, + (mem_size+256) * 1024, + 256*1024, + ps2_read_split_ram, + ps2_read_split_ramw, + ps2_read_split_raml, + ps2_write_split_ram, + ps2_write_split_ramw, + ps2_write_split_raml, + &ram[0xa0000], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.split_mapping); + if ((mem_size > 4096) && !is486) { /* Only 4 MB supported on planar, create a memory expansion card for the rest */ diff --git a/src/mem.c b/src/mem.c index 7bb2a12bc..cbd3fe165 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1334,13 +1334,16 @@ void mem_resize_pages(void) if (AT) { if (cpu_16bitbus) total_size = 4096; - else - total_size = 1048576; + else { + total_size = (mem_size + 384) >> 2; + if ((total_size << 2) < (mem_size + 384)) + total_size++; + if (total_size < 4096) + total_size = 4096; + } } else total_size = 256; - pclog("%i pages\n", total_size); - pages = malloc(total_size * sizeof(page_t)); memset(pages, 0, total_size * sizeof(page_t)); @@ -1469,70 +1472,6 @@ void mem_remap_top_384k() mem_remap_top(384); } -void mem_split_enable(int max_size, uint32_t addr) -{ - int c; - - uint8_t *mem_split_buffer = &ram[0x80000]; - - if (split_mapping_enabled) - return; - -#if 0 - pclog("Split mapping enable at %08X\n", addr); -#endif - - mem_set_mem_state(addr, max_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_set_addr(&ram_split_mapping, addr, max_size * 1024); - mem_mapping_set_exec(&ram_split_mapping, &ram[addr]); - - if (max_size == 384) - memcpy(&ram[addr], mem_split_buffer, max_size); - else - memcpy(&ram[addr], &mem_split_buffer[128 * 1024], max_size); - - for (c = ((addr / 1024) / 64); c < (((addr / 1024) + max_size - 1) / 64); c++) - { - isram[c] = 1; - } - - flushmmucache(); - - split_mapping_enabled = 1; -} - -void mem_split_disable(int max_size, uint32_t addr) -{ - int c; - - uint8_t *mem_split_buffer = &ram[0x80000]; - - if (!split_mapping_enabled) - return; - -#if 0 - pclog("Split mapping disable at %08X\n", addr); -#endif - - if (max_size == 384) - memcpy(mem_split_buffer, &ram[addr], max_size); - else - memcpy(&mem_split_buffer[128 * 1024], &ram[addr], max_size); - - mem_mapping_disable(&ram_split_mapping); - mem_set_mem_state(addr, max_size * 1024, 0); - mem_mapping_set_exec(&ram_split_mapping, NULL); - - for (c = ((addr / 1024) / 64); c < (((addr / 1024) + max_size - 1) / 64); c++) - { - isram[c] = 0; - } - - flushmmucache(); - - split_mapping_enabled = 0; -} - void mem_resize() { int c; diff --git a/src/mem.h b/src/mem.h index e31b3b1b2..f7f488435 100644 --- a/src/mem.h +++ b/src/mem.h @@ -231,9 +231,6 @@ extern void flushmmucache_cr3(void); extern void flushmmucache_nopc(void); extern void mmu_invalidate(uint32_t addr); -extern void mem_split_enable(int max_size, uint32_t addr); -extern void mem_split_disable(int max_size, uint32_t addr); - extern void mem_add_bios(void); diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 3c047dc7d..2081f0786 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -8,7 +8,7 @@ * * ATI 18800 emulation (VGA Edge-16) * - * Version: @(#)vid_ati18800.c 1.0.6 2018/03/15 + * Version: @(#)vid_ati18800.c 1.0.7 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -150,6 +150,39 @@ static uint8_t ati18800_in(uint16_t addr, void *p) case 0x3D5: temp = svga->crtc[svga->crtcreg]; break; + case 0x3DA: + svga->attrff = 0; + svga->attrff = 0; + svga->cgastat &= ~0x30; + /* copy color diagnostic info from the overscan color register */ + switch (svga->attrregs[0x12] & 0x30) + { + case 0x00: /* P0 and P2 */ + if (svga->attrregs[0x11] & 0x01) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x04) + svga->cgastat |= 0x20; + break; + case 0x10: /* P4 and P5 */ + if (svga->attrregs[0x11] & 0x10) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x20) + svga->cgastat |= 0x20; + break; + case 0x20: /* P1 and P3 */ + if (svga->attrregs[0x11] & 0x02) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x08) + svga->cgastat |= 0x20; + break; + case 0x30: /* P6 and P7 */ + if (svga->attrregs[0x11] & 0x40) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x80) + svga->cgastat |= 0x20; + break; + } + return svga->cgastat; default: temp = svga_in(addr, svga); break; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 7c6b64a51..0a1a0337d 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,7 +8,7 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.11 2018/03/15 + * Version: @(#)vid_ati28800.c 1.0.12 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -246,6 +246,39 @@ static uint8_t ati28800_in(uint16_t addr, void *p) case 0x3D5: temp = svga->crtc[svga->crtcreg]; break; + case 0x3DA: + svga->attrff = 0; + svga->attrff = 0; + svga->cgastat &= ~0x30; + /* copy color diagnostic info from the overscan color register */ + switch (svga->attrregs[0x12] & 0x30) + { + case 0x00: /* P0 and P2 */ + if (svga->attrregs[0x11] & 0x01) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x04) + svga->cgastat |= 0x20; + break; + case 0x10: /* P4 and P5 */ + if (svga->attrregs[0x11] & 0x10) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x20) + svga->cgastat |= 0x20; + break; + case 0x20: /* P1 and P3 */ + if (svga->attrregs[0x11] & 0x02) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x08) + svga->cgastat |= 0x20; + break; + case 0x30: /* P6 and P7 */ + if (svga->attrregs[0x11] & 0x40) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x80) + svga->cgastat |= 0x20; + break; + } + return svga->cgastat; default: temp = svga_in(addr, svga); break; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index d8478bfdf..3b349c635 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -8,7 +8,7 @@ * * ATi Mach64 graphics card emulation. * - * Version: @(#)vid_ati_mach64.c 1.0.15 2018/03/13 + * Version: @(#)vid_ati_mach64.c 1.0.16 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -429,6 +429,39 @@ uint8_t mach64_in(uint16_t addr, void *p) if (svga->crtcreg > 0x18) return 0xff; return svga->crtc[svga->crtcreg]; + case 0x3DA: + svga->attrff = 0; + svga->attrff = 0; + svga->cgastat &= ~0x30; + /* copy color diagnostic info from the overscan color register */ + switch (svga->attrregs[0x12] & 0x30) + { + case 0x00: /* P0 and P2 */ + if (svga->attrregs[0x11] & 0x01) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x04) + svga->cgastat |= 0x20; + break; + case 0x10: /* P4 and P5 */ + if (svga->attrregs[0x11] & 0x10) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x20) + svga->cgastat |= 0x20; + break; + case 0x20: /* P1 and P3 */ + if (svga->attrregs[0x11] & 0x02) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x08) + svga->cgastat |= 0x20; + break; + case 0x30: /* P6 and P7 */ + if (svga->attrregs[0x11] & 0x40) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x80) + svga->cgastat |= 0x20; + break; + } + return svga->cgastat; } return svga_in(addr, svga); } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 92b17be32..7299949b0 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.25 2018/03/12 + * Version: @(#)vid_svga.c 1.0.26 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -295,43 +295,11 @@ uint8_t svga_in(uint16_t addr, void *p) svga->attrff = 0; svga->attrff = 0; - /* old diagnostic code if (svga->cgastat & 0x01) svga->cgastat &= ~0x30; else svga->cgastat ^= 0x30; return svga->cgastat; - */ - svga->cgastat &= ~0x30; - /* copy color diagnostic info from the overscan color register */ - switch (svga->attrregs[0x12] & 0x30) - { - case 0x00: /* P0 and P2 */ - if (svga->attrregs[0x11] & 0x01) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x04) - svga->cgastat |= 0x20; - break; - case 0x10: /* P4 and P5 */ - if (svga->attrregs[0x11] & 0x10) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x20) - svga->cgastat |= 0x20; - break; - case 0x20: /* P1 and P3 */ - if (svga->attrregs[0x11] & 0x02) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x08) - svga->cgastat |= 0x20; - break; - case 0x30: /* P6 and P7 */ - if (svga->attrregs[0x11] & 0x40) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x80) - svga->cgastat |= 0x20; - break; - } - return svga->cgastat; } return 0xFF; } From cb53faacb279e2a17f2c28a1a58822906ca1a6b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Mar 2018 06:53:54 +0100 Subject: [PATCH 3/3] Fixed the IBM PS/2 Model 70 Type 3 and 4 ROM sizes. --- src/rom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rom.c b/src/rom.c index c36600291..19cf4c762 100644 --- a/src/rom.c +++ b/src/rom.c @@ -13,7 +13,7 @@ * - c386sx16 BIOS fails checksum * - the loadfont() calls should be done elsewhere * - * Version: @(#)rom.c 1.0.34 2018/03/11 + * Version: @(#)rom.c 1.0.35 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -721,7 +721,7 @@ rom_load_bios(int rom_id) if (! rom_load_interleaved( L"roms/machines/ibmps2_m70_type3/70-a_even.bin", L"roms/machines/ibmps2_m70_type3/70-a_odd.bin", - 0x000000, 65536, 0, rom)) break; + 0x000000, 131072, 0, rom)) break; biosmask = 0x1ffff; return(1); @@ -729,7 +729,7 @@ rom_load_bios(int rom_id) if (! rom_load_interleaved( L"roms/machines/ibmps2_m70_type4/70-b_even.bin", L"roms/machines/ibmps2_m70_type4/70-b_odd.bin", - 0x000000, 65536, 0, rom)) break; + 0x000000, 131072, 0, rom)) break; biosmask = 0x1ffff; return(1);