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/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/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();
}
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);
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 255aa43f4..43ae476e4 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.13 2018/03/02
+ * Version: @(#)vid_ati_mach64.c 1.0.16 2018/03/16
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -431,6 +431,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 92de3df80..f09b99f6d 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;
}