diff --git a/src/cpu/808x.c b/src/cpu/808x.c
index 146179c73..e95cf1c79 100644
--- a/src/cpu/808x.c
+++ b/src/cpu/808x.c
@@ -1,10 +1,10 @@
/*
- * 86Box A hypervisor and IBM PC system emulator that specializes in
- * running old operating systems and software designed for IBM
- * PC systems and compatibles from 1981 through fairly recent
- * system designs based on the PCI bus.
+ * VARCem Virtual ARchaeological Computer EMulator.
+ * An emulator of (mostly) x86-based PC systems and devices,
+ * using the ISA,EISA,VLB,MCA and PCI system buses, roughly
+ * spanning the era between 1981 and 1995.
*
- * This file is part of the 86Box distribution.
+ * This file is part of the VARCem Project.
*
* 808x CPU emulation.
*
@@ -18,13 +18,31 @@
* 2 clocks - fetch opcode 1 2 clocks - execute
* 2 clocks - fetch opcode 2 etc
*
- * Version: @(#)808x.c 1.0.10 2017/12/03
+ * Version: @(#)808x.c 1.0.2 2018/03/09
*
- * Authors: Sarah Walker,
+ * Authors: Sarah Walker,
* Miran Grca,
*
- * Copyright 2008-2017 Sarah Walker.
- * Copyright 2016,2017 Miran Grca.
+ * Copyright 2008-2018 Sarah Walker.
+ * Copyright 2016-2018 Miran Grca.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ *
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307
+ * USA.
*/
#include
#include
@@ -1212,7 +1230,7 @@ void execx86(int cycs)
break;
case 0x14: /*ADC AL,#8*/
tempw=FETCH();
- setadc8(AL,tempw);
+ setadc8(AL,tempw & 0xff);
AL+=tempw+tempc;
cycles-=4;
break;
@@ -2950,7 +2968,7 @@ void execx86(int cycs)
if (temp)
{
tempw2=tempw%temp;
- AH=tempw2;
+ AH=tempw2 & 0xff;
tempw/=temp;
AL=tempw&0xFF;
}
diff --git a/src/cpu/codegen.h b/src/cpu/codegen.h
index 99703e370..e613ecbed 100644
--- a/src/cpu/codegen.h
+++ b/src/cpu/codegen.h
@@ -1,3 +1,39 @@
+/*
+ * VARCem Virtual ARchaeological Computer EMulator.
+ * An emulator of (mostly) x86-based PC systems and devices,
+ * using the ISA,EISA,VLB,MCA and PCI system buses, roughly
+ * spanning the era between 1981 and 1995.
+ *
+ * This file is part of the VARCem Project.
+ *
+ * Definitions for the code generator.
+ *
+ * Version: @(#)codegen.h 1.0.2 2018/03/14
+ *
+ * Authors: Sarah Walker,
+ * Miran Grca,
+ *
+ * Copyright 2008-2018 Sarah Walker.
+ * Copyright 2016-2018 Miran Grca.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ *
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307
+ * USA.
+ */
#ifndef _CODEGEN_H_
#define _CODEGEN_H_
@@ -267,7 +303,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
void codegen_generate_seg_restore();
void codegen_set_op32();
void codegen_flush();
-void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr);
+void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr);
extern int cpu_block_end;
extern uint32_t codegen_endpc;
diff --git a/src/disk/hdc.c b/src/disk/hdc.c
index 809b82592..f2cb9b2b3 100644
--- a/src/disk/hdc.c
+++ b/src/disk/hdc.c
@@ -8,7 +8,7 @@
*
* Common code to handle all sorts of disk controllers.
*
- * Version: @(#)hdc.c 1.0.11 2018/03/18
+ * Version: @(#)hdc.c 1.0.12 2018/03/19
*
* Authors: Miran Grca,
* Fred N. van Kempen,
@@ -72,63 +72,63 @@ static const device_t inthdc_device = {
static const struct {
- char *name;
- char *internal_name;
+ const char *name;
+ const char *internal_name;
const device_t *device;
- int is_mfm;
} controllers[] = {
{ "None", "none",
- &null_device, 0 },
+ &null_device },
{ "Internal Controller", "internal",
- &inthdc_device, 0 },
+ &inthdc_device },
{ "[ISA] [MFM] IBM PC Fixed Disk Adapter", "mfm_xt",
- &mfm_xt_xebec_device, 1 },
+ &mfm_xt_xebec_device },
{ "[ISA] [MFM] DTC-5150X Fixed Disk Adapter", "mfm_dtc5150x",
- &mfm_xt_dtc5150x_device, 1 },
+ &mfm_xt_dtc5150x_device },
{ "[ISA] [MFM] IBM PC/AT Fixed Disk Adapter", "mfm_at",
- &mfm_at_wd1003_device, 1 },
+ &mfm_at_wd1003_device },
{ "[ISA] [ESDI] PC/AT ESDI Fixed Disk Adapter", "esdi_at",
- &esdi_at_wd1007vse1_device, 0 },
+ &esdi_at_wd1007vse1_device },
{ "[ISA] [IDE] PC/AT IDE Adapter", "ide_isa",
- &ide_isa_device, 0 },
+ &ide_isa_device },
{ "[ISA] [IDE] PC/AT IDE Adapter (Dual-Channel)", "ide_isa_2ch",
- &ide_isa_2ch_device, 0 },
+ &ide_isa_2ch_device },
{ "[ISA] [IDE] PC/AT XTIDE", "xtide_at",
- &xtide_at_device, 0 },
+ &xtide_at_device },
{ "[ISA] [IDE] PS/2 AT XTIDE (1.1.5)", "xtide_at_ps2",
- &xtide_at_ps2_device, 0 },
+ &xtide_at_ps2_device },
{ "[ISA] [XT IDE] Acculogic XT IDE", "xtide_acculogic",
- &xtide_acculogic_device, 0 },
+ &xtide_acculogic_device },
{ "[ISA] [XT IDE] PC/XT XTIDE", "xtide",
- &xtide_device , 0 },
+ &xtide_device },
{ "[MCA] [ESDI] IBM PS/2 ESDI Fixed Disk Adapter","esdi_mca",
- &esdi_ps2_device, 1 },
+ &esdi_ps2_device },
{ "[PCI] [IDE] PCI IDE Adapter", "ide_pci",
- &ide_pci_device, 0 },
+ &ide_pci_device },
{ "[PCI] [IDE] PCI IDE Adapter (Dual-Channel)", "ide_pci_2ch",
- &ide_pci_2ch_device, 0 },
+ &ide_pci_2ch_device },
{ "[VLB] [IDE] PC/AT IDE Adapter", "vlb_isa",
- &ide_vlb_device, 0 },
+ &ide_vlb_device },
{ "[VLB] [IDE] PC/AT IDE Adapter (Dual-Channel)", "vlb_isa_2ch",
- &ide_vlb_2ch_device, 0 },
+ &ide_vlb_2ch_device },
- { "", "", NULL, 0 }
+ { "", "",
+ NULL }
};
@@ -140,8 +140,8 @@ hdc_init(char *name)
pclog("HDC: initializing..\n");
- for (c=0; controllers[c].device; c++) {
- if (! strcmp(name, controllers[c].internal_name)) {
+ for (c = 0; controllers[c].device; c++) {
+ if (! strcmp(name, (char *) controllers[c].internal_name)) {
hdc_current = c;
break;
}
@@ -174,14 +174,14 @@ hdc_reset(void)
char *
hdc_get_name(int hdc)
{
- return(controllers[hdc].name);
+ return((char *) controllers[hdc].name);
}
char *
hdc_get_internal_name(int hdc)
{
- return(controllers[hdc].internal_name);
+ return((char *) controllers[hdc].internal_name);
}
@@ -204,10 +204,3 @@ hdc_available(int hdc)
{
return(device_available(controllers[hdc].device));
}
-
-
-int
-hdc_current_is_mfm(void)
-{
- return(controllers[hdc_current].is_mfm);
-}
diff --git a/src/disk/hdc.h b/src/disk/hdc.h
index 5f4f9a934..8dd1ac8a5 100644
--- a/src/disk/hdc.h
+++ b/src/disk/hdc.h
@@ -8,7 +8,7 @@
*
* Definitions for the common disk controller handler.
*
- * Version: @(#)hdc.h 1.0.6 2018/03/18
+ * Version: @(#)hdc.h 1.0.7 2018/03/19
*
* Authors: Miran Grca,
* Fred N. van Kempen,
@@ -61,7 +61,6 @@ extern char *hdc_get_internal_name(int hdc);
extern const device_t *hdc_get_device(int hdc);
extern int hdc_get_flags(int hdc);
extern int hdc_available(int hdc);
-extern int hdc_current_is_mfm(void);
#endif /*EMU_HDC_H*/
diff --git a/src/keyboard.c b/src/keyboard.c
index 9e50889ae..55fea6571 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -8,15 +8,15 @@
*
* General keyboard driver interface.
*
- * Version: @(#)keyboard.c 1.0.14 2018/02/10
+ * Version: @(#)keyboard.c 1.0.15 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
* Fred N. van Kempen,
*
* Copyright 2008-2018 Sarah Walker.
- * Copyright 2016,2018 Miran Grca.
- * Copyright 2018 Fred N. van Kempen.
+ * Copyright 2015-2018 Miran Grca.
+ * Copyright 2017,2018 Fred N. van Kempen.
*/
#include
#include
@@ -61,9 +61,9 @@ keyboard_init(void)
void
-keyboard_set_table(scancode *ptr)
+keyboard_set_table(const scancode *ptr)
{
- scan_table = ptr;
+ scan_table = (scancode *) ptr;
}
diff --git a/src/keyboard.h b/src/keyboard.h
index c9d5ebcd4..388f29d10 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -8,7 +8,7 @@
*
* Definitions for the keyboard interface.
*
- * Version: @(#)keyboard.h 1.0.12 2018/03/18
+ * Version: @(#)keyboard.h 1.0.13 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -51,7 +51,7 @@ extern int64_t keyboard_delay;
extern void (*keyboard_send)(uint16_t val);
extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val));
-extern scancode scancode_xt[512];
+extern const scancode scancode_xt[512];
extern uint8_t keyboard_set3_flags[512];
extern uint8_t keyboard_set3_all_repeat;
@@ -73,7 +73,7 @@ extern const device_t keyboard_ps2_quadtel_device;
extern void keyboard_init(void);
extern void keyboard_close(void);
-extern void keyboard_set_table(scancode *ptr);
+extern void keyboard_set_table(const scancode *ptr);
extern void keyboard_poll_host(void);
extern void keyboard_process(void);
extern uint16_t keyboard_convert(int ch);
diff --git a/src/keyboard_at.c b/src/keyboard_at.c
index 09f255515..87e7af857 100644
--- a/src/keyboard_at.c
+++ b/src/keyboard_at.c
@@ -8,7 +8,7 @@
*
* Intel 8042 (AT keyboard controller) emulation.
*
- * Version: @(#)keyboard_at.c 1.0.31 2018/03/18
+ * Version: @(#)keyboard_at.c 1.0.32 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -154,7 +154,7 @@ static atkbd_t *CurrentKbd = NULL; // FIXME: remove!!! --FvK
/* Non-translated to translated scan codes. */
-static uint8_t nont_to_t[256] = {
+static const uint8_t nont_to_t[256] = {
0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58,
0x64, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, 0x59,
0x65, 0x38, 0x2A, 0x70, 0x1D, 0x10, 0x02, 0x5A,
@@ -189,7 +189,7 @@ static uint8_t nont_to_t[256] = {
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
-static scancode scancode_set1[512] = {
+static const scancode scancode_set1[512] = {
{ { -1},{ -1} }, { { 0x01,-1},{ 0x81,-1} }, { { 0x02,-1},{ 0x82,-1} }, { { 0x03,-1},{ 0x83,-1} }, /*000*/
{ { 0x04,-1},{ 0x84,-1} }, { { 0x05,-1},{ 0x85,-1} }, { { 0x06,-1},{ 0x86,-1} }, { { 0x07,-1},{ 0x87,-1} }, /*004*/
{ { 0x08,-1},{ 0x88,-1} }, { { 0x09,-1},{ 0x89,-1} }, { { 0x0a,-1},{ 0x8a,-1} }, { { 0x0b,-1},{ 0x8b,-1} }, /*008*/
@@ -319,7 +319,7 @@ static scancode scancode_set1[512] = {
{ { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{ -1} }, { {0xe0,0xff,-1},{ -1} } /*1fc*/
};
-static scancode scancode_set2[512] = {
+static const scancode scancode_set2[512] = {
{ { -1},{ -1} }, { { 0x76,-1},{ 0xF0,0x76,-1} }, { { 0x16,-1},{ 0xF0,0x16,-1} }, { { 0x1E,-1},{ 0xF0,0x1E,-1} }, /*000*/
{ { 0x26,-1},{ 0xF0,0x26,-1} }, { { 0x25,-1},{ 0xF0,0x25,-1} }, { { 0x2E,-1},{ 0xF0,0x2E,-1} }, { { 0x36,-1},{ 0xF0,0x36,-1} }, /*004*/
{ { 0x3D,-1},{ 0xF0,0x3D,-1} }, { { 0x3E,-1},{ 0xF0,0x3E,-1} }, { { 0x46,-1},{ 0xF0,0x46,-1} }, { { 0x45,-1},{ 0xF0,0x45,-1} }, /*008*/
@@ -449,7 +449,7 @@ static scancode scancode_set2[512] = {
{ { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{0xe0,0xF0,0xFE,-1} }, { {0xe0,0xff,-1},{0xe0,0xF0,0xFF,-1} } /*1fc*/
};
-static scancode scancode_set3[512] = {
+static const scancode scancode_set3[512] = {
{ { -1},{ -1} }, { { 0x08,-1},{ 0xf0,0x08,-1} }, { { 0x16,-1},{ 0xf0,0x16,-1} }, { { 0x1E,-1},{ 0xf0,0x1E,-1} }, /*000*/
{ { 0x26,-1},{ 0xf0,0x26,-1} }, { { 0x25,-1},{ 0xf0,0x25,-1} }, { { 0x2E,-1},{ 0xf0,0x2E,-1} }, { { 0x36,-1},{ 0xf0,0x36,-1} }, /*004*/
{ { 0x3D,-1},{ 0xf0,0x3D,-1} }, { { 0x3E,-1},{ 0xf0,0x3E,-1} }, { { 0x46,-1},{ 0xf0,0x46,-1} }, { { 0x45,-1},{ 0xf0,0x45,-1} }, /*008*/
@@ -598,27 +598,23 @@ kbdlog(const char *fmt, ...)
static void
kbd_setmap(atkbd_t *kbd)
{
- scancode *map = NULL;
-
switch (keyboard_mode & 3) {
case 1:
default:
- map = scancode_set1;
+ keyboard_set_table(scancode_set1);
break;
case 2:
- map = scancode_set2;
+ keyboard_set_table(scancode_set2);
break;
case 3:
- map = scancode_set3;
+ keyboard_set_table(scancode_set3);
break;
}
if (keyboard_mode & 0x20)
- map = scancode_set1;
-
- keyboard_set_table(map);
+ keyboard_set_table(scancode_set1);
}
@@ -981,11 +977,6 @@ kbd_cmd_write(atkbd_t *kbd, uint8_t val)
kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled");
}
-
-#if 0
- /* Reset scancode map. */
- kbd_setmap(kbd);
-#endif
}
diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c
index 28bd1b645..fe9b162a0 100644
--- a/src/keyboard_xt.c
+++ b/src/keyboard_xt.c
@@ -8,7 +8,7 @@
*
* Implementation of the XT-style keyboard.
*
- * Version: @(#)keyboard_xt.c 1.0.10 2018/03/18
+ * Version: @(#)keyboard_xt.c 1.0.11 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -60,7 +60,7 @@ typedef struct {
/*XT keyboard has no escape scancodes, and no scancodes beyond 53*/
-scancode scancode_xt[512] = {
+const scancode scancode_xt[512] = {
{ {-1}, {-1} }, { {0x01, -1}, {0x81, -1} },
{ {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} },
{ {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} },
diff --git a/src/lpt.c b/src/lpt.c
index 4f692a37a..fbd048beb 100644
--- a/src/lpt.c
+++ b/src/lpt.c
@@ -19,7 +19,7 @@ static const struct
{
const char *name;
const char *internal_name;
- lpt_device_t *device;
+ const lpt_device_t *device;
} lpt_devices[] =
{
{"None", "none", NULL},
@@ -60,7 +60,7 @@ void lpt_devices_init()
lpt_device_ts[i] = NULL;
else
{
- lpt_device_ts[i] = lpt_devices[c].device;
+ lpt_device_ts[i] = (lpt_device_t *) lpt_devices[c].device;
if (lpt_device_ts[i])
lpt_device_ps[i] = lpt_device_ts[i]->init();
}
diff --git a/src/machine/m_olivetti_m24.c b/src/machine/m_olivetti_m24.c
index bf6c0ec6f..b8128f25b 100644
--- a/src/machine/m_olivetti_m24.c
+++ b/src/machine/m_olivetti_m24.c
@@ -8,7 +8,7 @@
*
* Emulation of the Olivetti M24.
*
- * Version: @(#)m_olivetti_m24.c 1.0.11 2018/03/18
+ * Version: @(#)m_olivetti_m24.c 1.0.12 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -836,7 +836,7 @@ machine_olim24_init(const machine_t *model)
kbd_read, NULL, NULL, kbd_write, NULL, NULL, m24);
io_sethandler(0x0064, 1,
kbd_read, NULL, NULL, kbd_write, NULL, NULL, m24);
- keyboard_set_table(scancode_xt);
+ keyboard_set_table(scancode_xt);
keyboard_send = kbd_adddata_ex;
keyboard_scan = 1;
timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, m24);
diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c
index a31fffde8..552f23fe9 100644
--- a/src/machine/m_tandy.c
+++ b/src/machine/m_tandy.c
@@ -8,7 +8,7 @@
*
* Emulation of Tandy models 1000, 1000HX and 1000SL2.
*
- * Version: @(#)m_tandy.c 1.0.4 2018/03/18
+ * Version: @(#)m_tandy.c 1.0.5 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -121,7 +121,7 @@ typedef struct {
} tandy_t;
-static scancode scancode_tandy[512] = {
+static const scancode scancode_tandy[512] = {
{ {-1}, {-1} }, { {0x01, -1}, {0x81, -1} },
{ {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} },
{ {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} },
diff --git a/src/machine/machine.c b/src/machine/machine.c
index 4a17cc7ae..b344ddd10 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
- * Version: @(#)machine.c 1.0.31 2018/03/18
+ * Version: @(#)machine.c 1.0.32 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -53,7 +53,7 @@ machine_init(void)
PCI = IS_ARCH(machine, MACHINE_PCI);
/* Resize the memory. */
- mem_resize();
+ mem_reset();
/* Load the machine's ROM BIOS. */
rom_load_bios(romset);
diff --git a/src/mem.c b/src/mem.c
index cbd3fe165..bd19461f7 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -1,1639 +1,1897 @@
-/* Copyright holders: Sarah Walker, Tenshi
- see COPYING for more details
-*/
-#include
-#include
-#include
-#include
-#include
-#include "86box.h"
-#include "cpu/cpu.h"
-#include "cpu/x86_ops.h"
-#include "cpu/x86.h"
-#include "machine/machine.h"
-#include "machine/m_xt_xi8088.h"
-#include "config.h"
-#include "io.h"
-#include "mem.h"
-#include "rom.h"
-
-#ifdef USE_DYNAREC
-# include "cpu/codegen.h"
-#else
-#define PAGE_MASK_INDEX_MASK 3
-#define PAGE_MASK_INDEX_SHIFT 10
-#define PAGE_MASK_MASK 63
-#define PAGE_MASK_SHIFT 4
-#endif
-
-
-static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv);
-static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv);
-static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv);
-static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv);
-static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv);
-static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv);
-static uint8_t *_mem_exec[0x40000];
-static void *_mem_priv_r[0x40000];
-static void *_mem_priv_w[0x40000];
-static mem_mapping_t *_mem_mapping_r[0x40000];
-static mem_mapping_t *_mem_mapping_w[0x40000];
-static int _mem_state[0x40000];
-
-static mem_mapping_t base_mapping;
-static mem_mapping_t ram_remapped_mapping;
-static mem_mapping_t ram_split_mapping;
-mem_mapping_t ram_low_mapping;
-mem_mapping_t ram_high_mapping;
-mem_mapping_t ram_mid_mapping;
-mem_mapping_t bios_mapping[8];
-mem_mapping_t bios_high_mapping[8];
-mem_mapping_t romext_mapping;
-
-page_t *pages;
-page_t **page_lookup;
-
-uint8_t *ram;
-uint32_t rammask;
-
-uint32_t pccache;
-uint8_t *pccache2;
-
-int readlookup[256],readlookupp[256];
-uintptr_t *readlookup2;
-int readlnext;
-int writelookup[256],writelookupp[256];
-uintptr_t *writelookup2;
-int writelnext;
-
-int shadowbios = 0,
- shadowbios_write;
-
-int mem_a20_state;
-
-unsigned char isram[0x10000];
-
-static uint8_t ff_array[0x1000];
-
-int mem_size;
-uint32_t biosmask;
-int readlnum=0,writelnum=0;
-int cachesize=256;
-
-uint8_t *rom;
-uint8_t romext[32768];
-
-uint32_t ram_mapped_addr[64];
-
-int split_mapping_enabled = 0;
-
-
-void resetreadlookup(void)
-{
- int c;
- memset(readlookup2,0xFF,1024*1024*sizeof(uintptr_t));
- for (c=0;c<256;c++) readlookup[c]=0xFFFFFFFF;
- readlnext=0;
- memset(writelookup2,0xFF,1024*1024*sizeof(uintptr_t));
- memset(page_lookup, 0, (1 << 20) * sizeof(page_t *));
- for (c=0;c<256;c++) writelookup[c]=0xFFFFFFFF;
- writelnext=0;
- pccache=0xFFFFFFFF;
-}
-
-int mmuflush=0;
-int mmu_perm=4;
-
-void flushmmucache(void)
-{
- int c;
- for (c=0;c<256;c++)
- {
- if (readlookup[c]!=0xFFFFFFFF)
- {
- readlookup2[readlookup[c]] = -1;
- readlookup[c]=0xFFFFFFFF;
- }
- if (writelookup[c] != 0xFFFFFFFF)
- {
- page_lookup[writelookup[c]] = NULL;
- writelookup2[writelookup[c]] = -1;
- writelookup[c] = 0xFFFFFFFF;
- }
- }
- mmuflush++;
- pccache=(uint32_t)0xFFFFFFFF;
- pccache2=(uint8_t *)0xFFFFFFFF;
-
-#ifdef USE_DYNAREC
- codegen_flush();
-#endif
-}
-
-void flushmmucache_nopc(void)
-{
- int c;
- for (c=0;c<256;c++)
- {
- if (readlookup[c]!=0xFFFFFFFF)
- {
- readlookup2[readlookup[c]] = -1;
- readlookup[c]=0xFFFFFFFF;
- }
- if (writelookup[c] != 0xFFFFFFFF)
- {
- page_lookup[writelookup[c]] = NULL;
- writelookup2[writelookup[c]] = -1;
- writelookup[c] = 0xFFFFFFFF;
- }
- }
-}
-
-void flushmmucache_cr3(void)
-{
- int c;
- for (c=0;c<256;c++)
- {
- if (readlookup[c]!=0xFFFFFFFF)
- {
- readlookup2[readlookup[c]] = -1;
- readlookup[c]=0xFFFFFFFF;
- }
- if (writelookup[c] != 0xFFFFFFFF)
- {
- page_lookup[writelookup[c]] = NULL;
- writelookup2[writelookup[c]] = -1;
- writelookup[c] = 0xFFFFFFFF;
- }
- }
-}
-
-void mem_flush_write_page(uint32_t addr, uint32_t virt)
-{
- int c;
- page_t *page_target = &pages[addr >> 12];
-
- for (c = 0; c < 256; c++)
- {
- if (writelookup[c] != 0xffffffff)
- {
- uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)];
-
- if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target)
- {
- writelookup2[writelookup[c]] = -1;
- page_lookup[writelookup[c]] = NULL;
- writelookup[c] = 0xffffffff;
- }
- }
- }
-}
-
-extern int output;
-
-#define mmutranslate_read(addr) mmutranslatereal(addr,0)
-#define mmutranslate_write(addr) mmutranslatereal(addr,1)
-
-int pctrans=0;
-
-extern uint32_t testr[9];
-
-#define rammap(x) ((uint32_t *)(_mem_exec[(x) >> 14]))[((x) >> 2) & 0xfff]
-
-uint32_t mmutranslatereal(uint32_t addr, int rw)
-{
- uint32_t addr2;
- uint32_t temp,temp2,temp3;
-
- if (cpu_state.abrt)
- return -1;
- addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
- temp=temp2=rammap(addr2);
- if (!(temp&1)) {
- cr2=addr;
- temp&=1;
- if (CPL==3) temp|=4;
- if (rw) temp|=2;
- cpu_state.abrt = ABRT_PF;
- abrt_error = temp;
- return -1;
- }
-
- if ((temp & 0x80) && (cr4 & CR4_PSE)) {
- /*4MB page*/
- if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) {
- cr2 = addr;
- temp &= 1;
- if (CPL == 3)
- temp |= 4;
- if (rw)
- temp |= 2;
- cpu_state.abrt = ABRT_PF;
- abrt_error = temp;
-
- return -1;
- }
-
- mmu_perm = temp & 4;
- rammap(addr2) |= 0x20;
-
- return (temp & ~0x3fffff) + (addr & 0x3fffff);
- }
-
- temp=rammap((temp&~0xFFF)+((addr>>10)&0xFFC));
- temp3=temp&temp2;
- if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || cr0&WP_FLAG))) {
- cr2=addr;
- temp&=1;
- if (CPL==3) temp|=4;
- if (rw) temp|=2;
- cpu_state.abrt = ABRT_PF;
- abrt_error = temp;
- return -1;
- }
- mmu_perm=temp&4;
- rammap(addr2)|=0x20;
- rammap((temp2&~0xFFF)+((addr>>10)&0xFFC))|=(rw?0x60:0x20);
-
- return (temp&~0xFFF)+(addr&0xFFF);
-}
-
-uint32_t mmutranslate_noabrt(uint32_t addr, int rw)
-{
- uint32_t addr2;
- uint32_t temp,temp2,temp3;
-
- if (cpu_state.abrt)
- return -1;
-
- addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
- temp=temp2=rammap(addr2);
-
- if (!(temp&1))
- return -1;
-
- if ((temp & 0x80) && (cr4 & CR4_PSE)) {
- /*4MB page*/
- if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG)))
- return -1;
-
- return (temp & ~0x3fffff) + (addr & 0x3fffff);
- }
-
- temp=rammap((temp&~0xFFF)+((addr>>10)&0xFFC));
- temp3=temp&temp2;
-
- if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG)))
- return -1;
-
- return (temp&~0xFFF)+(addr&0xFFF);
-}
-
-void mmu_invalidate(uint32_t addr)
-{
- flushmmucache_cr3();
-}
-
-uint8_t mem_addr_range_match(uint32_t addr, uint32_t start, uint32_t len)
-{
- if (addr < start)
- return 0;
- else if (addr >= (start + len))
- return 0;
- else
- return 1;
-}
-
-uint32_t mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len)
-{
- uint32_t mask = len - 1;
- return chunk_start + (addr & mask);
-}
-
-void addreadlookup(uint32_t virt, uint32_t phys)
-{
- if (virt == 0xffffffff)
- return;
-
- if (readlookup2[virt>>12] != -1)
- {
- return;
- }
-
- if (readlookup[readlnext]!=0xFFFFFFFF)
- {
- readlookup2[readlookup[readlnext]] = -1;
- }
-
- readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
- readlookupp[readlnext]=mmu_perm;
- readlookup[readlnext++]=virt>>12;
- readlnext&=(cachesize-1);
-
- cycles -= 9;
-}
-
-void addwritelookup(uint32_t virt, uint32_t phys)
-{
- if (virt == 0xffffffff)
- return;
-
- if (page_lookup[virt >> 12])
- {
- return;
- }
-
- if (writelookup[writelnext] != -1)
- {
- page_lookup[writelookup[writelnext]] = NULL;
- writelookup2[writelookup[writelnext]] = -1;
- }
-
-#ifdef USE_DYNAREC
- if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page)
-#else
- if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3])
-#endif
- page_lookup[virt >> 12] = &pages[phys >> 12];
- else {
- writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
- }
- writelookupp[writelnext] = mmu_perm;
- writelookup[writelnext++] = virt >> 12;
- writelnext &= (cachesize - 1);
-
- cycles -= 9;
-}
-
-uint8_t *getpccache(uint32_t a)
-{
- uint32_t a2;
-
- a2=a;
-
- if (a2 < 0x100000 && ram_mapped_addr[a2 >> 14])
- {
- a = (ram_mapped_addr[a2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? a2 : (ram_mapped_addr[a2 >> 14] & ~0x3FFF) + (a2 & 0x3FFF);
- return &ram[(uintptr_t)(a & 0xFFFFF000) - (uintptr_t)(a2 & ~0xFFF)];
- }
-
- a2 = a;
-
- if (cr0>>31)
- {
- pctrans=1;
- a = mmutranslate_read(a);
- pctrans=0;
-
- if (a==0xFFFFFFFF) return ram;
- }
- a&=rammask;
-
- if (_mem_exec[a >> 14])
- {
- if (_mem_mapping_r[a >> 14]->flags & MEM_MAPPING_ROM)
- cpu_prefetch_cycles = cpu_rom_prefetch_cycles;
- else
- cpu_prefetch_cycles = cpu_mem_prefetch_cycles;
-
-
- return &_mem_exec[a >> 14][(uintptr_t)(a & 0x3000) - (uintptr_t)(a2 & ~0xFFF)];
- }
-
- pclog("Bad getpccache %08X\n", a);
- return &ff_array[0-(uintptr_t)(a2 & ~0xFFF)];
-}
-
-uint32_t mem_logical_addr;
-uint8_t readmembl(uint32_t addr)
-{
- mem_logical_addr = addr;
- if (addr < 0x100000 && ram_mapped_addr[addr >> 14])
- {
- addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF);
- if(addr < mem_size * 1024) return ram[addr];
- return 0xFF;
- }
- if (cr0 >> 31)
- {
- addr = mmutranslate_read(addr);
- if (addr == 0xFFFFFFFF) return 0xFF;
- }
- addr &= rammask;
-
- if (_mem_read_b[addr >> 14]) {
- return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
- }
- return 0xFF;
-}
-
-void writemembl(uint32_t addr, uint8_t val)
-{
- mem_logical_addr = addr;
-
- if (addr < 0x100000 && ram_mapped_addr[addr >> 14])
- {
- addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF);
- if(addr < mem_size * 1024) ram[addr] = val;
- return;
- }
- if (page_lookup[addr>>12])
- {
- page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]);
- return;
- }
- if (cr0 >> 31)
- {
- addr = mmutranslate_write(addr);
- if (addr == 0xFFFFFFFF) return;
- }
- addr &= rammask;
-
- if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
-}
-
-uint8_t readmemb386l(uint32_t seg, uint32_t addr)
-{
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return -1;
- }
- mem_logical_addr = addr = addr + seg;
- if (addr < 0x100000 && ram_mapped_addr[addr >> 14])
- {
- addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF);
- if(addr < mem_size * 1024) return ram[addr];
- return 0xFF;
- }
-
- if (cr0 >> 31)
- {
- addr = mmutranslate_read(addr);
- if (addr == 0xFFFFFFFF) return 0xFF;
- }
-
- addr &= rammask;
-
- if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
- return 0xFF;
-}
-
-void writememb386l(uint32_t seg, uint32_t addr, uint8_t val)
-{
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return;
- }
-
- mem_logical_addr = addr = addr + seg;
- if (addr < 0x100000 && ram_mapped_addr[addr >> 14])
- {
- addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF);
- if(addr < mem_size * 1024) ram[addr] = val;
- return;
- }
- if (page_lookup[addr>>12])
- {
- page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]);
- return;
- }
- if (cr0 >> 31)
- {
- addr = mmutranslate_write(addr);
- if (addr == 0xFFFFFFFF) return;
- }
-
- addr &= rammask;
-
- if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
-}
-
-uint16_t readmemwl(uint32_t seg, uint32_t addr)
-{
- uint32_t addr2 = mem_logical_addr = seg + addr;
-
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return -1;
- }
- if (addr2 & 1)
- {
- if (!cpu_cyrix_alignment || (addr2 & 7) == 7)
- cycles -= timing_misaligned;
- if ((addr2 & 0xFFF) > 0xFFE)
- {
- if (cr0 >> 31)
- {
- if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff;
- if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff;
- }
- if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8);
- else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8);
- }
- else if (readlookup2[addr2 >> 12] != -1)
- return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2);
- }
- if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14])
- {
- addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF);
- if(addr < mem_size * 1024) return *((uint16_t *)&ram[addr]);
- return 0xFFFF;
- }
- if (cr0>>31)
- {
- addr2 = mmutranslate_read(addr2);
- if (addr2==0xFFFFFFFF) return 0xFFFF;
- }
-
- addr2 &= rammask;
-
- if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
-
- if (_mem_read_b[addr2 >> 14])
- {
- if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8);
- else return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14]) << 8);
- }
- return 0xffff;
-}
-
-void writememwl(uint32_t seg, uint32_t addr, uint16_t val)
-{
- uint32_t addr2 = mem_logical_addr = seg + addr;
-
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return;
- }
- if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14])
- {
- addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF);
- if(addr < mem_size * 1024) *((uint16_t *)&ram[addr]) = val;
- return;
- }
-
- if (addr2 & 1)
- {
- if (!cpu_cyrix_alignment || (addr2 & 7) == 7)
- cycles -= timing_misaligned;
- if ((addr2 & 0xFFF) > 0xFFE)
- {
- if (cr0 >> 31)
- {
- if (mmutranslate_write(addr2) == 0xffffffff) return;
- if (mmutranslate_write(addr2+1) == 0xffffffff) return;
- }
- if (is386)
- {
- writememb386l(seg,addr,val);
- writememb386l(seg,addr+1,val>>8);
- }
- else
- {
- writemembl(seg+addr,val);
- writemembl(seg+addr+1,val>>8);
- }
- return;
- }
- else if (writelookup2[addr2 >> 12] != -1)
- {
- *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val;
- return;
- }
- }
-
- if (page_lookup[addr2>>12])
- {
- page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]);
- return;
- }
- if (cr0>>31)
- {
- addr2 = mmutranslate_write(addr2);
- if (addr2==0xFFFFFFFF) return;
- }
-
- addr2 &= rammask;
-
-/* if (addr2 >= 0xa0000 && addr2 < 0xc0000)
- pclog("writememwl %08X %02X\n", addr2, val);*/
-
- if (_mem_write_w[addr2 >> 14])
- {
- _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- return;
- }
-
- if (_mem_write_b[addr2 >> 14])
- {
- _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]);
- return;
- }
-}
-
-uint32_t readmemll(uint32_t seg, uint32_t addr)
-{
- uint32_t addr2 = mem_logical_addr = seg + addr;
-
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return -1;
- }
-
- if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14])
- {
- addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF);
- if(addr < mem_size * 1024) return *((uint32_t *)&ram[addr]);
- return 0xFFFFFFFF;
- }
-
- if (addr2 & 3)
- {
- if (!cpu_cyrix_alignment || (addr2 & 7) > 4)
- cycles -= timing_misaligned;
- if ((addr2&0xFFF)>0xFFC)
- {
- if (cr0>>31)
- {
- if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
- if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff;
- }
- return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16);
- }
- else if (readlookup2[addr2 >> 12] != -1)
- return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2);
- }
-
- if (cr0>>31)
- {
- addr2 = mmutranslate_read(addr2);
- if (addr2==0xFFFFFFFF) return 0xFFFFFFFF;
- }
-
- addr2&=rammask;
-
- if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
-
- if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16);
-
- if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14]) << 24);
-
- return 0xffffffff;
-}
-
-void writememll(uint32_t seg, uint32_t addr, uint32_t val)
-{
- uint32_t addr2 = mem_logical_addr = seg + addr;
-
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return;
- }
- if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14])
- {
- addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF);
- if(addr < mem_size * 1024) *((uint32_t *)&ram[addr]) = val;
- return;
- }
- if (addr2 & 3)
- {
- if (!cpu_cyrix_alignment || (addr2 & 7) > 4)
- cycles -= timing_misaligned;
- if ((addr2 & 0xFFF) > 0xFFC)
- {
- if (cr0>>31)
- {
- if (mmutranslate_write(addr2) == 0xffffffff) return;
- if (mmutranslate_write(addr2+3) == 0xffffffff) return;
- }
- writememwl(seg,addr,val);
- writememwl(seg,addr+2,val>>16);
- return;
- }
- else if (writelookup2[addr2 >> 12] != -1)
- {
- *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val;
- return;
- }
- }
- if (page_lookup[addr2>>12])
- {
- page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]);
- return;
- }
- if (cr0>>31)
- {
- addr2 = mmutranslate_write(addr2);
- if (addr2==0xFFFFFFFF) return;
- }
-
- addr2&=rammask;
-
- if (_mem_write_l[addr2 >> 14])
- {
- _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- return;
- }
- if (_mem_write_w[addr2 >> 14])
- {
- _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
- return;
- }
- if (_mem_write_b[addr2 >> 14])
- {
- _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]);
- return;
- }
-}
-
-uint64_t readmemql(uint32_t seg, uint32_t addr)
-{
- uint32_t addr2 = mem_logical_addr = seg + addr;
-
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return -1;
- }
-
- if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14])
- {
- addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF);
- if(addr < mem_size * 1024) return *((uint64_t *)&ram[addr]);
- return -1;
- }
-
- if (addr2 & 7)
- {
- cycles -= timing_misaligned;
- if ((addr2 & 0xFFF) > 0xFF8)
- {
- if (cr0>>31)
- {
- if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
- if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff;
- }
- return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32);
- }
- else if (readlookup2[addr2 >> 12] != -1)
- return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2);
- }
-
- if (cr0>>31)
- {
- addr2 = mmutranslate_read(addr2);
- if (addr2==0xFFFFFFFF) return -1;
- }
-
- addr2&=rammask;
-
- if (_mem_read_l[addr2 >> 14])
- return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) |
- ((uint64_t)_mem_read_l[addr2 >> 14](addr2 + 4, _mem_priv_r[addr2 >> 14]) << 32);
-
- return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32);
-}
-
-void writememql(uint32_t seg, uint32_t addr, uint64_t val)
-{
- uint32_t addr2 = mem_logical_addr = seg + addr;
-
- if (seg==-1)
- {
- x86gpf("NULL segment", 0);
- return;
- }
- if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14])
- {
- addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF);
- if(addr < mem_size * 1024) *((uint64_t *)&ram[addr]) = val;
- return;
- }
- if (addr2 & 7)
- {
- cycles -= timing_misaligned;
- if ((addr2 & 0xFFF) > 0xFF8)
- {
- if (cr0>>31)
- {
- if (mmutranslate_write(addr2) == 0xffffffff) return;
- if (mmutranslate_write(addr2+7) == 0xffffffff) return;
- }
- writememll(seg, addr, val);
- writememll(seg, addr+4, val >> 32);
- return;
- }
- else if (writelookup2[addr2 >> 12] != -1)
- {
- *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val;
- return;
- }
- }
- if (page_lookup[addr2>>12])
- {
- page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]);
- page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]);
- return;
- }
- if (cr0>>31)
- {
- addr2 = mmutranslate_write(addr2);
- if (addr2==0xFFFFFFFF) return;
- }
-
- addr2&=rammask;
-
- if (_mem_write_l[addr2 >> 14])
- {
- _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- _mem_write_l[addr2 >> 14](addr2+4, val >> 32, _mem_priv_w[addr2 >> 14]);
- return;
- }
- if (_mem_write_w[addr2 >> 14])
- {
- _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
- _mem_write_w[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]);
- _mem_write_w[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]);
- return;
- }
- if (_mem_write_b[addr2 >> 14])
- {
- _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 5, val >> 40, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]);
- _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]);
- return;
- }
-}
-
-uint8_t mem_readb_phys(uint32_t addr)
-{
- mem_logical_addr = 0xffffffff;
-
- if (_mem_read_b[addr >> 14])
- return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
-
- return 0xff;
-}
-
-/* Version of mem_readby_phys that doesn't go through the CPU paging mechanism. */
-uint8_t mem_readb_phys_dma(uint32_t addr)
-{
- /* mem_logical_addr = 0xffffffff; */
-
- if (_mem_exec[addr >> 14])
- return _mem_exec[addr >> 14][addr & 0x3fff];
- else if (_mem_read_b[addr >> 14])
- return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
- else
- return 0xff;
-}
-
-uint16_t mem_readw_phys(uint32_t addr)
-{
- mem_logical_addr = 0xffffffff;
-
- if (_mem_read_w[addr >> 14])
- return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]);
-
- return 0xff;
-}
-
-void mem_writeb_phys(uint32_t addr, uint8_t val)
-{
- mem_logical_addr = 0xffffffff;
-
- if (_mem_write_b[addr >> 14])
- _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
-}
-
-/* Version of mem_readby_phys that doesn't go through the CPU paging mechanism. */
-void mem_writeb_phys_dma(uint32_t addr, uint8_t val)
-{
- /* mem_logical_addr = 0xffffffff; */
-
- if (_mem_exec[addr >> 14])
- _mem_exec[addr >> 14][addr & 0x3fff] = val;
- else if (_mem_write_b[addr >> 14])
- _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
-}
-
-void mem_writew_phys(uint32_t addr, uint16_t val)
-{
- mem_logical_addr = 0xffffffff;
-
- if (_mem_write_w[addr >> 14])
- _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
-}
-
-uint8_t mem_read_ram(uint32_t addr, void *priv)
-{
- addreadlookup(mem_logical_addr, addr);
- return ram[addr];
-}
-uint16_t mem_read_ramw(uint32_t addr, void *priv)
-{
- addreadlookup(mem_logical_addr, addr);
- return *(uint16_t *)&ram[addr];
-}
-uint32_t mem_read_raml(uint32_t addr, void *priv)
-{
- addreadlookup(mem_logical_addr, addr);
- return *(uint32_t *)&ram[addr];
-}
-
-void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
-{
-#ifdef USE_DYNAREC
- if (val != p->mem[addr & 0xfff] || codegen_in_recompile)
-#else
- if (val != p->mem[addr & 0xfff])
-#endif
- {
- uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
- p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
- p->mem[addr & 0xfff] = val;
- }
-}
-void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
-{
-#ifdef USE_DYNAREC
- if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile)
-#else
- if (val != *(uint16_t *)&p->mem[addr & 0xfff])
-#endif
- {
- uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
- if ((addr & 0xf) == 0xf)
- mask |= (mask << 1);
- p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
- *(uint16_t *)&p->mem[addr & 0xfff] = val;
- }
-}
-void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
-{
-#ifdef USE_DYNAREC
- if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile)
-#else
- if (val != *(uint32_t *)&p->mem[addr & 0xfff])
-#endif
- {
- uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
- if ((addr & 0xf) >= 0xd)
- mask |= (mask << 1);
- p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
- *(uint32_t *)&p->mem[addr & 0xfff] = val;
- }
-}
-
-void mem_write_ram(uint32_t addr, uint8_t val, void *priv)
-{
- addwritelookup(mem_logical_addr, addr);
- mem_write_ramb_page(addr, val, &pages[addr >> 12]);
-}
-void mem_write_ramw(uint32_t addr, uint16_t val, void *priv)
-{
- addwritelookup(mem_logical_addr, addr);
- mem_write_ramw_page(addr, val, &pages[addr >> 12]);
-}
-void mem_write_raml(uint32_t addr, uint32_t val, void *priv)
-{
- addwritelookup(mem_logical_addr, addr);
- mem_write_raml_page(addr, val, &pages[addr >> 12]);
-}
-
-
-uint8_t mem_read_bios(uint32_t addr, void *priv)
-{
- return rom[addr & biosmask];
-}
-uint16_t mem_read_biosw(uint32_t addr, void *priv)
-{
- return *(uint16_t *)&rom[addr & biosmask];
-}
-uint32_t mem_read_biosl(uint32_t addr, void *priv)
-{
- return *(uint32_t *)&rom[addr & biosmask];
-}
-
-uint8_t mem_read_romext(uint32_t addr, void *priv)
-{
- return romext[addr & 0x7fff];
-}
-uint16_t mem_read_romextw(uint32_t addr, void *priv)
-{
- uint16_t *p = (uint16_t *)&romext[addr & 0x7fff];
- return *p;
-}
-uint32_t mem_read_romextl(uint32_t addr, void *priv)
-{
- uint32_t *p = (uint32_t *)&romext[addr & 0x7fff];
- return *p;
-}
-
-void mem_write_null(uint32_t addr, uint8_t val, void *p)
-{
-}
-void mem_write_nullw(uint32_t addr, uint16_t val, void *p)
-{
-}
-void mem_write_nulll(uint32_t addr, uint32_t val, void *p)
-{
-}
-
-void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
-{
- start_addr &= ~PAGE_MASK_MASK;
- end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK;
-
- for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT))
- {
- uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
-
- pages[start_addr >> 12].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
- }
-}
-
-static __inline int mem_mapping_read_allowed(uint32_t flags, int state)
-{
- switch (state & MEM_READ_MASK)
- {
- case MEM_READ_ANY:
- return 1;
- case MEM_READ_EXTERNAL:
- return !(flags & MEM_MAPPING_INTERNAL);
- case MEM_READ_INTERNAL:
- return !(flags & MEM_MAPPING_EXTERNAL);
- default:
- fatal("mem_mapping_read_allowed : bad state %x\n", state);
- return 0;
- }
-}
-
-static __inline int mem_mapping_write_allowed(uint32_t flags, int state)
-{
- switch (state & MEM_WRITE_MASK)
- {
- case MEM_WRITE_DISABLED:
- return 0;
- case MEM_WRITE_ANY:
- return 1;
- case MEM_WRITE_EXTERNAL:
- return !(flags & MEM_MAPPING_INTERNAL);
- case MEM_WRITE_INTERNAL:
- return !(flags & MEM_MAPPING_EXTERNAL);
- default:
- fatal("mem_mapping_write_allowed : bad state %x\n", state);
- return 0;
- }
-}
-
-static void mem_mapping_recalc(uint64_t base, uint64_t size)
-{
- uint64_t c;
- mem_mapping_t *mapping = base_mapping.next;
-
- if (!size)
- return;
- /*Clear out old mappings*/
- for (c = base; c < base + size; c += 0x4000)
- {
- _mem_read_b[c >> 14] = NULL;
- _mem_read_w[c >> 14] = NULL;
- _mem_read_l[c >> 14] = NULL;
- _mem_priv_r[c >> 14] = NULL;
- _mem_mapping_r[c >> 14] = NULL;
- _mem_write_b[c >> 14] = NULL;
- _mem_write_w[c >> 14] = NULL;
- _mem_write_l[c >> 14] = NULL;
- _mem_priv_w[c >> 14] = NULL;
- _mem_mapping_w[c >> 14] = NULL;
- }
-
- /*Walk mapping list*/
- while (mapping != NULL)
- {
- /*In range?*/
- if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base)
- {
- uint64_t start = (mapping->base < base) ? mapping->base : base;
- uint64_t end = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->size) : (base + size);
- if (start < mapping->base)
- start = mapping->base;
-
- for (c = start; c < end; c += 0x4000)
- {
- if ((mapping->read_b || mapping->read_w || mapping->read_l) &&
- mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14]))
- {
- _mem_read_b[c >> 14] = mapping->read_b;
- _mem_read_w[c >> 14] = mapping->read_w;
- _mem_read_l[c >> 14] = mapping->read_l;
- if (mapping->exec)
- _mem_exec[c >> 14] = mapping->exec + (c - mapping->base);
- else
- _mem_exec[c >> 14] = NULL;
- _mem_priv_r[c >> 14] = mapping->p;
- _mem_mapping_r[c >> 14] = mapping;
- }
- if ((mapping->write_b || mapping->write_w || mapping->write_l) &&
- mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14]))
- {
- _mem_write_b[c >> 14] = mapping->write_b;
- _mem_write_w[c >> 14] = mapping->write_w;
- _mem_write_l[c >> 14] = mapping->write_l;
- _mem_priv_w[c >> 14] = mapping->p;
- _mem_mapping_w[c >> 14] = mapping;
- }
- }
- }
- mapping = mapping->next;
- }
- flushmmucache_cr3();
-}
-
-void mem_mapping_add(mem_mapping_t *mapping,
- uint32_t base,
- uint32_t size,
- uint8_t (*read_b)(uint32_t addr, void *p),
- uint16_t (*read_w)(uint32_t addr, void *p),
- uint32_t (*read_l)(uint32_t addr, void *p),
- void (*write_b)(uint32_t addr, uint8_t val, void *p),
- void (*write_w)(uint32_t addr, uint16_t val, void *p),
- void (*write_l)(uint32_t addr, uint32_t val, void *p),
- uint8_t *exec,
- uint32_t flags,
- void *p)
-{
- mem_mapping_t *dest = &base_mapping;
-
- /*Add mapping to the end of the list*/
- while (dest->next)
- dest = dest->next;
- dest->next = mapping;
- mapping->prev = dest;
-
- if (size)
- mapping->enable = 1;
- else
- mapping->enable = 0;
- mapping->base = base;
- mapping->size = size;
- mapping->read_b = read_b;
- mapping->read_w = read_w;
- mapping->read_l = read_l;
- mapping->write_b = write_b;
- mapping->write_w = write_w;
- mapping->write_l = write_l;
- mapping->exec = exec;
- mapping->flags = flags;
- mapping->p = p;
- mapping->next = NULL;
-
- mem_mapping_recalc(mapping->base, mapping->size);
-}
-
-void mem_mapping_set_handler(mem_mapping_t *mapping,
- uint8_t (*read_b)(uint32_t addr, void *p),
- uint16_t (*read_w)(uint32_t addr, void *p),
- uint32_t (*read_l)(uint32_t addr, void *p),
- void (*write_b)(uint32_t addr, uint8_t val, void *p),
- void (*write_w)(uint32_t addr, uint16_t val, void *p),
- void (*write_l)(uint32_t addr, uint32_t val, void *p))
-{
- mapping->read_b = read_b;
- mapping->read_w = read_w;
- mapping->read_l = read_l;
- mapping->write_b = write_b;
- mapping->write_w = write_w;
- mapping->write_l = write_l;
-
- mem_mapping_recalc(mapping->base, mapping->size);
-}
-
-void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size)
-{
- /*Remove old mapping*/
- mapping->enable = 0;
- mem_mapping_recalc(mapping->base, mapping->size);
-
- /*Set new mapping*/
- mapping->enable = 1;
- mapping->base = base;
- mapping->size = size;
-
- mem_mapping_recalc(mapping->base, mapping->size);
-}
-
-void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec)
-{
- mapping->exec = exec;
-
- mem_mapping_recalc(mapping->base, mapping->size);
-}
-
-void mem_mapping_set_p(mem_mapping_t *mapping, void *p)
-{
- mapping->p = p;
-}
-
-void mem_mapping_disable(mem_mapping_t *mapping)
-{
- mapping->enable = 0;
-
- mem_mapping_recalc(mapping->base, mapping->size);
-}
-
-void mem_mapping_enable(mem_mapping_t *mapping)
-{
- mapping->enable = 1;
-
- mem_mapping_recalc(mapping->base, mapping->size);
-}
-
-void mem_set_mem_state(uint32_t base, uint32_t size, int state)
-{
- uint32_t c;
-
- for (c = 0; c < size; c += 0x4000)
- _mem_state[(c + base) >> 14] = state;
-
- mem_mapping_recalc(base, size);
-}
-
-void mem_add_bios()
-{
- if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb()))
- {
- mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- }
- mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
-
- mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0);
-}
-
-int mem_a20_key = 0, mem_a20_alt = 0;
-int mem_a20_state = 0;
-
-void mem_a20_init(void)
-{
- if (AT) {
- rammask = cpu_16bitbus ? 0xefffff : 0xffefffff;
- flushmmucache();
- mem_a20_state = mem_a20_key | mem_a20_alt;
- } else {
- rammask = 0xfffff;
- flushmmucache();
- mem_a20_key = mem_a20_alt = mem_a20_state = 0;
- }
-}
-
-void mem_destroy_pages(void)
-{
- if (pages) {
- free(pages);
- pages = NULL;
- }
-}
-
-void mem_resize_pages(void)
-{
- int total_size, c;
-
- mem_destroy_pages();
-
- if (AT) {
- if (cpu_16bitbus)
- total_size = 4096;
- 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;
-
- pages = malloc(total_size * sizeof(page_t));
-
- memset(pages, 0, total_size * sizeof(page_t));
-
- for (c = 0; c < total_size; c++)
- {
- pages[c].mem = &ram[c << 12];
- pages[c].write_b = mem_write_ramb_page;
- pages[c].write_w = mem_write_ramw_page;
- pages[c].write_l = mem_write_raml_page;
- }
-}
-
-void mem_init(void)
-{
- int c;
-
- split_mapping_enabled = 0;
-
- /* Always allocate the full 16 MB memory space if memory size is smaller,
- we'll need this for stupid things like the PS/2 split mapping. */
- if (mem_size < 16384) {
- ram = malloc(16384 * 1024);
- memset(ram, 0, 16384 * 1024);
- } else {
- ram = malloc((mem_size + 384) * 1024); /* 386 extra kB for top remapping */
- memset(ram, 0, (mem_size + 384) * 1024);
- }
-
- readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t));
- writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t));
- rom = NULL;
- biosmask = 0xffff;
-
- memset(ram_mapped_addr, 0, 64 * sizeof(uint32_t));
-
- page_lookup = malloc((1 << 20) * sizeof(page_t *));
- memset(page_lookup, 0, (1 << 20) * sizeof(page_t *));
-
- mem_resize_pages();
-
- memset(isram, 0, sizeof(isram));
- for (c = 0; c < (mem_size / 64); c++)
- {
- isram[c] = 1;
- if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff))
- isram[c] = 0;
- }
-
- memset(_mem_read_b, 0, sizeof(_mem_read_b));
- memset(_mem_read_w, 0, sizeof(_mem_read_w));
- memset(_mem_read_l, 0, sizeof(_mem_read_l));
- memset(_mem_write_b, 0, sizeof(_mem_write_b));
- memset(_mem_write_w, 0, sizeof(_mem_write_w));
- memset(_mem_write_l, 0, sizeof(_mem_write_l));
- memset(_mem_exec, 0, sizeof(_mem_exec));
-
- memset(ff_array, 0xff, sizeof(ff_array));
-
- memset(&base_mapping, 0, sizeof(base_mapping));
-
- memset(_mem_state, 0, sizeof(_mem_state));
-
- mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
-
- mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL);
- if (mem_size > 1024) {
- if(cpu_16bitbus && mem_size > 16256)
- {
- mem_set_mem_state(0x100000, (16256 - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
- }
- else
- {
- mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
- }
- }
- if (mem_size > 768)
- mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
-
- if (romset == ROM_IBMPS1_2011)
- mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL);
-
- mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL);
- mem_mapping_disable(&ram_remapped_mapping);
-
- mem_mapping_add(&ram_split_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL);
- mem_mapping_disable(&ram_split_mapping);
-
- mem_a20_init();
-}
-
-static void mem_remap_top(int max_size)
-{
- int c;
-
- if (mem_size > 640)
- {
- uint32_t start = (mem_size >= 1024) ? mem_size : 1024;
- int size = mem_size - 640;
- if (size > max_size)
- size = max_size;
-
- for (c = (start / 64); c < ((start + size - 1) / 64); c++)
- {
- isram[c] = 1;
- }
-
- mem_set_mem_state(start * 1024, size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
- mem_mapping_set_exec(&ram_split_mapping, ram + (start * 1024));
-
- flushmmucache();
- }
-}
-
-void mem_remap_top_256k()
-{
- mem_remap_top(256);
-}
-
-void mem_remap_top_384k()
-{
- mem_remap_top(384);
-}
-
-void mem_resize()
-{
- int c;
-
- split_mapping_enabled = 0;
-
- free(ram);
-
- /* Always allocate the full 16 MB memory space if memory size is smaller,
- we'll need this for stupid things like the PS/2 split mapping. */
- if (mem_size < 16384) {
- ram = malloc(16384 * 1024);
- memset(ram, 0, 16384 * 1024);
- } else {
- ram = malloc((mem_size + 384) * 1024); /* 386 extra kB for top remapping */
- memset(ram, 0, (mem_size + 384) * 1024);
- }
-
- memset(isram, 0, sizeof(isram));
- for (c = 0; c < (mem_size / 64); c++)
- {
- isram[c] = 1;
- if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff))
- isram[c] = 0;
- }
-
- mem_resize_pages();
-
- memset(_mem_read_b, 0, sizeof(_mem_read_b));
- memset(_mem_read_w, 0, sizeof(_mem_read_w));
- memset(_mem_read_l, 0, sizeof(_mem_read_l));
- memset(_mem_write_b, 0, sizeof(_mem_write_b));
- memset(_mem_write_w, 0, sizeof(_mem_write_w));
- memset(_mem_write_l, 0, sizeof(_mem_write_l));
- memset(_mem_exec, 0, sizeof(_mem_exec));
-
- memset(&base_mapping, 0, sizeof(base_mapping));
-
- memset(_mem_state, 0, sizeof(_mem_state));
-
- mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
-
- mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL);
- if (mem_size > 1024) {
- if(cpu_16bitbus && mem_size > 16256)
- {
- mem_set_mem_state(0x100000, (16256 - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
- }
- else
- {
- mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
- }
- }
- if (mem_size > 768)
- mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
-
- if (romset == ROM_IBMPS1_2011)
- mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL);
-
- mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL);
- mem_mapping_disable(&ram_remapped_mapping);
-
- mem_mapping_add(&ram_split_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL);
- mem_mapping_disable(&ram_split_mapping);
-
- mem_a20_init();
-}
-
-void mem_reset_page_blocks()
-{
- int c;
-
- if (!pages)
- return;
-
- for (c = 0; c < ((mem_size * 1024) >> 12); c++)
- {
- pages[c].write_b = mem_write_ramb_page;
- pages[c].write_w = mem_write_ramw_page;
- pages[c].write_l = mem_write_raml_page;
- pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL;
- pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL;
- }
-}
-
-
-static int port_92_reg = 0;
-
-void mem_a20_recalc(void)
-{
- int state;
-
- if (!AT) {
- rammask = 0xfffff;
- flushmmucache();
- mem_a20_key = mem_a20_alt = mem_a20_state = 0;
- return;
- }
-
- state = mem_a20_key | mem_a20_alt;
- if (state && !mem_a20_state)
- {
- rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff;
- flushmmucache();
- }
- else if (!state && mem_a20_state)
- {
- rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff;
- flushmmucache();
- }
- mem_a20_state = state;
-}
-
-
-uint8_t port_92_read(uint16_t port, void *priv)
-{
- return port_92_reg;
-}
-
-
-void port_92_write(uint16_t port, uint8_t val, void *priv)
-{
- if ((mem_a20_alt ^ val) & 2)
- {
- mem_a20_alt = (val & 2);
- mem_a20_recalc();
- }
-
- if ((~port_92_reg & val) & 1)
- {
- softresetx86();
- cpu_set_edx();
- }
-
- port_92_reg = val;
-}
-
-
-void port_92_clear_reset(void)
-{
- port_92_reg &= 2;
-}
-
-void port_92_add(void)
-{
- io_sethandler(0x0092, 0x0001, port_92_read, NULL, NULL, port_92_write, NULL, NULL, NULL);
-}
-
-void port_92_remove(void)
-{
- io_removehandler(0x0092, 0x0001, port_92_read, NULL, NULL, port_92_write, NULL, NULL, NULL);
-}
-
-void port_92_reset(void)
-{
- port_92_reg = 0;
- mem_a20_alt = 0;
- mem_a20_recalc();
- flushmmucache();
-}
-
-uint32_t get_phys_virt,get_phys_phys;
+/*
+ * VARCem Virtual ARchaeological Computer EMulator.
+ * An emulator of (mostly) x86-based PC systems and devices,
+ * using the ISA,EISA,VLB,MCA and PCI system buses, roughly
+ * spanning the era between 1981 and 1995.
+ *
+ * This file is part of the VARCem Project.
+ *
+ * Memory handling and MMU.
+ *
+ * NOTE: Experimenting with dynamically allocated lookup tables;
+ * the DYNAMIC_TABLES=1 enables this. Will eventually go
+ * away, either way...
+ *
+ * Version: @(#)mem.c 1.0.9 2018/03/19
+ *
+ * Authors: Fred N. van Kempen,
+ * Miran Grca,
+ * Sarah Walker,
+ *
+ * Copyright 2017,2018 Fred N. van Kempen.
+ * Copyright 2016-2018 Miran Grca.
+ * Copyright 2008-2018 Sarah Walker.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ *
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307
+ * USA.
+ */
+#include
+#include
+#include
+#include
+#include
+#include "86box.h"
+#include "cpu/cpu.h"
+#include "cpu/x86_ops.h"
+#include "cpu/x86.h"
+#include "machine/machine.h"
+#include "machine/m_xt_xi8088.h"
+#include "config.h"
+#include "io.h"
+#include "mem.h"
+#include "rom.h"
+#ifdef USE_DYNAREC
+# include "cpu/codegen.h"
+#else
+# define PAGE_MASK_INDEX_MASK 3
+# define PAGE_MASK_INDEX_SHIFT 10
+# define PAGE_MASK_MASK 63
+# define PAGE_MASK_SHIFT 4
+#endif
+
+
+#define FIXME 0
+#define DYNAMIC_TABLES 0 /* experimental */
+
+
+mem_mapping_t ram_low_mapping;
+mem_mapping_t ram_high_mapping;
+mem_mapping_t ram_mid_mapping;
+mem_mapping_t bios_mapping[8];
+mem_mapping_t bios_high_mapping[8];
+mem_mapping_t romext_mapping;
+
+page_t *pages, /* RAM page table */
+ **page_lookup; /* pagetable lookup */
+uint32_t pages_sz; /* #pages in table */
+
+uint8_t isram[0x10000];
+
+uint8_t *ram; /* the virtual RAM */
+uint32_t rammask;
+
+uint8_t *rom; /* the virtual ROM */
+uint8_t romext[32768];
+uint32_t biosmask;
+
+uint32_t pccache;
+uint8_t *pccache2;
+
+int readlnext;
+int readlookup[256],
+ readlookupp[256];
+uintptr_t *readlookup2;
+int writelnext;
+int writelookup[256],
+ writelookupp[256];
+uintptr_t *writelookup2;
+
+uint32_t mem_logical_addr;
+
+int shadowbios = 0,
+ shadowbios_write;
+int readlnum = 0,
+ writelnum = 0;
+int pctrans = 0;
+int cachesize = 256;
+
+uint32_t ram_mapped_addr[64];
+
+uint32_t get_phys_virt,
+ get_phys_phys;
+
+int mem_a20_key = 0,
+ mem_a20_alt = 0,
+ mem_a20_state = 0;
+
+int mmuflush = 0;
+int mmu_perm = 4;
+
+
+/* FIXME: re-do this with a 'mem_ops' struct. */
+static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv);
+static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv);
+static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv);
+static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv);
+static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv);
+static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv);
+static uint8_t *_mem_exec[0x40000];
+static void *_mem_priv_r[0x40000];
+static void *_mem_priv_w[0x40000];
+static mem_mapping_t *_mem_mapping_r[0x40000];
+static mem_mapping_t *_mem_mapping_w[0x40000];
+static int _mem_state[0x40000];
+
+static mem_mapping_t base_mapping;
+static mem_mapping_t ram_remapped_mapping;
+
+#if FIXME
+static uint8_t ff_array[0x1000];
+#else
+static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
+#endif
+
+static int port_92_reg = 0;
+
+
+void
+resetreadlookup(void)
+{
+ int c;
+
+ /* This is NULL after app startup, when mem_init() has not yet run. */
+#if DYNAMIC_TABLES
+pclog("MEM: reset_lookup: pages=%08lx, lookup=%08lx, pages_sz=%i\n", pages, page_lookup, pages_sz);
+#endif
+
+ /* Initialize the page lookup table. */
+#if DYNAMIC_TABLES
+ memset(page_lookup, 0x00, pages_sz*sizeof(page_t *));
+#else
+ memset(page_lookup, 0x00, (1<<20)*sizeof(page_t *));
+#endif
+
+ /* Initialize the tables for lower (<= 1024K) RAM. */
+ for (c = 0; c < 256; c++) {
+ readlookup[c] = 0xffffffff;
+ writelookup[c] = 0xffffffff;
+ }
+
+ /* Initialize the tables for high (> 1024K) RAM. */
+#if DYNAMIC_TABLES
+ memset(readlookup2, 0xff, pages_sz*sizeof(uintptr_t));
+ memset(writelookup2, 0xff, pages_sz*sizeof(uintptr_t));
+#else
+ memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t));
+ memset(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t));
+#endif
+
+ readlnext = 0;
+ writelnext = 0;
+ pccache = 0xffffffff;
+}
+
+
+void
+flushmmucache(void)
+{
+ int c;
+
+ for (c = 0; c < 256; c++) {
+ if (readlookup[c] != 0xffffffff) {
+ readlookup2[readlookup[c]] = -1;
+ readlookup[c] = 0xffffffff;
+ }
+ if (writelookup[c] != 0xffffffff) {
+ page_lookup[writelookup[c]] = NULL;
+ writelookup2[writelookup[c]] = -1;
+ writelookup[c] = 0xffffffff;
+ }
+ }
+ mmuflush++;
+
+ pccache = (uint32_t)0xffffffff;
+ pccache2 = (uint8_t *)0xffffffff;
+
+#ifdef USE_DYNAREC
+ codegen_flush();
+#endif
+}
+
+
+void
+flushmmucache_nopc(void)
+{
+ int c;
+
+ for (c = 0; c < 256; c++) {
+ if (readlookup[c] != 0xffffffff) {
+ readlookup2[readlookup[c]] = -1;
+ readlookup[c] = 0xffffffff;
+ }
+ if (writelookup[c] != 0xffffffff) {
+ page_lookup[writelookup[c]] = NULL;
+ writelookup2[writelookup[c]] = -1;
+ writelookup[c] = 0xffffffff;
+ }
+ }
+}
+
+
+void
+flushmmucache_cr3(void)
+{
+ int c;
+
+ for (c = 0; c < 256; c++) {
+ if (readlookup[c] != 0xffffffff) {
+ readlookup2[readlookup[c]] = -1;
+ readlookup[c] = 0xffffffff;
+ }
+ if (writelookup[c] != 0xffffffff) {
+ page_lookup[writelookup[c]] = NULL;
+ writelookup2[writelookup[c]] = -1;
+ writelookup[c] = 0xffffffff;
+ }
+ }
+}
+
+
+void
+mem_flush_write_page(uint32_t addr, uint32_t virt)
+{
+ page_t *page_target = &pages[addr >> 12];
+ int c;
+
+ for (c = 0; c < 256; c++) {
+ if (writelookup[c] != 0xffffffff) {
+ uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)];
+
+ if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) {
+ writelookup2[writelookup[c]] = -1;
+ page_lookup[writelookup[c]] = NULL;
+ writelookup[c] = 0xffffffff;
+ }
+ }
+ }
+}
+
+
+#define mmutranslate_read(addr) mmutranslatereal(addr,0)
+#define mmutranslate_write(addr) mmutranslatereal(addr,1)
+#define rammap(x) ((uint32_t *)(_mem_exec[(x) >> 14]))[((x) >> 2) & 0xfff]
+
+uint32_t
+mmutranslatereal(uint32_t addr, int rw)
+{
+ uint32_t temp,temp2,temp3;
+ uint32_t addr2;
+
+ if (cpu_state.abrt) return -1;
+
+ addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
+ temp = temp2 = rammap(addr2);
+ if (! (temp&1)) {
+ cr2 = addr;
+ temp &= 1;
+ if (CPL == 3) temp |= 4;
+ if (rw) temp |= 2;
+ cpu_state.abrt = ABRT_PF;
+ abrt_error = temp;
+ return -1;
+ }
+
+ if ((temp & 0x80) && (cr4 & CR4_PSE)) {
+ /*4MB page*/
+ if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) {
+ cr2 = addr;
+ temp &= 1;
+ if (CPL == 3)
+ temp |= 4;
+ if (rw)
+ temp |= 2;
+ cpu_state.abrt = ABRT_PF;
+ abrt_error = temp;
+
+ return -1;
+ }
+
+ mmu_perm = temp & 4;
+ rammap(addr2) |= 0x20;
+
+ return (temp & ~0x3fffff) + (addr & 0x3fffff);
+ }
+
+ temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc));
+ temp3 = temp & temp2;
+ if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || cr0&WP_FLAG))) {
+ cr2 = addr;
+ temp &= 1;
+ if (CPL == 3) temp |= 4;
+ if (rw) temp |= 2;
+ cpu_state.abrt = ABRT_PF;
+ abrt_error = temp;
+ return -1;
+ }
+
+ mmu_perm = temp & 4;
+ rammap(addr2) |= 0x20;
+ rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw?0x60:0x20);
+
+ return (temp&~0xfff)+(addr&0xfff);
+}
+
+
+uint32_t
+mmutranslate_noabrt(uint32_t addr, int rw)
+{
+ uint32_t temp,temp2,temp3;
+ uint32_t addr2;
+
+ if (cpu_state.abrt)
+ return -1;
+
+ addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
+ temp = temp2 = rammap(addr2);
+
+ if (! (temp & 1))
+ return -1;
+
+ if ((temp & 0x80) && (cr4 & CR4_PSE)) {
+ /*4MB page*/
+ if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG)))
+ return -1;
+
+ return (temp & ~0x3fffff) + (addr & 0x3fffff);
+ }
+
+ temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc));
+ temp3 = temp & temp2;
+
+ if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG)))
+ return -1;
+
+ return (temp & ~0xfff) + (addr & 0xfff);
+}
+
+
+void
+mmu_invalidate(uint32_t addr)
+{
+ flushmmucache_cr3();
+}
+
+
+uint8_t
+mem_addr_range_match(uint32_t addr, uint32_t start, uint32_t len)
+{
+ if (addr < start)
+ return 0;
+ else if (addr >= (start + len))
+ return 0;
+ else
+ return 1;
+}
+
+
+uint32_t
+mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len)
+{
+ uint32_t mask = len - 1;
+
+ return chunk_start + (addr & mask);
+}
+
+
+void
+addreadlookup(uint32_t virt, uint32_t phys)
+{
+ if (virt == 0xffffffff) return;
+
+ if (readlookup2[virt>>12] != -1) return;
+
+ if (readlookup[readlnext] != 0xffffffff)
+ readlookup2[readlookup[readlnext]] = -1;
+
+ readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
+
+ readlookupp[readlnext] = mmu_perm;
+ readlookup[readlnext++] = virt >> 12;
+ readlnext &= (cachesize-1);
+
+ cycles -= 9;
+}
+
+
+void
+addwritelookup(uint32_t virt, uint32_t phys)
+{
+ if (virt == 0xffffffff) return;
+
+ if (page_lookup[virt >> 12]) return;
+
+ if (writelookup[writelnext] != -1) {
+ page_lookup[writelookup[writelnext]] = NULL;
+ writelookup2[writelookup[writelnext]] = -1;
+ }
+
+#ifdef USE_DYNAREC
+ if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page)
+#else
+ if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3])
+#endif
+ page_lookup[virt >> 12] = &pages[phys >> 12];
+ else
+ writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
+
+ writelookupp[writelnext] = mmu_perm;
+ writelookup[writelnext++] = virt >> 12;
+ writelnext &= (cachesize - 1);
+
+ cycles -= 9;
+}
+
+
+uint8_t *
+getpccache(uint32_t a)
+{
+ uint32_t a2;
+
+ a2 = a;
+
+ if (a2 < 0x100000 && ram_mapped_addr[a2 >> 14]) {
+ a = (ram_mapped_addr[a2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? a2 : (ram_mapped_addr[a2 >> 14] & ~0x3FFF) + (a2 & 0x3FFF);
+ return &ram[(uintptr_t)(a & 0xFFFFF000) - (uintptr_t)(a2 & ~0xFFF)];
+ }
+
+ a2 = a;
+
+ if (cr0 >> 31) {
+ pctrans=1;
+ a = mmutranslate_read(a);
+ pctrans = 0;
+
+ if (a == 0xffffffff) return ram;
+ }
+ a &= rammask;
+
+ if (_mem_exec[a >> 14]) {
+ if (_mem_mapping_r[a >> 14]->flags & MEM_MAPPING_ROM)
+ cpu_prefetch_cycles = cpu_rom_prefetch_cycles;
+ else
+ cpu_prefetch_cycles = cpu_mem_prefetch_cycles;
+
+ return &_mem_exec[a >> 14][(uintptr_t)(a & 0x3000) - (uintptr_t)(a2 & ~0xfff)];
+ }
+
+ pclog("Bad getpccache %08X\n", a);
+
+#if FIXME
+ return &ff_array[0-(uintptr_t)(a2 & ~0xfff)];
+#else
+ return (uint8_t *)&ff_pccache;
+#endif
+}
+
+
+uint8_t
+readmembl(uint32_t addr)
+{
+ mem_logical_addr = addr;
+
+ if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
+ addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
+ if(addr < mem_size * 1024) return ram[addr];
+ return 0xff;
+ }
+
+ if (cr0 >> 31) {
+ addr = mmutranslate_read(addr);
+ if (addr == 0xffffffff) return 0xff;
+ }
+ addr &= rammask;
+
+ if (_mem_read_b[addr >> 14])
+ return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
+
+ return 0xff;
+}
+
+
+void
+writemembl(uint32_t addr, uint8_t val)
+{
+ mem_logical_addr = addr;
+
+ if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
+ addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
+ if (addr < mem_size * 1024)
+ ram[addr] = val;
+ return;
+ }
+
+ if (page_lookup[addr>>12])
{
+ page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]);
+
+ return;
+ }
+
+ if (cr0 >> 31) {
+ addr = mmutranslate_write(addr);
+ if (addr == 0xffffffff) return;
+ }
+ addr &= rammask;
+
+ if (_mem_write_b[addr >> 14])
+ _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
+}
+
+
+uint8_t
+readmemb386l(uint32_t seg, uint32_t addr)
+{
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+
+ return -1;
+ }
+
+ mem_logical_addr = addr = addr + seg;
+ if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
+ addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
+ if (addr < mem_size * 1024)
+ return ram[addr];
+ return 0xff;
+ }
+
+ if (cr0 >> 31) {
+ addr = mmutranslate_read(addr);
+ if (addr == 0xffffffff)
+ return 0xff;
+ }
+
+ addr &= rammask;
+
+ if (_mem_read_b[addr >> 14])
+ return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
+
+ return 0xff;
+}
+
+
+void
+writememb386l(uint32_t seg, uint32_t addr, uint8_t val)
+{
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+ return;
+ }
+
+ mem_logical_addr = addr = addr + seg;
+ if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
+ addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
+ if (addr < mem_size * 1024)
+ ram[addr] = val;
+ return;
+ }
+
+ if (page_lookup[addr>>12]) {
+ page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]);
+
+ return;
+ }
+
+ if (cr0 >> 31) {
+ addr = mmutranslate_write(addr);
+ if (addr == 0xffffffff) return;
+ }
+
+ addr &= rammask;
+
+ if (_mem_write_b[addr >> 14])
+ _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
+}
+
+
+uint16_t
+readmemwl(uint32_t seg, uint32_t addr)
+{
+ uint32_t addr2 = mem_logical_addr = seg + addr;
+
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+ return -1;
+ }
+
+ if (addr2 & 1) {
+ if (!cpu_cyrix_alignment || (addr2 & 7) == 7)
+ cycles -= timing_misaligned;
+ if ((addr2 & 0xFFF) > 0xffe) {
+ if (cr0 >> 31) {
+ if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff;
+ if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff;
+ }
+ if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8);
+ else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8);
+ }
+ else if (readlookup2[addr2 >> 12] != -1)
+ return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2);
+ }
+
+ if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) {
+ addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
+ if (addr < mem_size * 1024)
+ return *((uint16_t *)&ram[addr]);
+ return 0xffff;
+ }
+
+ if (cr0 >> 31) {
+ addr2 = mmutranslate_read(addr2);
+ if (addr2 == 0xffffffff)
+ return 0xFFFF;
+ }
+
+ addr2 &= rammask;
+
+ if (_mem_read_w[addr2 >> 14])
+ return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
+
+ if (_mem_read_b[addr2 >> 14]) {
+ if (AT)
+ return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8);
+ else
+ return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14]) << 8);
+ }
+
+ return 0xffff;
+}
+
+
+void
+writememwl(uint32_t seg, uint32_t addr, uint16_t val)
+{
+ uint32_t addr2 = mem_logical_addr = seg + addr;
+
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+ return;
+ }
+
+ if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) {
+ addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
+ if (addr < mem_size * 1024)
+ *((uint16_t *)&ram[addr]) = val;
+ return;
+ }
+
+ if (addr2 & 1) {
+ if (!cpu_cyrix_alignment || (addr2 & 7) == 7)
+ cycles -= timing_misaligned;
+ if ((addr2 & 0xFFF) > 0xffe) {
+ if (cr0 >> 31) {
+ if (mmutranslate_write(addr2) == 0xffffffff) return;
+ if (mmutranslate_write(addr2+1) == 0xffffffff) return;
+ }
+ if (is386) {
+ writememb386l(seg,addr,val);
+ writememb386l(seg,addr+1,val>>8);
+ } else {
+ writemembl(seg+addr,val);
+ writemembl(seg+addr+1,val>>8);
+ }
+ return;
+ } else if (writelookup2[addr2 >> 12] != -1) {
+ *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val;
+ return;
+ }
+ }
+
+ if (page_lookup[addr2>>12]) {
+ page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]);
+ return;
+ }
+
+ if (cr0 >> 31) {
+ addr2 = mmutranslate_write(addr2);
+ if (addr2 == 0xffffffff) return;
+ }
+
+ addr2 &= rammask;
+
+#if 0
+ if (addr2 >= 0xa0000 && addr2 < 0xc0000)
+ pclog("writememwl %08X %02X\n", addr2, val);
+#endif
+
+ if (_mem_write_w[addr2 >> 14]) {
+ _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+
+ if (_mem_write_b[addr2 >> 14]) {
+ _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+}
+
+
+uint32_t
+readmemll(uint32_t seg, uint32_t addr)
+{
+ uint32_t addr2 = mem_logical_addr = seg + addr;
+
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+ return -1;
+ }
+
+ if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) {
+ addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
+ if (addr < mem_size * 1024)
+ return *((uint32_t *)&ram[addr]);
+ return 0xffffffff;
+ }
+
+ if (addr2 & 3) {
+ if (!cpu_cyrix_alignment || (addr2 & 7) > 4)
+ cycles -= timing_misaligned;
+ if ((addr2 & 0xfff) > 0xffc) {
+ if (cr0 >> 31) {
+ if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
+ if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff;
+ }
+ return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16);
+ } else if (readlookup2[addr2 >> 12] != -1)
+ return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2);
+ }
+
+ if (cr0 >> 31) {
+ addr2 = mmutranslate_read(addr2);
+ if (addr2 == 0xffffffff)
+ return 0xffffffff;
+ }
+
+ addr2 &= rammask;
+
+ if (_mem_read_l[addr2 >> 14])
+ return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
+
+ if (_mem_read_w[addr2 >> 14])
+ return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16);
+
+ if (_mem_read_b[addr2 >> 14])
+ return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14]) << 24);
+
+ return 0xffffffff;
+}
+
+
+void
+writememll(uint32_t seg, uint32_t addr, uint32_t val)
+{
+ uint32_t addr2 = mem_logical_addr = seg + addr;
+
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+ return;
+ }
+
+ if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) {
+ addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
+ if (addr < mem_size * 1024)
+ *((uint32_t *)&ram[addr]) = val;
+ return;
+ }
+
+ if (addr2 & 3) {
+ if (!cpu_cyrix_alignment || (addr2 & 7) > 4)
+ cycles -= timing_misaligned;
+ if ((addr2 & 0xfff) > 0xffc) {
+ if (cr0 >> 31) {
+ if (mmutranslate_write(addr2) == 0xffffffff) return;
+ if (mmutranslate_write(addr2+3) == 0xffffffff) return;
+ }
+ writememwl(seg,addr,val);
+ writememwl(seg,addr+2,val>>16);
+ return;
+ } else if (writelookup2[addr2 >> 12] != -1) {
+ *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val;
+ return;
+ }
+ }
+
+ if (page_lookup[addr2>>12]) {
+ page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]);
+ return;
+ }
+
+ if (cr0 >> 31) {
+ addr2 = mmutranslate_write(addr2);
+ if (addr2 == 0xffffffff) return;
+ }
+
+ addr2 &= rammask;
+
+ if (_mem_write_l[addr2 >> 14]) {
+ _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+ if (_mem_write_w[addr2 >> 14]) {
+ _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+ if (_mem_write_b[addr2 >> 14]) {
+ _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+}
+
+
+uint64_t
+readmemql(uint32_t seg, uint32_t addr)
+{
+ uint32_t addr2 = mem_logical_addr = seg + addr;
+
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+ return -1;
+ }
+
+ if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) {
+ addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
+ if (addr < mem_size * 1024)
+ return *((uint64_t *)&ram[addr]);
+ return -1;
+ }
+
+ if (addr2 & 7) {
+ cycles -= timing_misaligned;
+ if ((addr2 & 0xfff) > 0xff8) {
+ if (cr0 >> 31) {
+ if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
+ if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff;
+ }
+ return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32);
+ } else if (readlookup2[addr2 >> 12] != -1)
+ return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2);
+ }
+
+ if (cr0 >> 31) {
+ addr2 = mmutranslate_read(addr2);
+ if (addr2 == 0xffffffff)
+ return -1;
+ }
+
+ addr2 &= rammask;
+
+ if (_mem_read_l[addr2 >> 14])
+ return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) |
+ ((uint64_t)_mem_read_l[addr2 >> 14](addr2 + 4, _mem_priv_r[addr2 >> 14]) << 32);
+
+ return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32);
+}
+
+
+void
+writememql(uint32_t seg, uint32_t addr, uint64_t val)
+{
+ uint32_t addr2 = mem_logical_addr = seg + addr;
+
+ if (seg == -1) {
+ x86gpf("NULL segment", 0);
+ return;
+ }
+
+ if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) {
+ addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
+ if (addr < mem_size * 1024)
+ *((uint64_t *)&ram[addr]) = val;
+ return;
+ }
+
+ if (addr2 & 7) {
+ cycles -= timing_misaligned;
+ if ((addr2 & 0xfff) > 0xff8) {
+ if (cr0 >> 31) {
+ if (mmutranslate_write(addr2) == 0xffffffff) return;
+ if (mmutranslate_write(addr2+7) == 0xffffffff) return;
+ }
+ writememll(seg, addr, val);
+ writememll(seg, addr+4, val >> 32);
+ return;
+ } else if (writelookup2[addr2 >> 12] != -1) {
+ *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val;
+ return;
+ }
+ }
+
+ if (page_lookup[addr2>>12]) {
+ page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]);
+ page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]);
+ return;
+ }
+
+ if (cr0 >> 31) {
+ addr2 = mmutranslate_write(addr2);
+ if (addr2 == 0xffffffff) return;
+ }
+
+ addr2 &= rammask;
+
+ if (_mem_write_l[addr2 >> 14]) {
+ _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ _mem_write_l[addr2 >> 14](addr2+4, val >> 32, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+ if (_mem_write_w[addr2 >> 14]) {
+ _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
+ _mem_write_w[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]);
+ _mem_write_w[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+ if (_mem_write_b[addr2 >> 14]) {
+ _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 5, val >> 40, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]);
+ _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]);
+ return;
+ }
+}
+
+
+uint8_t
+mem_readb_phys(uint32_t addr)
+{
+ mem_logical_addr = 0xffffffff;
+
+ if (_mem_read_b[addr >> 14])
+ return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
+
+ return 0xff;
+}
+
+
+/*
+ * Version of mem_readby_phys that doesn't go through
+ * the CPU paging mechanism.
+ */
+uint8_t
+mem_readb_phys_dma(uint32_t addr)
+{
+#if 0
+ mem_logical_addr = 0xffffffff;
+#endif
+
+ if (_mem_exec[addr >> 14])
+ return _mem_exec[addr >> 14][addr & 0x3fff];
+ else if (_mem_read_b[addr >> 14])
+ return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
+ else
+ return 0xff;
+}
+
+
+uint16_t
+mem_readw_phys(uint32_t addr)
+{
+ mem_logical_addr = 0xffffffff;
+
+ if (_mem_read_w[addr >> 14])
+ return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]);
+
+ return 0xff;
+}
+
+
+void
+mem_writeb_phys(uint32_t addr, uint8_t val)
+{
+ mem_logical_addr = 0xffffffff;
+
+ if (_mem_write_b[addr >> 14])
+ _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
+}
+
+
+/*
+ * Version of mem_readby_phys that doesn't go through
+ * the CPU paging mechanism.
+ */
+void
+mem_writeb_phys_dma(uint32_t addr, uint8_t val)
+{
+#if 0
+ mem_logical_addr = 0xffffffff;
+#endif
+
+ if (_mem_exec[addr >> 14])
+ _mem_exec[addr >> 14][addr & 0x3fff] = val;
+ else if (_mem_write_b[addr >> 14])
+ _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
+}
+
+
+void
+mem_writew_phys(uint32_t addr, uint16_t val)
+{
+ mem_logical_addr = 0xffffffff;
+
+ if (_mem_write_w[addr >> 14])
+ _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
+}
+
+
+uint8_t
+mem_read_ram(uint32_t addr, void *priv)
+{
+ addreadlookup(mem_logical_addr, addr);
+
+ return ram[addr];
+}
+
+
+uint16_t
+mem_read_ramw(uint32_t addr, void *priv)
+{
+ addreadlookup(mem_logical_addr, addr);
+
+ return *(uint16_t *)&ram[addr];
+}
+
+
+uint32_t
+mem_read_raml(uint32_t addr, void *priv)
+{
+ addreadlookup(mem_logical_addr, addr);
+
+ return *(uint32_t *)&ram[addr];
+}
+
+
+void
+mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
+{
+#ifdef USE_DYNAREC
+ if (val != p->mem[addr & 0xfff] || codegen_in_recompile) {
+#else
+ if (val != p->mem[addr & 0xfff]) {
+#endif
+ uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
+ p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
+ p->mem[addr & 0xfff] = val;
+ }
+}
+
+
+void
+mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
+{
+#ifdef USE_DYNAREC
+ if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) {
+#else
+ if (val != *(uint16_t *)&p->mem[addr & 0xfff]) {
+#endif
+ uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
+ if ((addr & 0xf) == 0xf)
+ mask |= (mask << 1);
+ p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
+ *(uint16_t *)&p->mem[addr & 0xfff] = val;
+ }
+}
+
+
+void
+mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
+{
+#ifdef USE_DYNAREC
+ if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) {
+#else
+ if (val != *(uint32_t *)&p->mem[addr & 0xfff]) {
+#endif
+ uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
+ if ((addr & 0xf) >= 0xd)
+ mask |= (mask << 1);
+ p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
+ *(uint32_t *)&p->mem[addr & 0xfff] = val;
+ }
+}
+
+
+void
+mem_write_ram(uint32_t addr, uint8_t val, void *priv)
+{
+ addwritelookup(mem_logical_addr, addr);
+ mem_write_ramb_page(addr, val, &pages[addr >> 12]);
+}
+
+
+void
+mem_write_ramw(uint32_t addr, uint16_t val, void *priv)
+{
+ addwritelookup(mem_logical_addr, addr);
+ mem_write_ramw_page(addr, val, &pages[addr >> 12]);
+}
+
+
+void
+mem_write_raml(uint32_t addr, uint32_t val, void *priv)
+{
+ addwritelookup(mem_logical_addr, addr);
+ mem_write_raml_page(addr, val, &pages[addr >> 12]);
+}
+
+
+uint8_t
+mem_read_bios(uint32_t addr, void *priv)
+{
+ return rom[addr & biosmask];
+}
+
+
+uint16_t
+mem_read_biosw(uint32_t addr, void *priv)
+{
+ return *(uint16_t *)&rom[addr & biosmask];
+}
+
+
+uint32_t
+mem_read_biosl(uint32_t addr, void *priv)
+{
+ return *(uint32_t *)&rom[addr & biosmask];
+}
+
+
+uint8_t
+mem_read_romext(uint32_t addr, void *priv)
+{
+ return romext[addr & 0x7fff];
+}
+
+
+uint16_t
+mem_read_romextw(uint32_t addr, void *priv)
+{
+ uint16_t *p = (uint16_t *)&romext[addr & 0x7fff];
+
+ return *p;
+}
+
+
+uint32_t
+mem_read_romextl(uint32_t addr, void *priv)
+{
+ uint32_t *p = (uint32_t *)&romext[addr & 0x7fff];
+
+ return *p;
+}
+
+
+void
+mem_write_null(uint32_t addr, uint8_t val, void *p)
+{
+}
+
+
+void
+mem_write_nullw(uint32_t addr, uint16_t val, void *p)
+{
+}
+
+
+void
+mem_write_nulll(uint32_t addr, uint32_t val, void *p)
+{
+}
+
+
+void
+mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
+{
+ start_addr &= ~PAGE_MASK_MASK;
+ end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK;
+
+ for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) {
+ uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
+
+ pages[start_addr >> 12].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
+ }
+}
+
+
+static __inline int
+mem_mapping_read_allowed(uint32_t flags, int state)
+{
+ switch (state & MEM_READ_MASK) {
+ case MEM_READ_ANY:
+ return 1;
+
+ case MEM_READ_EXTERNAL:
+ return !(flags & MEM_MAPPING_INTERNAL);
+
+ case MEM_READ_INTERNAL:
+ return !(flags & MEM_MAPPING_EXTERNAL);
+
+ default:
+ fatal("mem_mapping_read_allowed : bad state %x\n", state);
+ }
+
+ return 0;
+}
+
+
+static __inline int
+mem_mapping_write_allowed(uint32_t flags, int state)
+{
+ switch (state & MEM_WRITE_MASK) {
+ case MEM_WRITE_DISABLED:
+ return 0;
+ case MEM_WRITE_ANY:
+ return 1;
+ case MEM_WRITE_EXTERNAL:
+ return !(flags & MEM_MAPPING_INTERNAL);
+ case MEM_WRITE_INTERNAL:
+ return !(flags & MEM_MAPPING_EXTERNAL);
+ default:
+ fatal("mem_mapping_write_allowed : bad state %x\n", state);
+ }
+
+ return 0;
+}
+
+
+static void
+mem_mapping_recalc(uint64_t base, uint64_t size)
+{
+ mem_mapping_t *mapping = base_mapping.next;
+ uint64_t c;
+
+ if (! size) return;
+
+ /* Clear out old mappings. */
+ for (c = base; c < base + size; c += 0x4000) {
+ _mem_read_b[c >> 14] = NULL;
+ _mem_read_w[c >> 14] = NULL;
+ _mem_read_l[c >> 14] = NULL;
+ _mem_priv_r[c >> 14] = NULL;
+ _mem_mapping_r[c >> 14] = NULL;
+ _mem_write_b[c >> 14] = NULL;
+ _mem_write_w[c >> 14] = NULL;
+ _mem_write_l[c >> 14] = NULL;
+ _mem_priv_w[c >> 14] = NULL;
+ _mem_mapping_w[c >> 14] = NULL;
+ }
+
+ /* Walk mapping list. */
+ while (mapping != NULL) {
+ /*In range?*/
+ if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base) {
+ uint64_t start = (mapping->base < base) ? mapping->base : base;
+ uint64_t end = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->size) : (base + size);
+ if (start < mapping->base)
+ start = mapping->base;
+
+ for (c = start; c < end; c += 0x4000) {
+ if ((mapping->read_b || mapping->read_w || mapping->read_l) &&
+ mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14])) {
+ _mem_read_b[c >> 14] = mapping->read_b;
+ _mem_read_w[c >> 14] = mapping->read_w;
+ _mem_read_l[c >> 14] = mapping->read_l;
+ if (mapping->exec)
+ _mem_exec[c >> 14] = mapping->exec + (c - mapping->base);
+ else
+ _mem_exec[c >> 14] = NULL;
+ _mem_priv_r[c >> 14] = mapping->p;
+ _mem_mapping_r[c >> 14] = mapping;
+ }
+ if ((mapping->write_b || mapping->write_w || mapping->write_l) &&
+ mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) {
+ _mem_write_b[c >> 14] = mapping->write_b;
+ _mem_write_w[c >> 14] = mapping->write_w;
+ _mem_write_l[c >> 14] = mapping->write_l;
+ _mem_priv_w[c >> 14] = mapping->p;
+ _mem_mapping_w[c >> 14] = mapping;
+ }
+ }
+ }
+ mapping = mapping->next;
+ }
+
+ flushmmucache_cr3();
+}
+
+
+void
+mem_mapping_add(mem_mapping_t *mapping,
+ uint32_t base,
+ uint32_t size,
+ uint8_t (*read_b)(uint32_t addr, void *p),
+ uint16_t (*read_w)(uint32_t addr, void *p),
+ uint32_t (*read_l)(uint32_t addr, void *p),
+ void (*write_b)(uint32_t addr, uint8_t val, void *p),
+ void (*write_w)(uint32_t addr, uint16_t val, void *p),
+ void (*write_l)(uint32_t addr, uint32_t val, void *p),
+ uint8_t *exec,
+ uint32_t flags,
+ void *p)
+{
+ mem_mapping_t *dest = &base_mapping;
+
+ /* Add mapping to the end of the list.*/
+ while (dest->next)
+ dest = dest->next;
+ dest->next = mapping;
+ mapping->prev = dest;
+
+ if (size)
+ mapping->enable = 1;
+ else
+ mapping->enable = 0;
+ mapping->base = base;
+ mapping->size = size;
+ mapping->read_b = read_b;
+ mapping->read_w = read_w;
+ mapping->read_l = read_l;
+ mapping->write_b = write_b;
+ mapping->write_w = write_w;
+ mapping->write_l = write_l;
+ mapping->exec = exec;
+ mapping->flags = flags;
+ mapping->p = p;
+ mapping->next = NULL;
+
+ mem_mapping_recalc(mapping->base, mapping->size);
+}
+
+
+void
+mem_mapping_set_handler(mem_mapping_t *mapping,
+ uint8_t (*read_b)(uint32_t addr, void *p),
+ uint16_t (*read_w)(uint32_t addr, void *p),
+ uint32_t (*read_l)(uint32_t addr, void *p),
+ void (*write_b)(uint32_t addr, uint8_t val, void *p),
+ void (*write_w)(uint32_t addr, uint16_t val, void *p),
+ void (*write_l)(uint32_t addr, uint32_t val, void *p))
+{
+ mapping->read_b = read_b;
+ mapping->read_w = read_w;
+ mapping->read_l = read_l;
+ mapping->write_b = write_b;
+ mapping->write_w = write_w;
+ mapping->write_l = write_l;
+
+ mem_mapping_recalc(mapping->base, mapping->size);
+}
+
+
+void
+mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size)
+{
+ /* Remove old mapping. */
+ mapping->enable = 0;
+ mem_mapping_recalc(mapping->base, mapping->size);
+
+ /* Set new mapping. */
+ mapping->enable = 1;
+ mapping->base = base;
+ mapping->size = size;
+
+ mem_mapping_recalc(mapping->base, mapping->size);
+}
+
+
+void
+mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec)
+{
+ mapping->exec = exec;
+
+ mem_mapping_recalc(mapping->base, mapping->size);
+}
+
+
+void
+mem_mapping_set_p(mem_mapping_t *mapping, void *p)
+{
+ mapping->p = p;
+}
+
+
+void
+mem_mapping_disable(mem_mapping_t *mapping)
+{
+ mapping->enable = 0;
+
+ mem_mapping_recalc(mapping->base, mapping->size);
+}
+
+
+void
+mem_mapping_enable(mem_mapping_t *mapping)
+{
+ mapping->enable = 1;
+
+ mem_mapping_recalc(mapping->base, mapping->size);
+}
+
+
+void
+mem_set_mem_state(uint32_t base, uint32_t size, int state)
+{
+ uint32_t c;
+
+ for (c = 0; c < size; c += 0x4000)
+ _mem_state[(c + base) >> 14] = state;
+
+ mem_mapping_recalc(base, size);
+}
+
+
+void
+mem_add_bios(void)
+{
+ if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) {
+ mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom,MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x4000 & biosmask),
+ MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x8000 & biosmask),
+ MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0xc000 & biosmask),
+ MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ }
+
+ mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x10000 & biosmask),
+ MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x14000 & biosmask),
+ MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x18000 & biosmask),
+ MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x1c000 & biosmask),
+ MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+
+ mem_mapping_add(&bios_high_mapping[0],
+ (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom, MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[1],
+ (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[2],
+ (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[3],
+ (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[4],
+ (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[5],
+ (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[6],
+ (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[7],
+ (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000,
+ mem_read_bios,mem_read_biosw,mem_read_biosl,
+ mem_write_null,mem_write_nullw,mem_write_nulll,
+ rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0);
+}
+
+
+void
+mem_a20_init(void)
+{
+ if (AT) {
+ rammask = cpu_16bitbus ? 0xefffff : 0xffefffff;
+ flushmmucache();
+ mem_a20_state = mem_a20_key | mem_a20_alt;
+ } else {
+ rammask = 0xfffff;
+ flushmmucache();
+ mem_a20_key = mem_a20_alt = mem_a20_state = 0;
+ }
+}
+
+
+/* Reset the memory state. */
+void
+mem_reset(void)
+{
+ uint32_t c, m;
+
+ /* Free the ROM memory and reset size mask. */
+ if (rom != NULL) {
+ free(rom);
+ rom = NULL;
+ }
+ biosmask = 0xffff;
+
+ /*
+ * Always allocate the full 16 MB memory space if memory size
+ * is smaller, we'll need this for stupid things like the PS/2
+ * split mapping.
+ */
+ if (mem_size < 16384)
+ m = 1024UL * 16384;
+ else
+ m = 1024UL * (mem_size + 384); /* 386 extra kB for top remapping */
+ if (ram != NULL) {
+ free(ram);
+ ram = NULL;
+ }
+ ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */
+ memset(ram, 0x00, m);
+
+ /*
+ * Allocate the page table based on how much RAM we have.
+ * We re-allocate the table on each (hard) reset, as the
+ * memory amount could have changed.
+ */
+ if (AT) {
+ if (cpu_16bitbus) {
+ /* 80186/286; maximum address space is 16MB. */
+ m = 4096;
+ } else {
+ /* 80386+; maximum address space is 4GB. */
+ m = (mem_size + 384) >> 2;
+ if ((m << 2) < (mem_size + 384))
+ m++;
+ if (m < 4096)
+ m = 4096;
+ }
+ } else {
+ /* 8088/86; maximum address space is 1MB. */
+ m = 256;
+ }
+
+ /*
+ * Allocate and initialize the (new) page table.
+ * We only do this if the size of the page table has changed.
+ */
+#if DYNAMIC_TABLES
+pclog("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz);
+#endif
+ if (pages_sz != m) {
+ pages_sz = m;
+ if (pages) {
+ free(pages);
+ pages = NULL;
+ }
+ pages = (page_t *)malloc(m*sizeof(page_t));
+#if DYNAMIC_TABLES
+pclog("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
+#endif
+
+#if DYNAMIC_TABLES
+ /* Allocate the (new) lookup tables. */
+ if (page_lookup != NULL) free(page_lookup);
+ page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *));
+
+ if (readlookup2 != NULL) free(readlookup2);
+ readlookup2 = malloc(pages_sz*sizeof(uintptr_t));
+
+ if (writelookup2 != NULL) free(writelookup2);
+ writelookup2 = malloc(pages_sz*sizeof(uintptr_t));
+
+#endif
+ }
+
+#if DYNAMIC_TABLES
+ memset(page_lookup, 0x00, pages_sz * sizeof(page_t *));
+#else
+ memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *));
+#endif
+
+ memset(pages, 0x00, pages_sz*sizeof(page_t));
+
+ for (c=0; c= 0xa && c <= 0xf) ||
+ (cpu_16bitbus && c >= 0xfe && c <= 0xff))
+ isram[c] = 0;
+ }
+
+ memset(_mem_read_b, 0x00, sizeof(_mem_read_b));
+ memset(_mem_read_w, 0x00, sizeof(_mem_read_w));
+ memset(_mem_read_l, 0x00, sizeof(_mem_read_l));
+ memset(_mem_write_b, 0x00, sizeof(_mem_write_b));
+ memset(_mem_write_w, 0x00, sizeof(_mem_write_w));
+ memset(_mem_write_l, 0x00, sizeof(_mem_write_l));
+ memset(_mem_exec, 0x00, sizeof(_mem_exec));
+
+ memset(&base_mapping, 0x00, sizeof(base_mapping));
+
+ memset(_mem_state, 0x00, sizeof(_mem_state));
+
+ mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024,
+ MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ mem_set_mem_state(0x0c0000, 0x40000,
+ MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+
+ mem_mapping_add(&ram_low_mapping, 0x00000,
+ (mem_size > 640) ? 0xa0000 : mem_size * 1024,
+ mem_read_ram,mem_read_ramw,mem_read_raml,
+ mem_write_ram,mem_write_ramw,mem_write_raml,
+ ram, MEM_MAPPING_INTERNAL, NULL);
+
+ if (mem_size > 1024) {
+ if (cpu_16bitbus && mem_size > 16256) {
+ mem_set_mem_state(0x100000, (16256 - 1024) * 1024,
+ MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ mem_mapping_add(&ram_high_mapping, 0x100000,
+ ((16256 - 1024) * 1024),
+ mem_read_ram,mem_read_ramw,mem_read_raml,
+ mem_write_ram,mem_write_ramw,mem_write_raml,
+ ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
+ } else {
+ mem_set_mem_state(0x100000, (mem_size - 1024) * 1024,
+ MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ mem_mapping_add(&ram_high_mapping, 0x100000,
+ ((mem_size - 1024) * 1024),
+ mem_read_ram,mem_read_ramw,mem_read_raml,
+ mem_write_ram,mem_write_ramw,mem_write_raml,
+ ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
+ }
+ }
+
+ if (mem_size > 768)
+ mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000,
+ mem_read_ram,mem_read_ramw,mem_read_raml,
+ mem_write_ram,mem_write_ramw,mem_write_raml,
+ ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
+
+ if (romset == ROM_IBMPS1_2011)
+ mem_mapping_add(&romext_mapping, 0xc8000, 0x08000,
+ mem_read_romext,mem_read_romextw,mem_read_romextl,
+ NULL,NULL, NULL, romext, 0, NULL);
+
+ mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024,
+ mem_read_ram,mem_read_ramw,mem_read_raml,
+ mem_write_ram,mem_write_ramw,mem_write_raml,
+ ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL);
+ mem_mapping_disable(&ram_remapped_mapping);
+
+ mem_a20_init();
+}
+
+
+void
+mem_init(void)
+{
+ /* Perform a one-time init. */
+ ram = rom = NULL;
+ pages = NULL;
+#if DYNAMIC_TABLES
+ page_lookup = NULL;
+ readlookup2 = NULL;
+ writelookup2 = NULL;
+
+#else
+ /* Allocate the lookup tables. */
+ page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *));
+
+ readlookup2 = malloc((1<<20)*sizeof(uintptr_t));
+
+ writelookup2 = malloc((1<<20)*sizeof(uintptr_t));
+#endif
+
+ memset(ram_mapped_addr, 0x00, 64 * sizeof(uint32_t));
+
+#if FIXME
+ memset(ff_array, 0xff, sizeof(ff_array));
+#endif
+
+ /* Reset the memory state. */
+ mem_reset();
+}
+
+
+static void
+mem_remap_top(int max_size)
+{
+ int c;
+
+ if (mem_size > 640) {
+ uint32_t start = (mem_size >= 1024) ? mem_size : 1024;
+ int size = mem_size - 640;
+ if (size > max_size)
+ size = max_size;
+
+ for (c = (start / 64); c < ((start + size - 1) / 64); c++)
+ isram[c] = 1;
+
+ mem_set_mem_state(start * 1024, size * 1024,
+ MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+ mem_mapping_set_addr(&ram_remapped_mapping,
+ start * 1024, size * 1024);
+ mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024));
+
+ flushmmucache();
+ }
+}
+
+
+void
+mem_remap_top_256k(void)
+{
+ mem_remap_top(256);
+}
+
+
+void
+mem_remap_top_384k(void)
+{
+ mem_remap_top(384);
+}
+
+
+void
+mem_reset_page_blocks(void)
+{
+ int c;
+
+ if (pages == NULL) return;
+
+ for (c = 0; c < ((mem_size * 1024) >> 12); c++) {
+ pages[c].write_b = mem_write_ramb_page;
+ pages[c].write_w = mem_write_ramw_page;
+ pages[c].write_l = mem_write_raml_page;
+ pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL;
+ pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL;
+ }
+}
+
+
+void
+mem_a20_recalc(void)
+{
+ int state;
+
+ if (! AT) {
+ rammask = 0xfffff;
+ flushmmucache();
+ mem_a20_key = mem_a20_alt = mem_a20_state = 0;
+
+ return;
+ }
+
+ state = mem_a20_key | mem_a20_alt;
+ if (state && !mem_a20_state) {
+ rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff;
+ flushmmucache();
+ } else if (!state && mem_a20_state) {
+ rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff;
+ flushmmucache();
+ }
+
+ mem_a20_state = state;
+}
+
+
+uint8_t
+port_92_read(uint16_t port, void *priv)
+{
+ return port_92_reg;
+}
+
+
+void
+port_92_write(uint16_t port, uint8_t val, void *priv)
+{
+ if ((mem_a20_alt ^ val) & 2) {
+ mem_a20_alt = (val & 2);
+ mem_a20_recalc();
+ }
+
+ if ((~port_92_reg & val) & 1) {
+ softresetx86();
+ cpu_set_edx();
+ }
+
+ port_92_reg = val;
+}
+
+
+void
+port_92_clear_reset(void)
+{
+ port_92_reg &= 2;
+}
+
+
+void
+port_92_add(void)
+{
+ io_sethandler(0x0092, 1,
+ port_92_read,NULL,NULL, port_92_write, NULL,NULL,NULL);
+}
+
+
+void
+port_92_remove(void)
+{
+ io_removehandler(0x0092, 1,
+ port_92_read,NULL,NULL, port_92_write,NULL,NULL, NULL);
+}
+
+
+void
+port_92_reset(void)
+{
+ port_92_reg = 0;
+ mem_a20_alt = 0;
+ mem_a20_recalc();
+
+ flushmmucache();
+}
diff --git a/src/mem.h b/src/mem.h
index f7f488435..660bab616 100644
--- a/src/mem.h
+++ b/src/mem.h
@@ -1,26 +1,154 @@
-/* Copyright holders: Sarah Walker, Tenshi
- see COPYING for more details
-*/
+/*
+ * VARCem Virtual ARchaeological Computer EMulator.
+ * An emulator of (mostly) x86-based PC systems and devices,
+ * using the ISA,EISA,VLB,MCA and PCI system buses, roughly
+ * spanning the era between 1981 and 1995.
+ *
+ * This file is part of the VARCem Project.
+ *
+ * Definitions for the memory interface.
+ *
+ * Version: @(#)mem.h 1.0.4 2018/03/16
+ *
+ * Authors: Fred N. van Kempen,
+ * Sarah Walker,
+ *
+ * Copyright 2017,2018 Fred N. van Kempen.
+ * Copyright 2008-2018 Sarah Walker.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ *
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307
+ * USA.
+ */
#ifndef EMU_MEM_H
# define EMU_MEM_H
-extern uint8_t *ram;
-extern uint32_t rammask;
+#define MEM_MAPPING_EXTERNAL 1 /* on external bus (ISA/PCI) */
+#define MEM_MAPPING_INTERNAL 2 /* on internal bus (RAM) */
+#define MEM_MAPPING_ROM 4 /* Executing from ROM may involve
+ * additional wait states. */
-extern int readlookup[256],readlookupp[256];
-extern uintptr_t *readlookup2;
-extern int readlnext;
-extern int writelookup[256],writelookupp[256];
-extern uintptr_t *writelookup2;
-extern int writelnext;
+#define MEM_MAP_TO_SHADOW_RAM_MASK 1
+#define MEM_MAP_TO_RAM_ADDR_MASK 2
+
+#define MEM_READ_ANY 0x00
+#define MEM_READ_INTERNAL 0x10
+#define MEM_READ_EXTERNAL 0x20
+#define MEM_READ_MASK 0xf0
+
+#define MEM_WRITE_ANY 0x00
+#define MEM_WRITE_INTERNAL 0x01
+#define MEM_WRITE_EXTERNAL 0x02
+#define MEM_WRITE_DISABLED 0x03
+#define MEM_WRITE_MASK 0x0f
+
+
+typedef struct _mem_mapping_ {
+ struct _mem_mapping_ *prev, *next;
+
+ int enable;
+
+ uint32_t base;
+ uint32_t size;
+
+ uint8_t (*read_b)(uint32_t addr, void *priv);
+ uint16_t (*read_w)(uint32_t addr, void *priv);
+ uint32_t (*read_l)(uint32_t addr, void *priv);
+ void (*write_b)(uint32_t addr, uint8_t val, void *priv);
+ void (*write_w)(uint32_t addr, uint16_t val, void *priv);
+ void (*write_l)(uint32_t addr, uint32_t val, void *priv);
+
+ uint8_t *exec;
+
+ uint32_t flags;
+
+ void *p;
+} mem_mapping_t;
+
+typedef struct _page_ {
+ void (*write_b)(uint32_t addr, uint8_t val, struct _page_ *p);
+ void (*write_w)(uint32_t addr, uint16_t val, struct _page_ *p);
+ void (*write_l)(uint32_t addr, uint32_t val, struct _page_ *p);
+
+ uint8_t *mem;
+
+ uint64_t code_present_mask[4],
+ dirty_mask[4];
+
+ struct codeblock_t *block[4], *block_2[4];
+
+ /*Head of codeblock tree associated with this page*/
+ struct codeblock_t *head;
+} page_t;
+
+
+extern uint8_t *ram;
+extern uint32_t rammask;
+
+extern uint8_t *rom;
+extern uint8_t romext[32768];
+extern uint32_t biosmask;
+
+extern int readlookup[256],
+ readlookupp[256];
+extern uintptr_t * readlookup2;
+extern int readlnext;
+extern int writelookup[256],
+ writelookupp[256];
+extern uintptr_t *writelookup2;
+extern int writelnext;
+extern uint32_t ram_mapped_addr[64];
+
+extern mem_mapping_t bios_mapping[8],
+ bios_high_mapping[8],
+ romext_mapping,
+ ram_low_mapping,
+ ram_mid_mapping,
+ ram_high_mapping;
+
+extern uint32_t mem_logical_addr;
+
+extern page_t *pages,
+ **page_lookup;
+
+extern uint32_t get_phys_virt,get_phys_phys;
+
+extern int shadowbios,
+ shadowbios_write;
+extern int readlnum,
+ writelnum;
+
+extern int nopageerrors;
+extern int memspeed[11];
+extern uint8_t isram[0x10000];
+
+extern int mmu_perm;
+
+extern int mem_a20_state,
+ mem_a20_alt,
+ mem_a20_key;
-extern int mmu_perm;
#define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a)))
#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
+
extern uint8_t readmembl(uint32_t addr);
extern void writemembl(uint32_t addr, uint8_t val);
extern uint8_t readmemb386l(uint32_t seg, uint32_t addr);
@@ -37,54 +165,7 @@ extern uint32_t mmutranslatereal(uint32_t addr, int rw);
extern void addreadlookup(uint32_t virt, uint32_t phys);
extern void addwritelookup(uint32_t virt, uint32_t phys);
-extern int shadowbios,shadowbios_write;
-extern int readlnum,writelnum;
-
-
-typedef struct mem_mapping_t
-{
- struct mem_mapping_t *prev, *next;
-
- int enable;
-
- uint32_t base;
- uint32_t size;
-
- uint8_t (*read_b)(uint32_t addr, void *priv);
- uint16_t (*read_w)(uint32_t addr, void *priv);
- uint32_t (*read_l)(uint32_t addr, void *priv);
- void (*write_b)(uint32_t addr, uint8_t val, void *priv);
- void (*write_w)(uint32_t addr, uint16_t val, void *priv);
- void (*write_l)(uint32_t addr, uint32_t val, void *priv);
-
- uint8_t *exec;
-
- uint32_t flags;
-
- void *p;
-} mem_mapping_t;
-
-/*Only present on external bus (ISA/PCI)*/
-#define MEM_MAPPING_EXTERNAL 1
-/*Only present on internal bus (RAM)*/
-#define MEM_MAPPING_INTERNAL 2
-/*Executing from ROM may involve additional wait states*/
-#define MEM_MAPPING_ROM 4
-
-extern uint8_t *ram,*rom;
-extern uint8_t romext[32768];
-extern int readlnum,writelnum;
-extern int memspeed[11];
-extern int nopageerrors;
-extern uint32_t biosmask;
-extern unsigned char isram[0x10000];
-
-#define MEM_MAP_TO_SHADOW_RAM_MASK 1
-#define MEM_MAP_TO_RAM_ADDR_MASK 2
-
-extern uint32_t ram_mapped_addr[64];
-
-void mem_mapping_add(mem_mapping_t *mapping,
+extern void mem_mapping_add(mem_mapping_t *mapping,
uint32_t base,
uint32_t size,
uint8_t (*read_b)(uint32_t addr, void *p),
@@ -96,149 +177,71 @@ void mem_mapping_add(mem_mapping_t *mapping,
uint8_t *exec,
uint32_t flags,
void *p);
-void mem_mapping_set_handler(mem_mapping_t *mapping,
+
+extern void mem_mapping_set_handler(mem_mapping_t *mapping,
uint8_t (*read_b)(uint32_t addr, void *p),
uint16_t (*read_w)(uint32_t addr, void *p),
uint32_t (*read_l)(uint32_t addr, void *p),
void (*write_b)(uint32_t addr, uint8_t val, void *p),
void (*write_w)(uint32_t addr, uint16_t val, void *p),
void (*write_l)(uint32_t addr, uint32_t val, void *p));
-void mem_mapping_set_p(mem_mapping_t *mapping, void *p);
-void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size);
-void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec);
-void mem_mapping_disable(mem_mapping_t *mapping);
-void mem_mapping_enable(mem_mapping_t *mapping);
-void mem_set_mem_state(uint32_t base, uint32_t size, int state);
+extern void mem_mapping_set_p(mem_mapping_t *mapping, void *p);
-#define MEM_READ_ANY 0x00
-#define MEM_READ_INTERNAL 0x10
-#define MEM_READ_EXTERNAL 0x20
-#define MEM_READ_MASK 0xf0
+extern void mem_mapping_set_addr(mem_mapping_t *mapping,
+ uint32_t base, uint32_t size);
+extern void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec);
+extern void mem_mapping_disable(mem_mapping_t *mapping);
+extern void mem_mapping_enable(mem_mapping_t *mapping);
-#define MEM_WRITE_ANY 0x00
-#define MEM_WRITE_INTERNAL 0x01
-#define MEM_WRITE_EXTERNAL 0x02
-#define MEM_WRITE_DISABLED 0x03
-#define MEM_WRITE_MASK 0x0f
+extern void mem_set_mem_state(uint32_t base, uint32_t size, int state);
-extern int mem_a20_state;
-extern int mem_a20_alt;
-extern int mem_a20_key;
-void mem_a20_recalc();
+extern uint8_t mem_readb_phys(uint32_t addr);
+extern uint8_t mem_readb_phys_dma(uint32_t addr);
+extern uint16_t mem_readw_phys(uint32_t addr);
+extern void mem_writeb_phys(uint32_t addr, uint8_t val);
+extern void mem_writeb_phys_dma(uint32_t addr, uint8_t val);
+extern void mem_writew_phys(uint32_t addr, uint16_t val);
-uint8_t mem_readb_phys(uint32_t addr);
-uint8_t mem_readb_phys_dma(uint32_t addr);
-uint16_t mem_readw_phys(uint32_t addr);
-void mem_writeb_phys(uint32_t addr, uint8_t val);
-void mem_writeb_phys_dma(uint32_t addr, uint8_t val);
-void mem_writew_phys(uint32_t addr, uint16_t val);
+extern uint8_t mem_read_ram(uint32_t addr, void *priv);
+extern uint16_t mem_read_ramw(uint32_t addr, void *priv);
+extern uint32_t mem_read_raml(uint32_t addr, void *priv);
+extern void mem_write_ram(uint32_t addr, uint8_t val, void *priv);
+extern void mem_write_ramw(uint32_t addr, uint16_t val, void *priv);
+extern void mem_write_raml(uint32_t addr, uint32_t val, void *priv);
-uint8_t mem_read_ram(uint32_t addr, void *priv);
-uint16_t mem_read_ramw(uint32_t addr, void *priv);
-uint32_t mem_read_raml(uint32_t addr, void *priv);
+extern uint8_t mem_read_bios(uint32_t addr, void *priv);
+extern uint16_t mem_read_biosw(uint32_t addr, void *priv);
+extern uint32_t mem_read_biosl(uint32_t addr, void *priv);
-void mem_write_ram(uint32_t addr, uint8_t val, void *priv);
-void mem_write_ramw(uint32_t addr, uint16_t val, void *priv);
-void mem_write_raml(uint32_t addr, uint32_t val, void *priv);
+extern void mem_write_null(uint32_t addr, uint8_t val, void *p);
+extern void mem_write_nullw(uint32_t addr, uint16_t val, void *p);
+extern void mem_write_nulll(uint32_t addr, uint32_t val, void *p);
-uint8_t mem_read_bios(uint32_t addr, void *priv);
-uint16_t mem_read_biosw(uint32_t addr, void *priv);
-uint32_t mem_read_biosl(uint32_t addr, void *priv);
+extern uint32_t mmutranslate_noabrt(uint32_t addr, int rw);
-void mem_write_null(uint32_t addr, uint8_t val, void *p);
-void mem_write_nullw(uint32_t addr, uint16_t val, void *p);
-void mem_write_nulll(uint32_t addr, uint32_t val, void *p);
+extern void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr);
-mem_mapping_t bios_mapping[8];
-mem_mapping_t bios_high_mapping[8];
-mem_mapping_t romext_mapping;
-
-extern mem_mapping_t ram_high_mapping;
-
-
-typedef struct page_t
-{
- void (*write_b)(uint32_t addr, uint8_t val, struct page_t *p);
- void (*write_w)(uint32_t addr, uint16_t val, struct page_t *p);
- void (*write_l)(uint32_t addr, uint32_t val, struct page_t *p);
-
- uint8_t *mem;
-
- struct codeblock_t *block[4], *block_2[4];
-
- /*Head of codeblock tree associated with this page*/
- struct codeblock_t *head;
-
- uint64_t code_present_mask[4], dirty_mask[4];
-} page_t;
-
-extern page_t *pages;
-
-extern page_t **page_lookup;
-
-uint32_t mmutranslate_noabrt(uint32_t addr, int rw);
-
-extern uint32_t get_phys_virt,get_phys_phys;
-
-#ifdef EMU_CPU_H
-static __inline uint32_t get_phys(uint32_t addr)
-{
- if (!((addr ^ get_phys_virt) & ~0xfff))
- return get_phys_phys | (addr & 0xfff);
-
- get_phys_virt = addr;
-
- if (!(cr0 >> 31))
- {
- get_phys_phys = (addr & rammask) & ~0xfff;
- return addr & rammask;
- }
-
- get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff;
- return get_phys_phys | (addr & 0xfff);
- /* return mmutranslatereal(addr, 0) & rammask; */
-}
-
-static __inline uint32_t get_phys_noabrt(uint32_t addr)
-{
- if (!(cr0 >> 31))
- return addr & rammask;
-
- return mmutranslate_noabrt(addr, 0) & rammask;
-}
-#endif
-
-void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr);
-
-extern uint32_t mem_logical_addr;
-
-void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p);
-void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p);
-void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p);
-void mem_flush_write_page(uint32_t addr, uint32_t virt);
+extern void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p);
+extern void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p);
+extern void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p);
+extern void mem_flush_write_page(uint32_t addr, uint32_t virt);
extern void mem_reset_page_blocks(void);
-extern mem_mapping_t ram_low_mapping;
-extern mem_mapping_t ram_mid_mapping;
-
-extern void mem_remap_top_256k(void);
-extern void mem_remap_top_384k(void);
-
extern void flushmmucache(void);
extern void flushmmucache_cr3(void);
extern void flushmmucache_nopc(void);
extern void mmu_invalidate(uint32_t addr);
+extern void mem_a20_recalc(void);
extern void mem_add_bios(void);
extern void mem_init(void);
-extern void mem_resize(void);
-
-extern void mem_destroy_pages(void);
-extern void mem_resize_pages(void);
+extern void mem_reset(void);
+extern void mem_remap_top_256k(void);
+extern void mem_remap_top_384k(void);
extern uint8_t port_92_read(uint16_t port, void *priv);
extern void port_92_write(uint16_t port, uint8_t val, void *priv);
@@ -248,4 +251,38 @@ extern void port_92_remove(void);
extern void port_92_reset(void);
+#ifdef EMU_CPU_H
+static __inline uint32_t get_phys(uint32_t addr)
+{
+ if (! ((addr ^ get_phys_virt) & ~0xfff))
+ return get_phys_phys | (addr & 0xfff);
+
+ get_phys_virt = addr;
+
+ if (! (cr0 >> 31)) {
+ get_phys_phys = (addr & rammask) & ~0xfff;
+
+ return addr & rammask;
+ }
+
+ get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff;
+
+#if 1
+ return get_phys_phys | (addr & 0xfff);
+#else
+ return mmutranslatereal(addr, 0) & rammask;
+#endif
+}
+
+
+static __inline uint32_t get_phys_noabrt(uint32_t addr)
+{
+ if (! (cr0 >> 31))
+ return addr & rammask;
+
+ return mmutranslate_noabrt(addr, 0) & rammask;
+}
+#endif
+
+
#endif /*EMU_MEM_H*/
diff --git a/src/mouse.c b/src/mouse.c
index 62fd322f7..89fe585ea 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -11,7 +11,7 @@
* TODO: Add the Genius bus- and serial mouse.
* Remove the '3-button' flag from mouse types.
*
- * Version: @(#)mouse.c 1.0.24 2018/03/19
+ * Version: @(#)mouse.c 1.0.25 2018/03/19
*
* Authors: Miran Grca,
* Fred N. van Kempen,
@@ -142,7 +142,7 @@ mouse_process(void)
{
static int poll_delay = 2;
- if ((mouse_curr != NULL) || (mouse_type == MOUSE_TYPE_INTERNAL))
+ if ((mouse_curr == NULL) || (mouse_type == MOUSE_TYPE_INTERNAL))
return;
if (--poll_delay) return;
diff --git a/src/pc.c b/src/pc.c
index 38595a0da..172875c0a 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.66 2018/03/19
+ * Version: @(#)pc.c 1.0.67 2018/03/19
*
* Authors: Sarah Walker,
* Miran Grca,
@@ -558,8 +558,6 @@ pc_reload(wchar_t *fn)
fdd_load(2, floppyfns[2]);
fdd_load(3, floppyfns[3]);
- mem_resize();
- rom_load_bios(romset);
network_init();
pc_reset_hard_init();
@@ -947,8 +945,6 @@ pc_close(thread_t *ptr)
sound_cd_thread_end();
- mem_destroy_pages();
-
ide_destroy_buffers();
cdrom_destroy_drives();
diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c
index 5efd751d1..0e271ea2d 100644
--- a/src/sound/snd_lpt_dac.c
+++ b/src/sound/snd_lpt_dac.c
@@ -104,7 +104,7 @@ static void dac_close(void *p)
free(lpt_dac);
}
-lpt_device_t lpt_dac_device =
+const lpt_device_t lpt_dac_device =
{
"LPT DAC / Covox Speech Thing",
dac_init,
@@ -113,7 +113,7 @@ lpt_device_t lpt_dac_device =
dac_write_ctrl,
dac_read_status
};
-lpt_device_t lpt_dac_stereo_device =
+const lpt_device_t lpt_dac_stereo_device =
{
"Stereo LPT DAC",
dac_stereo_init,
diff --git a/src/sound/snd_lpt_dac.h b/src/sound/snd_lpt_dac.h
index 7db7a34dd..d9f505353 100644
--- a/src/sound/snd_lpt_dac.h
+++ b/src/sound/snd_lpt_dac.h
@@ -1,2 +1,2 @@
-extern lpt_device_t lpt_dac_device;
-extern lpt_device_t lpt_dac_stereo_device;
+extern const lpt_device_t lpt_dac_device;
+extern const lpt_device_t lpt_dac_stereo_device;
diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c
index 2042a6494..bacd1e706 100644
--- a/src/sound/snd_lpt_dss.c
+++ b/src/sound/snd_lpt_dss.c
@@ -109,7 +109,7 @@ static void dss_close(void *p)
free(dss);
}
-lpt_device_t dss_device =
+const lpt_device_t dss_device =
{
"Disney Sound Source",
dss_init,
diff --git a/src/sound/snd_lpt_dss.h b/src/sound/snd_lpt_dss.h
index b7d8fcbc1..07d37617a 100644
--- a/src/sound/snd_lpt_dss.h
+++ b/src/sound/snd_lpt_dss.h
@@ -1 +1 @@
-extern lpt_device_t dss_device;
+extern const lpt_device_t dss_device;
diff --git a/src/video/vid_table.c b/src/video/vid_table.c
index 38337d5fe..365619145 100644
--- a/src/video/vid_table.c
+++ b/src/video/vid_table.c
@@ -8,7 +8,7 @@
*
* Define all known video cards.
*
- * Version: @(#)vid_table.c 1.0.24 2018/03/15
+ * Version: @(#)vid_table.c 1.0.25 2018/03/19
*
* Authors: Miran Grca,
* Fred N. van Kempen,
@@ -74,105 +74,105 @@ enum {
#define VIDEO_FLAG_TYPE_MASK 3
typedef struct {
- const char *name;
- const char *internal_name;
+ const char *name;
+ const char *internal_name;
const device_t *device;
- int legacy_id;
- int flags;
+ int legacy_id;
+ int flags;
video_timings_t timing;
} VIDEO_CARD;
static const VIDEO_CARD
video_cards[] = {
- { "None", "none", NULL, GFX_NONE },
- { "Internal", "internal", NULL, GFX_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, GFX_MACH64GX_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
- {"[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
- { "[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, GFX_VGA88, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
- { "[ISA] ATI VGA Edge-16 (ATI-18800-5)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] ATI VGA Wonder (ATI-18800)", "ati18800w", &ati18800_wonder_device, GFX_VGAWONDER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "None", "none", NULL, GFX_NONE },
+ { "Internal", "internal", NULL, GFX_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, GFX_MACH64GX_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
+ { "[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
+ { "[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, GFX_VGA88, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
+ { "[ISA] ATI VGA Edge-16 (ATI-18800-5)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] ATI VGA Wonder (ATI-18800)", "ati18800w", &ati18800_wonder_device, GFX_VGAWONDER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
#if defined(DEV_BRANCH) && defined(USE_XL24)
- { "[ISA] ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device,GFX_VGAWONDERXL24, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
+ { "[ISA] ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
#endif
- { "[ISA] CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] Cirrus Logic CL-GD 5428", "cl_gd5428_isa", &gd5428_isa_device, GFX_CL_GD5428_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
- { "[ISA] Cirrus Logic CL-GD 5429", "cl_gd5429_isa", &gd5429_isa_device, GFX_CL_GD5429_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
- { "[ISA] Cirrus Logic CL-GD 5434", "cl_gd5434_isa", &gd5434_isa_device, GFX_CL_GD5434_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
- { "[ISA] Compaq ATI VGA Wonder XL (ATI-28800-5)","compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
- { "[ISA] Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] Compaq CGA 2", "compaq_cga_2", &compaq_cga_2_device, GFX_COMPAQ_CGA_2, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] Compaq EGA", "compaq_ega", &cpqega_device, GFX_COMPAQ_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- { "[ISA] MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- {"[ISA] OAK OTI-037C", "oti037c", &oti037c_device, GFX_OTI037C, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
- {"[ISA] OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
- {"[ISA] OAK OTI-077", "oti077", &oti077_device, GFX_OTI077, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
- {"[ISA] Paradise PVGA1A", "pvga1a", ¶dise_pvga1a_device, GFX_PVGA1A, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- {"[ISA] Paradise WD90C11-LR", "wd90c11", ¶dise_wd90c11_device, GFX_WD90C11, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- {"[ISA] Paradise WD90C30-LR", "wd90c30", ¶dise_wd90c30_device, GFX_WD90C30, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
- {"[ISA] Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Cirrus Logic CL-GD 5428", "cl_gd5428_isa", &gd5428_isa_device, GFX_CL_GD5428_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
+ { "[ISA] Cirrus Logic CL-GD 5429", "cl_gd5429_isa", &gd5429_isa_device, GFX_CL_GD5429_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
+ { "[ISA] Cirrus Logic CL-GD 5434", "cl_gd5434_isa", &gd5434_isa_device, GFX_CL_GD5434_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
+ { "[ISA] Compaq ATI VGA Wonder XL (ATI-28800-5)", "compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
+ { "[ISA] Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Compaq CGA 2", "compaq_cga_2", &compaq_cga_2_device, GFX_COMPAQ_CGA_2, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Compaq EGA", "compaq_ega", &cpqega_device, GFX_COMPAQ_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] OAK OTI-037C", "oti037c", &oti037c_device, GFX_OTI037C, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
+ { "[ISA] OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
+ { "[ISA] OAK OTI-077", "oti077", &oti077_device, GFX_OTI077, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
+ { "[ISA] Paradise PVGA1A", "pvga1a", ¶dise_pvga1a_device, GFX_PVGA1A, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Paradise WD90C11-LR", "wd90c11", ¶dise_wd90c11_device, GFX_WD90C11, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] Paradise WD90C30-LR", "wd90c30", ¶dise_wd90c30_device, GFX_WD90C30, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
+ { "[ISA] Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
#if defined(DEV_BRANCH) && defined(USE_TI)
- {"[ISA] TI CF62011 SVGA", "ti_cf62011", &ti_cf62011_device, GFX_TICF62011, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ { "[ISA] TI CF62011 SVGA", "ti_cf62011", &ti_cf62011_device, GFX_TICF62011, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
#endif
- {"[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
- {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
- {"[ISA] VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- {"[ISA] Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
- {"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, GFX_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
- {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
- {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device,GFX_ET4000W32_CARDEX_PCI,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
- {"[PCI] Cirrus Logic CL-GD 5430", "cl_gd5430_pci", &gd5430_pci_device, GFX_CL_GD5430_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
- {"[PCI] Cirrus Logic CL-GD 5434", "cl_gd5434_pci", &gd5434_pci_device, GFX_CL_GD5434_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
- {"[PCI] Cirrus Logic CL-GD 5436", "cl_gd5436_pci", &gd5436_pci_device, GFX_CL_GD5436_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
+ {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
+ {"[ISA] VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ {"[ISA] Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
+ {"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, GFX_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
+ {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
+ {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, GFX_ET4000W32_CARDEX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
+ {"[PCI] Cirrus Logic CL-GD 5430", "cl_gd5430_pci", &gd5430_pci_device, GFX_CL_GD5430_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[PCI] Cirrus Logic CL-GD 5434", "cl_gd5434_pci", &gd5434_pci_device, GFX_CL_GD5434_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[PCI] Cirrus Logic CL-GD 5436", "cl_gd5436_pci", &gd5436_pci_device, GFX_CL_GD5436_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
#if defined(DEV_BRANCH) && defined(USE_STEALTH32)
- {"[PCI] Diamond Stealth 32 (Tseng ET4000/w32p)","stealth32_pci", &et4000w32p_pci_device, GFX_ET4000W32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
+ {"[PCI] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_pci", &et4000w32p_pci_device, GFX_ET4000W32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
#endif
- {"[PCI] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_pci",&s3_virge_pci_device, GFX_VIRGE_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
- {"[PCI] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_pci",&s3_virge_988_pci_device, GFX_VIRGEVX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
- {"[PCI] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_pci", &s3_diamond_stealth64_pci_device,GFX_STEALTH64_PCI,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
+ {"[PCI] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_pci", &s3_virge_pci_device, GFX_VIRGE_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
+ {"[PCI] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_pci", &s3_virge_988_pci_device, GFX_VIRGEVX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
+ {"[PCI] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_pci", &s3_diamond_stealth64_pci_device, GFX_STEALTH64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
#if defined(DEV_BRANCH) && defined(USE_RIVA)
- {"[PCI] nVidia RIVA 128", "riva128", &riva128_device, GFX_RIVA128, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},
- {"[PCI] nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},
- {"[PCI] nVidia RIVA TNT2", "rivatnt2", &rivatnt2_device, GFX_RIVATNT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},
+ {"[PCI] nVidia RIVA 128", "riva128", &riva128_device, GFX_RIVA128, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},
+ {"[PCI] nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},
+ {"[PCI] nVidia RIVA TNT2", "rivatnt2", &rivatnt2_device, GFX_RIVATNT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},
#endif
- {"[PCI] Number Nine 9FX (S3 Trio64)", "n9_9fx_pci", &s3_9fx_pci_device, GFX_N9_9FX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
- {"[PCI] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_pci", &s3_bahamas64_pci_device, GFX_BAHAMAS64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
- {"[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device,GFX_PHOENIX_VISION864_PCI,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
- {"[PCI] Phoenix S3 Trio32", "px_trio32_pci", &s3_phoenix_trio32_pci_device,GFX_PHOENIX_TRIO32_PCI,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
- {"[PCI] Phoenix S3 Trio64", "px_trio64_pci", &s3_phoenix_trio64_pci_device,GFX_PHOENIX_TRIO64_PCI,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
- {"[PCI] S3 ViRGE/DX", "virge375_pci", &s3_virge_375_pci_device, GFX_VIRGEDX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
- {"[PCI] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_pci",&s3_virge_375_4_pci_device,GFX_VIRGEDX4_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
- {"[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device, GFX_TGUI9440_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},
- {"[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device, GFX_MACH64GX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
- {"[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device,GFX_ET4000W32_CARDEX_VLB,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
- {"[VLB] Cirrus Logic CL-GD 5428", "cl_gd5428_vlb", &gd5428_vlb_device, GFX_CL_GD5428_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
- {"[VLB] Cirrus Logic CL-GD 5429", "cl_gd5429_vlb", &gd5429_vlb_device, GFX_CL_GD5429_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
- {"[VLB] Cirrus Logic CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device, GFX_CL_GD5434_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[PCI] Number Nine 9FX (S3 Trio64)", "n9_9fx_pci", &s3_9fx_pci_device, GFX_N9_9FX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
+ {"[PCI] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_pci", &s3_bahamas64_pci_device, GFX_BAHAMAS64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
+ {"[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device, GFX_PHOENIX_VISION864_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
+ {"[PCI] Phoenix S3 Trio32", "px_trio32_pci", &s3_phoenix_trio32_pci_device, GFX_PHOENIX_TRIO32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
+ {"[PCI] Phoenix S3 Trio64", "px_trio64_pci", &s3_phoenix_trio64_pci_device, GFX_PHOENIX_TRIO64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
+ {"[PCI] S3 ViRGE/DX", "virge375_pci", &s3_virge_375_pci_device, GFX_VIRGEDX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
+ {"[PCI] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_pci", &s3_virge_375_4_pci_device, GFX_VIRGEDX4_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
+ {"[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device, GFX_TGUI9440_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},
+ {"[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device, GFX_MACH64GX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
+ {"[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device, GFX_ET4000W32_CARDEX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
+ {"[VLB] Cirrus Logic CL-GD 5428", "cl_gd5428_vlb", &gd5428_vlb_device, GFX_CL_GD5428_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[VLB] Cirrus Logic CL-GD 5429", "cl_gd5429_vlb", &gd5429_vlb_device, GFX_CL_GD5429_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[VLB] Cirrus Logic CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device, GFX_CL_GD5434_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
#if defined(DEV_BRANCH) && defined(USE_STEALTH32)
- {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)","stealth32_vlb", &et4000w32p_vlb_device, GFX_ET4000W32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
+ {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_vlb", &et4000w32p_vlb_device, GFX_ET4000W32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},
#endif
- {"[VLB] Diamond SpeedStar PRO (CL-GD5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
- {"[VLB] Diamond SpeedStar PRO SE (CL-GD5430)", "cl_gd5430_vlb", &gd5430_vlb_device, GFX_CL_GD5430_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
- {"[VLB] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_vlb",&s3_virge_vlb_device, GFX_VIRGE_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
- {"[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb",&s3_virge_988_vlb_device, GFX_VIRGEVX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
- {"[VLB] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_vlb", &s3_diamond_stealth64_vlb_device,GFX_STEALTH64_VLB,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
- {"[VLB] Number Nine 9FX (S3 Trio64)", "n9_9fx_vlb", &s3_9fx_vlb_device, GFX_N9_9FX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
- {"[VLB] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_vlb", &s3_bahamas64_vlb_device, GFX_BAHAMAS64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
- {"[VLB] Phoenix S3 Vision864", "px_vision864_vlb", &s3_phoenix_vision864_vlb_device,GFX_PHOENIX_VISION864_VLB,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
- {"[VLB] Phoenix S3 Trio32", "px_trio32_vlb", &s3_phoenix_trio32_vlb_device,GFX_PHOENIX_TRIO32_VLB,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
- {"[VLB] Phoenix S3 Trio64", "px_trio64_vlb", &s3_phoenix_trio64_vlb_device,GFX_PHOENIX_TRIO64_VLB,VIDEO_FLAG_TYPE_SPECIAL,{VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
- {"[VLB] S3 ViRGE/DX", "virge375_vlb", &s3_virge_375_vlb_device, GFX_VIRGEDX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
- {"[VLB] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_vlb",&s3_virge_375_4_vlb_device,GFX_VIRGEDX4_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
- {"[VLB] Trident TGUI9400CXi", "tgui9400cxi_vlb", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},
- {"[VLB] Trident TGUI9440", "tgui9440_vlb", &tgui9440_vlb_device, GFX_TGUI9440_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},
- {"", "", NULL, -1 }
+ {"[VLB] Diamond SpeedStar PRO (CL-GD5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[VLB] Diamond SpeedStar PRO SE (CL-GD5430)", "cl_gd5430_vlb", &gd5430_vlb_device, GFX_CL_GD5430_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}},
+ {"[VLB] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_vlb", &s3_virge_vlb_device, GFX_VIRGE_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
+ {"[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb", &s3_virge_988_vlb_device, GFX_VIRGEVX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
+ {"[VLB] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_vlb", &s3_diamond_stealth64_vlb_device, GFX_STEALTH64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}},
+ {"[VLB] Number Nine 9FX (S3 Trio64)", "n9_9fx_vlb", &s3_9fx_vlb_device, GFX_N9_9FX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
+ {"[VLB] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_vlb", &s3_bahamas64_vlb_device, GFX_BAHAMAS64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
+ {"[VLB] Phoenix S3 Vision864", "px_vision864_vlb", &s3_phoenix_vision864_vlb_device, GFX_PHOENIX_VISION864_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
+ {"[VLB] Phoenix S3 Trio32", "px_trio32_vlb", &s3_phoenix_trio32_vlb_device, GFX_PHOENIX_TRIO32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
+ {"[VLB] Phoenix S3 Trio64", "px_trio64_vlb", &s3_phoenix_trio64_vlb_device, GFX_PHOENIX_TRIO64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
+ {"[VLB] S3 ViRGE/DX", "virge375_vlb", &s3_virge_375_vlb_device, GFX_VIRGEDX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
+ {"[VLB] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device, GFX_VIRGEDX4_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
+ {"[VLB] Trident TGUI9400CXi", "tgui9400cxi_vlb", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},
+ {"[VLB] Trident TGUI9440", "tgui9440_vlb", &tgui9440_vlb_device, GFX_TGUI9440_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},
+ {"", "", NULL, -1 }
};