diff --git a/CMakeLists.txt b/CMakeLists.txt
index abfe1b7f4..10f85ee55 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,7 +106,6 @@ option(FLUIDSYNTH   "FluidSynth"
 option(MUNT         "MUNT"                                                          ON)
 option(VRAMDUMP     "Video RAM dumping"                                             OFF)
 option(DINPUT       "DirectInput"                                                   OFF)
-option(DISCORD      "Discord integration"                                           ON)
 option(CPPTHREADS   "C++11 threads"                                                 ON)
 option(NEW_DYNAREC  "Use the PCem v15 (\"new\") dynamic recompiler"                 OFF)
 option(MINITRACE    "Enable Chrome tracing using the modified minitrace library"    OFF)
@@ -120,24 +119,16 @@ option(QT           "QT GUI"
 cmake_dependent_option(AMD_K5       "AMD K5"                                        ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(CYRIX_6X86   "Cyrix 6x86"                                    ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(GUSMAX       "Gravis UltraSound MAX"                         ON      "DEV_BRANCH"    OFF)
-cmake_dependent_option(HEDAKA       "Hedaka HED-919"                                ON      "DEV_BRANCH"    OFF)
-cmake_dependent_option(I450KX       "Intel i450KX"                                  ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(LASERXT      "VTech Laser XT"                                ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(MGA          "Matrox Mystique graphics adapters"             ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(NO_SIO       "Machines without emulated Super I/O chips"     ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(OLIVETTI     "Olivetti M290"                                 ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(OPEN_AT      "OpenAT"                                        ON      "DEV_BRANCH"    OFF)
-cmake_dependent_option(OPENGL       "OpenGL 3.0 Core renderer"                      ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(PAS16        "Pro Audio Spectrum 16"                         OFF     "DEV_BRANCH"    OFF)
-cmake_dependent_option(PS2M70T4     "IBM PS/2 model 70 (type 4)"                    ON      "DEV_BRANCH"    OFF)
-cmake_dependent_option(S3TRIO3D2X   "S3 Trio3D/2X"                                  ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(SIO_DETECT   "Super I/O Detection Helper"                    ON      "DEV_BRANCH"    OFF)
-cmake_dependent_option(M154X        "ALi ALADDiN IV"                                ON      "DEV_BRANCH"    OFF)
-cmake_dependent_option(M6117        "ALi M6117"                                     ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(VGAWONDER    "ATI VGA Wonder (ATI-18800)"                    ON      "DEV_BRANCH"    OFF)
 cmake_dependent_option(VNC          "VNC renderer"                                  OFF     "DEV_BRANCH"    OFF)
 cmake_dependent_option(XL24         "ATI VGA Wonder XL24 (ATI-28800-6)"             ON      "DEV_BRANCH"    OFF)
-cmake_dependent_option(VECT486VL    "HP Vectra 486VL"                               ON      "DEV_BRANCH"    OFF)
 
 # Determine the build type
 set(RELEASE_BUILD   OFF)
diff --git a/src/config.c b/src/config.c
index 2299897db..bda66d417 100644
--- a/src/config.c
+++ b/src/config.c
@@ -644,6 +644,8 @@ load_machine(void)
 		machine = machine_get_machine_from_internal_name("s1857");
 	else if (! strcmp(p, "63a"))
 		machine = machine_get_machine_from_internal_name("63a1");
+	else if (! strcmp(p, "4sa2"))
+		machine = machine_get_machine_from_internal_name("4saw2");
 	else if (! strcmp(p, "award386dx")) /* ...merged machines... */
 		machine = machine_get_machine_from_internal_name("award495");
 	else if (! strcmp(p, "ami386dx"))
@@ -656,6 +658,8 @@ load_machine(void)
 		machine = machine_get_machine_from_internal_name("ami495");
 	else if (! strcmp(p, "mr486"))
 		machine = machine_get_machine_from_internal_name("mr495");
+	else if (! strcmp(p, "ibmps1_2121_isa"))
+		machine = machine_get_machine_from_internal_name("ibmps1_2121");
 	else if (! strcmp(p, "fw6400gx_s1"))
 		machine = machine_get_machine_from_internal_name("fw6400gx");
 	else if (! strcmp(p, "p54vl"))
@@ -910,15 +914,30 @@ load_input_devices(void)
 
     p = config_get_string(cat, "joystick_type", NULL);
     if (p != NULL) {
+	if (!strcmp(p, "standard_2button"))
+		joystick_type = joystick_get_from_internal_name("2axis_2button");
+	else if (!strcmp(p, "standard_4button"))
+		joystick_type = joystick_get_from_internal_name("2axis_4button");
+	else if (!strcmp(p, "standard_6button"))
+		joystick_type = joystick_get_from_internal_name("2axis_6button");
+	else if (!strcmp(p, "standard_8button"))
+		joystick_type = joystick_get_from_internal_name("2axis_8button");
+
 	joystick_type = joystick_get_from_internal_name(p);
 	if (!joystick_type) {
 		/* Try to read an integer for backwards compatibility with old configs */
 		c = config_get_int(cat, "joystick_type", 8);
-		if ((c >= 0) && (c < 8))
-			/* "None" was type 8 instead of 0 previously, shift the number accordingly */
-			joystick_type = c + 1;
-		else
-			joystick_type = 0;
+		switch (c) {
+			case 0: case 1: case 2: case 3: /* 2-axis joysticks */
+				joystick_type = c + 1;
+				break;
+			case 4: case 5: case 6: case 7: /* other joysticks */
+				joystick_type = c + 3;
+				break;
+			default: /* "None" (8) or invalid value */
+				joystick_type = 0;
+				break;
+		}
 	}
     } else
 	joystick_type = 0;
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 7021a83e4..2004d7336 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -56,10 +56,12 @@ enum {
         CPUID_TSC = (1 << 4),
         CPUID_MSR = (1 << 5),
         CPUID_PAE = (1 << 6),
+        CPUID_MCE = (1 << 7),
         CPUID_CMPXCHG8B = (1 << 8),
 	CPUID_AMDSEP = (1 << 10),
 	CPUID_SEP = (1 << 11),
 	CPUID_MTRR = (1 << 12),
+        CPUID_MCA = (1 << 14),
         CPUID_CMOV = (1 << 15),
         CPUID_MMX = (1 << 23),
 	CPUID_FXSR = (1 << 24)
@@ -1616,7 +1618,7 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
+			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B;
 		} else
 			EAX = EBX = ECX = EDX = 0;
 		break;
@@ -1631,7 +1633,7 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
+			EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B;
 		} else
 			EAX = EBX = ECX = EDX = 0;
 		break;
@@ -1645,14 +1647,14 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
+			EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B;
 		} else if (EAX == 0x80000000) {
 			EAX = 0x80000005;
 			EBX = ECX = EDX = 0;
 		} else if (EAX == 0x80000001) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
+			EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B;
 		} else if (EAX == 0x80000002) {
 			EAX = 0x2D444D41;
 			EBX = 0x7428354B;
@@ -1682,14 +1684,14 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
+			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
 		} else if (EAX == 0x80000000) {
 			EAX = 0x80000005;
 			EBX = ECX = EDX = 0;
 		} else if (EAX == 0x80000001) {
 			EAX = CPUID + 0x100;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX;
+			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX;
 		} else if (EAX == 0x80000002) {
 			EAX = 0x2D444D41;
 			EBX = 0x6D74364B;
@@ -1729,14 +1731,14 @@ cpu_CPUID(void)
 			case 1:
 				EAX = CPUID;
 				EBX = ECX = 0;
-				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
+				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
 				break;
 			case 0x80000000:
 				EAX = 0x80000005;
 				break;
 			case 0x80000001:
 				EAX = CPUID + 0x100;
-				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW;
+				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW;
 				break;
 			case 0x80000002:	/* Processor name string */
 				EAX = 0x2d444d41;	/* AMD-K6(tm) 3D pr */
@@ -1772,14 +1774,14 @@ cpu_CPUID(void)
 			case 1:
 				EAX = CPUID;
 				EBX = ECX = 0;
-				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
+				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
 				break;
 			case 0x80000000:
 				EAX = 0x80000006;
 				break;
 			case 0x80000001:
 				EAX = CPUID + 0x100;
-				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW;
+				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW;
 				break;
 			case 0x80000002:	/* Processor name string */
 				EAX = 0x2d444d41;	/* AMD-K6(tm) 3D+ P */
@@ -1819,14 +1821,14 @@ cpu_CPUID(void)
 			case 1:
 				EAX = CPUID;
 				EBX = ECX = 0;
-				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
+				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
 				break;
 			case 0x80000000:
 				EAX = 0x80000007;
 				break;
 			case 0x80000001:
 				EAX = CPUID + 0x100;
-				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW;
+				EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW;
 				break;
 			case 0x80000002:	/* Processor name string */
 				EAX = 0x2d444d41;	/* AMD-K6(tm)-III P */
@@ -1869,7 +1871,7 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
+			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
 		} else
 			EAX = EBX = ECX = EDX = 0;
 		break;
@@ -1941,7 +1943,7 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_SEP | CPUID_CMOV;
+			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
 		} else if (EAX == 2) {
 			EAX = 0x00000001;
 			EBX = ECX = 0;
@@ -1959,7 +1961,7 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_CMOV;
+			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
 		} else if (EAX == 2) {
 			EAX = 0x00000001;
 			EBX = ECX = 0;
@@ -1977,7 +1979,7 @@ cpu_CPUID(void)
 		} else if (EAX == 1) {
 			EAX = CPUID;
 			EBX = ECX = 0;
-			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_FXSR | CPUID_CMOV;
+			EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV;
 		} else if (EAX == 2) {
 			EAX = 0x00000001;
 			EBX = ECX = 0;
@@ -2003,7 +2005,7 @@ cpu_CPUID(void)
 			case 1:
 				EAX = CPUID;
 				EBX = ECX = 0;
-				EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR;
+				EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR;
 				if (cpu_has_feature(CPU_FEATURE_CX8))
 					EDX |= CPUID_CMPXCHG8B;							
 				break;
@@ -2012,7 +2014,7 @@ cpu_CPUID(void)
 				break;
 			case 0x80000001:
 				EAX = CPUID;
-				EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW;
+				EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW;
 				if (cpu_has_feature(CPU_FEATURE_CX8))
 					EDX |= CPUID_CMPXCHG8B;
 				break;                                
@@ -2124,6 +2126,8 @@ cpu_RDMSR(void)
 	case CPU_CYRIX3S:
 		EAX = EDX = 0;
 		switch (ECX) {
+			case 0x00: case 0x01:
+				break;
 			case 0x10:
 				EAX = tsc & 0xffffffff;
 				EDX = tsc >> 32;
@@ -2209,6 +2213,9 @@ cpu_RDMSR(void)
 	case CPU_K6_3P:
 		EAX = EDX = 0;
 		switch (ECX) {
+			case 0x00000000:
+			case 0x00000001:
+				break;
 			case 0x0000000e:
 				EAX = msr.tr12;
 				break;
@@ -2289,6 +2296,8 @@ amd_k_invalid_rdmsr:
 #endif
 			EAX = EDX = 0;
 		switch (ECX) {
+			case 0x00: case 0x01:
+				break;
 			case 0x10:
 				EAX = tsc & 0xffffffff;
 				EDX = tsc >> 32;
@@ -2302,6 +2311,8 @@ amd_k_invalid_rdmsr:
 	case CPU_PENTIUM2D:
 		EAX = EDX = 0;
 		switch (ECX) {
+			case 0x00: case 0x01:
+				break;
 			case 0x10:
 				EAX = tsc & 0xffffffff;
 				EDX = tsc >> 32;
@@ -2310,8 +2321,10 @@ amd_k_invalid_rdmsr:
 				if (cpu_s->cpu_type != CPU_PENTIUM2D)
 					goto i686_invalid_rdmsr;
 
-				EAX = msr.ecx17 & 0xffffffff;
-				EDX = msr.ecx17 >> 32;
+				if (cpu_f->package == CPU_PKG_SLOT2)
+					EDX |= 0x80000;
+				else if (cpu_f->package == CPU_PKG_SOCKET370)
+					EDX |= 0x100000;
 				break;
 			case 0x1B:
 				EAX = msr.apic_base & 0xffffffff;
@@ -2404,7 +2417,14 @@ amd_k_invalid_rdmsr:
 				EDX = 0x00000000;
 				break;
 			case 0x179:
-				EAX = EDX = 0x00000000;
+				EAX = 0x00000105;
+				EDX = 0x00000000;
+				break;
+			case 0x17a:
+				break;
+			case 0x17b:
+				EAX = msr.mcg_ctl & 0xffffffff;
+				EDX = msr.mcg_ctl >> 32;
 				break;
 			case 0x186:
 				EAX = msr.ecx186 & 0xffffffff;
@@ -2455,21 +2475,14 @@ amd_k_invalid_rdmsr:
 				EAX = msr.mtrr_deftype & 0xffffffff;
 				EDX = msr.mtrr_deftype >> 32;
 				break;
-			case 0x404:
-				EAX = msr.ecx404 & 0xffffffff;
-				EDX = msr.ecx404 >> 32;
-				break;
-			case 0x408:
-				EAX = msr.ecx408 & 0xffffffff;
-				EDX = msr.ecx408 >> 32;
-				break;
-			case 0x40c:
-				EAX = msr.ecx40c & 0xffffffff;
-				EDX = msr.ecx40c >> 32;
-				break;
+			case 0x400: case 0x404: case 0x408: case 0x40c:
 			case 0x410:
-				EAX = msr.ecx410 & 0xffffffff;
-				EDX = msr.ecx410 >> 32;
+				EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff;
+				EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32;
+				break;
+			case 0x401: case 0x402: case 0x405: case 0x406:
+			case 0x407: case 0x409: case 0x40d: case 0x40e:
+			case 0x411: case 0x412:
 				break;
 			case 0x570:
 				EAX = msr.ecx570 & 0xffffffff;
@@ -2575,6 +2588,8 @@ cpu_WRMSR(void)
 
 	case CPU_CYRIX3S:
 		switch (ECX) {
+			case 0x00: case 0x01:
+				break;
 			case 0x10:
 				tsc = EAX | ((uint64_t)EDX << 32);
 				break;
@@ -2629,6 +2644,8 @@ cpu_WRMSR(void)
 	case CPU_K6_2P:
 	case CPU_K6_3P:
 		switch (ECX) {
+			case 0x00: case 0x01:
+				break;
 			case 0x0e:
 				msr.tr12 = EAX & 0x228;
 				break;
@@ -2702,6 +2719,8 @@ amd_k_invalid_wrmsr:
 #endif
 		cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
 		switch (ECX) {
+			case 0x00: case 0x01:
+				break;
 			case 0x10:
 				tsc = EAX | ((uint64_t)EDX << 32);
 				break;
@@ -2722,15 +2741,13 @@ amd_k_invalid_wrmsr:
 	case CPU_PENTIUM2:
 	case CPU_PENTIUM2D:
 		switch (ECX) {
+			case 0x00: case 0x01:
+				if (EAX || EDX)
+					x86gpf(NULL, 0);
+				break;
 			case 0x10:
 				tsc = EAX | ((uint64_t)EDX << 32);
 				break;
-			case 0x17:
-				if (cpu_s->cpu_type != CPU_PENTIUM2D)
-					goto i686_invalid_wrmsr;
-
-				msr.ecx17 = EAX | ((uint64_t)EDX << 32);
-				break;
 			case 0x1b:
 				cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX);
 				// msr.apic_base = EAX | ((uint64_t)EDX << 32);
@@ -2779,6 +2796,13 @@ amd_k_invalid_wrmsr:
 				break;
 			case 0x179:
 				break;
+			case 0x17a:
+				if (EAX || EDX)
+					x86gpf(NULL, 0);
+				break;
+			case 0x17b:
+				msr.mcg_ctl = EAX | ((uint64_t)EDX << 32);
+				break;
 			case 0x186:
 				msr.ecx186 = EAX | ((uint64_t)EDX << 32);
 				break;
@@ -2816,17 +2840,15 @@ amd_k_invalid_wrmsr:
 			case 0x2ff:
 				msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32);
 				break;
-			case 0x404:
-				msr.ecx404 = EAX | ((uint64_t)EDX << 32);
-				break;
-			case 0x408:
-				msr.ecx408 = EAX | ((uint64_t)EDX << 32);
-				break;
-			case 0x40c:
-				msr.ecx40c = EAX | ((uint64_t)EDX << 32);
-				break;
+			case 0x400: case 0x404: case 0x408: case 0x40c:
 			case 0x410:
-				msr.ecx410 = EAX | ((uint64_t)EDX << 32);
+				msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t)EDX << 32);
+				break;
+			case 0x401: case 0x402: case 0x405: case 0x406:
+			case 0x407: case 0x409: case 0x40d: case 0x40e:
+			case 0x411: case 0x412:
+				if (EAX || EDX)
+					x86gpf(NULL, 0);
 				break;
 			case 0x570:
 				msr.ecx570 = EAX | ((uint64_t)EDX << 32);
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 9beac3fab..18962bab0 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -236,7 +236,6 @@ typedef struct {
     uint32_t	cesr;			/* 0x00000011 */
 
     /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
-    uint64_t	ecx17;			/* 0x00000017 - Only on Pentium II Deschutes */
     uint64_t	apic_base;		/* 0x0000001b - Should the Pentium not also have this? */
     uint64_t	ecx79;			/* 0x00000079 */
 
@@ -262,6 +261,9 @@ typedef struct {
     uint32_t	sysenter_esp;		/* 0x00000175 - SYSENTER/SYSEXIT MSR's */
     uint32_t	sysenter_eip;		/* 0x00000176 - SYSENTER/SYSEXIT MSR's */
 
+    /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
+    uint64_t	mcg_ctl;		/* 0x0000017b - Machine Check Architecture */
+
     /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
     uint64_t	ecx186, ecx187;		/* 0x00000186, 0x00000187 */
     uint64_t	ecx1e0;			/* 0x000001e0 */
@@ -283,10 +285,7 @@ typedef struct {
     uint64_t	mtrr_deftype;		/* 0x000002ff */
 
     /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
-    uint64_t	ecx404;			/* 0x00000404 - Model Identification MSR's used by some Acer BIOSes */
-    uint64_t	ecx408;			/* 0x00000408 */
-    uint64_t	ecx40c;			/* 0x0000040c */
-    uint64_t	ecx410;			/* 0x00000410 */
+    uint64_t	mca_ctl[5];		/* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */
     uint64_t	ecx570;			/* 0x00000570 */
 
     /* IBM 386SLC, 486SLC, and 486BL MSR's */
diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c
index e98536bf4..78c17ae19 100644
--- a/src/device/keyboard_xt.c
+++ b/src/device/keyboard_xt.c
@@ -755,9 +755,6 @@ kbd_init(const device_t *info)
         /* Switch 2 - 8087 FPU. */
         if (hasfpu)
             kbd->pd |= 0x02;
-
-        /* Switch 1 - always off. */
-        kbd->pd |= 0x01;
     } else if (kbd-> type == 9) {
         /* Zenith Data Systems Z-151
         * SW2 switch settings:
diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c
index 1b048b8b0..a04de517c 100644
--- a/src/disk/hdc_ide.c
+++ b/src/disk/hdc_ide.c
@@ -445,7 +445,7 @@ ide_get_max(ide_t *ide, int type)
     switch(type) {
 	case TYPE_PIO:	/* PIO */
 		if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
-			return 1;
+			return 4;
 
 		return 0;	/* Maximum PIO 0 for legacy PIO-only drive. */
 	case TYPE_SDMA:	/* SDMA */
diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h
index 7df22bcbe..f3fb0928f 100644
--- a/src/include/86box/machine.h
+++ b/src/include/86box/machine.h
@@ -358,7 +358,7 @@ extern int	machine_at_greenb_init(const machine_t *);
 extern int	machine_at_r418_init(const machine_t *);
 extern int	machine_at_ls486e_init(const machine_t *);
 extern int	machine_at_4dps_init(const machine_t *);
-extern int	machine_at_4sa2_init(const machine_t *);
+extern int	machine_at_4saw2_init(const machine_t *);
 extern int	machine_at_m4li_init(const machine_t *);
 extern int	machine_at_alfredo_init(const machine_t *);
 extern int	machine_at_ninja_init(const machine_t *);
diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h
index b0157088c..b841d7e6a 100644
--- a/src/include/86box/nvr.h
+++ b/src/include/86box/nvr.h
@@ -112,6 +112,7 @@ extern int	nvr_save(void);
 
 extern int	nvr_is_leap(int year);
 extern int	nvr_get_days(int month, int year);
+extern void	nvr_time_sync();
 extern void	nvr_time_get(struct tm *);
 extern void	nvr_time_set(struct tm *);
 
diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h
index f4626890d..2e6e7eb8f 100644
--- a/src/include/86box/snd_sb_dsp.h
+++ b/src/include/86box/snd_sb_dsp.h
@@ -66,6 +66,11 @@ typedef struct sb_dsp_t
 	int sb_irqm8, sb_irqm16, sb_irqm401;
 
 	uint8_t sb_asp_regs[256];
+	uint8_t sb_asp_mode;
+
+	uint8_t sb_asp_ram[2048];
+	int sb_asp_ram_index;
+
 	uint8_t sb_8051_ram[256];
 
 	int sbenable, sb_enable_i;
diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt
index 79da0e550..a20c105fe 100644
--- a/src/machine/CMakeLists.txt
+++ b/src/machine/CMakeLists.txt
@@ -35,8 +35,4 @@ endif()
 
 if(OPEN_AT)
     target_compile_definitions(mch PRIVATE USE_OPEN_AT)
-endif()
-
-if(M154X)
-    target_compile_definitions(mch PRIVATE USE_M154X)
 endif()
\ No newline at end of file
diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c
index ee9a5e489..9bb4ff21e 100644
--- a/src/machine/m_at_386dx_486.c
+++ b/src/machine/m_at_386dx_486.c
@@ -1025,11 +1025,11 @@ machine_at_486sp3c_init(const machine_t *model)
 
 
 int
-machine_at_4sa2_init(const machine_t *model)
+machine_at_4saw2_init(const machine_t *model)
 {
     int ret;
 
-    ret = bios_load_linear("roms/machines/4sa2/4saw0911.bin",
+    ret = bios_load_linear("roms/machines/4saw2/4saw0911.bin",
 			   0x000e0000, 131072, 0);
 
     if (bios_only || !ret)
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index 842f543ee..74260d668 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -446,7 +446,7 @@ const machine_t machines[] = {
     { "[SiS 496] Rise Computer R418",		"r418",			MACHINE_TYPE_486_S3,		CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0,										MACHINE_PCI | MACHINE_IDE_DUAL,							 1024, 261120, 1024, 255,		 machine_at_r418_init, NULL			},
     /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it
        must be an ASIC that clones the standard IBM PS/2 KBC. */
-    { "[SiS 496] Soyo 4SA2",			"4sa2",			MACHINE_TYPE_486_S3,		CPU_PKG_SOCKET3, CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), 0, 0, 0, 0, 0, 0,			MACHINE_PCI | MACHINE_IDE_DUAL,							 1024, 261120, 1024, 255,		 machine_at_4sa2_init, NULL			},
+    { "[SiS 496] Soyo 4SAW2",			"4saw2",		MACHINE_TYPE_486_S3,		CPU_PKG_SOCKET3, CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), 0, 0, 0, 0, 0, 0,			MACHINE_PCIV | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL,				 1024, 261120, 1024, 255,		machine_at_4saw2_init, NULL			},
     /* According to MrKsoft, his real 4DPS has an AMIKey-2, which is an updated version
        of type 'H'. */
     { "[SiS 496] Zida Tomato 4DP",		"4dps",			MACHINE_TYPE_486_S3,		CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0,										MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL,				 1024, 261120, 1024, 255,		 machine_at_4dps_init, NULL			},
@@ -920,7 +920,7 @@ const machine_t machines[] = {
     /* Miscellaneous/Fake/Hypervisor machines */
     /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC
        firmware. */
-    { "[i440BX] Microsoft Virtual PC 2007",	"vpc2007",		MACHINE_TYPE_MISC,		CPU_PKG_SLOT1, CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), 0, 0, 0, 0, 0, 0,						MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL,		  		 8192,1048576, 8192, 255,	      machine_at_vpc2007_init, NULL			},
+    { "[i440BX] Microsoft Virtual PC 2007",	"vpc2007",		MACHINE_TYPE_MISC,		CPU_PKG_SLOT1, CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), 0, 66666667, 0, 0, 0, 0,					MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL,		  		 8192,1048576, 8192, 255,	      machine_at_vpc2007_init, NULL			},
 
     { NULL,					NULL,			MACHINE_TYPE_NONE,		0, 0, 0, 0, 0, 0, 0, 0,												0,										    0,      0,    0,   0,				 NULL, NULL			}
 };
diff --git a/src/nvr.c b/src/nvr.c
index ee9dcaaca..46e0f6c5a 100644
--- a/src/nvr.c
+++ b/src/nvr.c
@@ -166,8 +166,6 @@ onesec_timer(void *priv)
 void
 nvr_init(nvr_t *nvr)
 {
-    struct tm *tm;
-    time_t now;
     int c;
 
     /* Set up the NVR file's name. */
@@ -178,15 +176,7 @@ nvr_init(nvr_t *nvr)
     /* Initialize the internal clock as needed. */
     memset(&intclk, 0x00, sizeof(intclk));
     if (time_sync & TIME_SYNC_ENABLED) {
-	/* Get the current time of day, and convert to local time. */
-	(void)time(&now);
-	if(time_sync & TIME_SYNC_UTC)
-		tm = gmtime(&now);
-	else
-		tm = localtime(&now);
-
-	/* Set the internal clock. */
-	nvr_time_set(tm);
+	nvr_time_sync();
     } else {
 	/* Reset the internal clock to 1980/01/01 00:00. */
 	intclk.tm_mon = 1;
@@ -325,6 +315,24 @@ nvr_close(void)
 }
 
 
+void
+nvr_time_sync(void)
+{
+    struct tm *tm;
+    time_t now;
+
+    /* Get the current time of day, and convert to local time. */
+    (void)time(&now);
+    if(time_sync & TIME_SYNC_UTC)
+	tm = gmtime(&now);
+    else
+	tm = localtime(&now);
+
+    /* Set the internal clock. */
+    nvr_time_set(tm);
+}
+
+
 /* Get current time from internal clock. */
 void
 nvr_time_get(struct tm *tm)
diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c
index 01a2ca6e0..d41467bb5 100644
--- a/src/sound/snd_sb_dsp.c
+++ b/src/sound/snd_sb_dsp.c
@@ -46,22 +46,22 @@ static int sbe2dat[4][9] = {
 
 static int sb_commands[256]=
 {
-		-1, 2,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1,
-		 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0,
-		 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		 1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0,
-		 2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1,
-		 0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-		 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-		 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1,
-		 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1, 0,-1,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0
+        -1, 2,-1, 0, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1,
+         1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0,
+         0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+         1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+        -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0,
+         2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1,
+         0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1,
+        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+         0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1,
+         1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1,
+        -1,-1, 0, 0,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0
 };
 
 
@@ -71,50 +71,50 @@ uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x
 
 /*These tables were 'borrowed' from DOSBox*/
 int8_t scaleMap4[64] = {
-	0,  1,  2,  3,  4,  5,  6,  7,  0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,
-	1,  3,  5,  7,  9, 11, 13, 15, -1,  -3,  -5,  -7,  -9, -11, -13, -15,
-	2,  6, 10, 14, 18, 22, 26, 30, -2,  -6, -10, -14, -18, -22, -26, -30,
-	4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
+    0,  1,  2,  3,  4,  5,  6,  7,  0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,
+    1,  3,  5,  7,  9, 11, 13, 15, -1,  -3,  -5,  -7,  -9, -11, -13, -15,
+    2,  6, 10, 14, 18, 22, 26, 30, -2,  -6, -10, -14, -18, -22, -26, -30,
+    4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
 };
 
 uint8_t adjustMap4[64] = {
-	  0, 0, 0, 0, 0, 16, 16, 16,
-	  0, 0, 0, 0, 0, 16, 16, 16,
-	240, 0, 0, 0, 0, 16, 16, 16,
-	240, 0, 0, 0, 0, 16, 16, 16,
-	240, 0, 0, 0, 0, 16, 16, 16,
-	240, 0, 0, 0, 0, 16, 16, 16,
-	240, 0, 0, 0, 0,  0,  0,  0,
-	240, 0, 0, 0, 0,  0,  0,  0
+      0, 0, 0, 0, 0, 16, 16, 16,
+      0, 0, 0, 0, 0, 16, 16, 16,
+    240, 0, 0, 0, 0, 16, 16, 16,
+    240, 0, 0, 0, 0, 16, 16, 16,
+    240, 0, 0, 0, 0, 16, 16, 16,
+    240, 0, 0, 0, 0, 16, 16, 16,
+    240, 0, 0, 0, 0,  0,  0,  0,
+    240, 0, 0, 0, 0,  0,  0,  0
 };
 
 int8_t scaleMap26[40] = {
-	0,  1,  2,  3,  0,  -1,  -2,  -3,
-	1,  3,  5,  7, -1,  -3,  -5,  -7,
-	2,  6, 10, 14, -2,  -6, -10, -14,
-	4, 12, 20, 28, -4, -12, -20, -28,
-	5, 15, 25, 35, -5, -15, -25, -35
+    0,  1,  2,  3,  0,  -1,  -2,  -3,
+    1,  3,  5,  7, -1,  -3,  -5,  -7,
+    2,  6, 10, 14, -2,  -6, -10, -14,
+    4, 12, 20, 28, -4, -12, -20, -28,
+    5, 15, 25, 35, -5, -15, -25, -35
 };
 
 uint8_t adjustMap26[40] = {
-	  0, 0, 0, 8,   0, 0, 0, 8,
-	248, 0, 0, 8, 248, 0, 0, 8,
-	248, 0, 0, 8, 248, 0, 0, 8,
-	248, 0, 0, 8, 248, 0, 0, 8,
-	248, 0, 0, 0, 248, 0, 0, 0
+      0, 0, 0, 8,   0, 0, 0, 8,
+    248, 0, 0, 8, 248, 0, 0, 8,
+    248, 0, 0, 8, 248, 0, 0, 8,
+    248, 0, 0, 8, 248, 0, 0, 8,
+    248, 0, 0, 0, 248, 0, 0, 0
 };
 
 int8_t scaleMap2[24] = {
-	0,  1,  0,  -1, 1,  3,  -1,  -3,
-	2,  6, -2,  -6, 4, 12,  -4, -12,
-	8, 24, -8, -24, 6, 48, -16, -48
+    0,  1,  0,  -1, 1,  3,  -1,  -3,
+    2,  6, -2,  -6, 4, 12,  -4, -12,
+    8, 24, -8, -24, 6, 48, -16, -48
 };
 
 uint8_t adjustMap2[24] = {
-	  0, 4,   0, 4,
-	252, 4, 252, 4, 252, 4, 252, 4,
-	252, 4, 252, 4, 252, 4, 252, 4,
-	252, 0, 252, 0
+      0, 4,   0, 4,
+    252, 4, 252, 4, 252, 4, 252, 4,
+    252, 4, 252, 4, 252, 4, 252, 4,
+    252, 0, 252, 0
 };
 
 double low_fir_sb16_coef[2][SB16_NCoef];
@@ -127,13 +127,13 @@ int sb_dsp_do_log = ENABLE_SB_DSP_LOG;
 static void
 sb_dsp_log(const char *fmt, ...)
 {
-	va_list ap;
+    va_list ap;
 
-	if (sb_dsp_do_log) {
+    if (sb_dsp_do_log) {
 	va_start(ap, fmt);
 	pclog_ex(fmt, ap);
 	va_end(ap);
-	}
+    }
 }
 #else
 #define sb_dsp_log(fmt, ...)
@@ -143,19 +143,19 @@ sb_dsp_log(const char *fmt, ...)
 static __inline double
 sinc(double x)
 {
-	return sin(M_PI * x) / (M_PI * x);
+    return sin(M_PI * x) / (M_PI * x);
 }
 
 static void
 recalc_sb16_filter(int c, int playback_freq)
 {
-	/* Cutoff frequency = playback / 2 */
-	int n;
-	double w, h;
-	double fC = ((double) playback_freq) / 96000.0;
-	double gain;
+    /* Cutoff frequency = playback / 2 */
+    int n;
+    double w, h;
+    double fC = ((double) playback_freq) / 96000.0;
+    double gain;
 
-	for (n = 0; n < SB16_NCoef; n++) {
+    for (n = 0; n < SB16_NCoef; n++) {
 	/* Blackman window */
 	w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(SB16_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(SB16_NCoef-1)));
 	/* Sinc filter */
@@ -163,16 +163,16 @@ recalc_sb16_filter(int c, int playback_freq)
 
 	/* Create windowed-sinc filter */
 	low_fir_sb16_coef[c][n] = w * h;
-	}
+    }
 
-	low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0;
+    low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0;
 
-	gain = 0.0;
-	for (n = 0; n < SB16_NCoef; n++)
+    gain = 0.0;
+    for (n = 0; n < SB16_NCoef; n++)
 	gain += low_fir_sb16_coef[c][n];
 
-	/* Normalise filter, to produce unity gain */
-	for (n = 0; n < SB16_NCoef; n++)
+    /* Normalise filter, to produce unity gain */
+    for (n = 0; n < SB16_NCoef; n++)
 	low_fir_sb16_coef[c][n] /= gain;
 }
 
@@ -180,19 +180,19 @@ recalc_sb16_filter(int c, int playback_freq)
 void
 sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401)
 {
-	int clear = 0;
+    int clear = 0;
 
-	if (!dsp->sb_irqm8 && irqm8)
+    if (!dsp->sb_irqm8 && irqm8)
 	clear |= 1;
-	dsp->sb_irqm8 = irqm8;
-	if (!dsp->sb_irqm16 && irqm16)
+    dsp->sb_irqm8 = irqm8;
+    if (!dsp->sb_irqm16 && irqm16)
 	clear |= 1;
-	dsp->sb_irqm16 = irqm16;
-	if (!dsp->sb_irqm401 && irqm401)
+    dsp->sb_irqm16 = irqm16;
+    if (!dsp->sb_irqm401 && irqm401)
 	clear |= 1;
-	dsp->sb_irqm401 = irqm401;
+    dsp->sb_irqm401 = irqm401;
 
-	if (clear)
+    if (clear)
 	picintc(1 << dsp->sb_irqnum);
 }
 
@@ -200,9 +200,9 @@ sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401)
 void
 sb_update_status(sb_dsp_t *dsp, int bit, int set)
 {
-	int masked = 0;
+    int masked = 0;
 
-	switch (bit) {
+    switch (bit) {
 	case 0:
 	default:
 		dsp->sb_irq8  = set;
@@ -216,11 +216,11 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set)
 		dsp->sb_irq401 = set;
 		masked = dsp->sb_irqm401;
 		break;
-	}
+    }
 
-	if (set && !masked)
+    if (set && !masked)
 	picint(1 << dsp->sb_irqnum);
-	else if (!set)
+    else if (!set)
 	picintc(1 << dsp->sb_irqnum);
 }
 
@@ -228,41 +228,41 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set)
 void
 sb_irq(sb_dsp_t *dsp, int irq8)
 {
-	sb_update_status(dsp, !irq8, 1);
+    sb_update_status(dsp, !irq8, 1);
 }
 
 
 void
 sb_irqc(sb_dsp_t *dsp, int irq8)
 {
-	sb_update_status(dsp, !irq8, 0);
+    sb_update_status(dsp, !irq8, 0);
 }
 
 
 static void
 sb_dsp_irq_update(void *priv, int set)
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) priv;
+    sb_dsp_t *dsp = (sb_dsp_t *) priv;
 
-	sb_update_status(dsp, 2, set);
+    sb_update_status(dsp, 2, set);
 }
 
 
 static int
 sb_dsp_irq_pending(void *priv)
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) priv;
+    sb_dsp_t *dsp = (sb_dsp_t *) priv;
 
-	return dsp->sb_irq401;
+    return dsp->sb_irq401;
 }
 
 
 void
 sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu)
 {
-	dsp->mpu = mpu;
+    dsp->mpu = mpu;
 
-	if (mpu != NULL)
+    if (mpu != NULL)
 	mpu401_irq_attach(mpu, sb_dsp_irq_update, sb_dsp_irq_pending, dsp);
 }
 
@@ -270,75 +270,77 @@ sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu)
 void
 sb_dsp_reset(sb_dsp_t *dsp)
 {
-	midi_clear_buffer();
+    midi_clear_buffer();
 
-	timer_disable(&dsp->output_timer);
-	timer_disable(&dsp->input_timer);
+    timer_disable(&dsp->output_timer);
+    timer_disable(&dsp->input_timer);
 
-	dsp->sb_command = 0;
+    dsp->sb_command = 0;
 
-	dsp->sb_8_length = 0xffff;
-	dsp->sb_8_autolen = 0xffff;
+    dsp->sb_8_length = 0xffff;
+    dsp->sb_8_autolen = 0xffff;
 
-	dsp->sb_irq8 = 0;
-	dsp->sb_irq16 = 0;
-	dsp->sb_irq401 = 0;
-	dsp->sb_16_pause = 0;
-	dsp->sb_read_wp = dsp->sb_read_rp = 0;
-	dsp->sb_data_stat = -1;
-	dsp->sb_speaker = 0;
-	dsp->sb_pausetime = -1LL;
-	dsp->sbe2 = 0xAA;
-	dsp->sbe2count = 0;
+    dsp->sb_irq8 = 0;
+    dsp->sb_irq16 = 0;
+    dsp->sb_irq401 = 0;
+    dsp->sb_16_pause = 0;
+    dsp->sb_read_wp = dsp->sb_read_rp = 0;
+    dsp->sb_data_stat = -1;
+    dsp->sb_speaker = 0;
+    dsp->sb_pausetime = -1LL;
+    dsp->sbe2 = 0xAA;
+    dsp->sbe2count = 0;
 
-	dsp->sbreset = 0;
+    dsp->sbreset = 0;
 
-	dsp->record_pos_read = 0;
-	dsp->record_pos_write = SB_DSP_REC_SAFEFTY_MARGIN;
+    dsp->record_pos_read = 0;
+    dsp->record_pos_write = SB_DSP_REC_SAFEFTY_MARGIN;
 
-	picintc(1 << dsp->sb_irqnum);
+    picintc(1 << dsp->sb_irqnum);
 
-	dsp->asp_data_len = 0;
+    dsp->asp_data_len = 0;
 }
 
 
 void
 sb_doreset(sb_dsp_t *dsp)
 {
-	int c;
+    int c;
 
-	sb_dsp_reset(dsp);
+    sb_dsp_reset(dsp);
 
 
-	if (IS_AZTECH(dsp)) {
+    if (IS_AZTECH(dsp)) {
+	sb_commands[8] =  1;
+	sb_commands[9] =  1;
+    } else {
+	if (dsp->sb_type >= SB16)
 		sb_commands[8] =  1;
-		sb_commands[9] =  1;
-	} else {
-		if ((dsp->sb_type >= SB16) && (dsp->sb_type < SBAWE64))
-		sb_commands[8] =  1;
-		else
+	else
 		sb_commands[8] = -1;
-	}
+    }
 
-	for (c = 0; c < 256; c++)
+    dsp->sb_asp_mode = 0;
+    dsp->sb_asp_ram_index = 0;
+    for (c = 0; c < 256; c++)
 	dsp->sb_asp_regs[c] = 0;
 
-	dsp->sb_asp_regs[5] = 0x01;
-	dsp->sb_asp_regs[9] = 0xf8;
+    dsp->sb_asp_regs[5] = 0x01;
+    dsp->sb_asp_regs[9] = 0xf8;
 }
 
 
 void
 sb_dsp_speed_changed(sb_dsp_t *dsp)
 {
-	if (dsp->sb_timeo < 256)
+    if (dsp->sb_timeo < 256)
 	dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo);
-	else
+    else
 	dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256)));
 
-	if (dsp->sb_timei < 256)
+    if (dsp->sb_timei < 256)
 	dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei);
-	else
+    else
 	dsp->sblatchi = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256)));
 }
 
@@ -346,17 +348,17 @@ sb_dsp_speed_changed(sb_dsp_t *dsp)
 void
 sb_add_data(sb_dsp_t *dsp, uint8_t v)
 {
-	dsp->sb_read_data[dsp->sb_read_wp++] = v;
-	dsp->sb_read_wp &= 0xff;
+    dsp->sb_read_data[dsp->sb_read_wp++] = v;
+    dsp->sb_read_wp &= 0xff;
 }
 
 
 void
 sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
 {
-	dsp->sb_pausetime = -1;
+    dsp->sb_pausetime = -1;
 
-	if (dma8) {
+    if (dma8) {
 	dsp->sb_8_length = len;
 	dsp->sb_8_format = format;
 	dsp->sb_8_autoinit = autoinit;
@@ -370,7 +372,7 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
 		timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho);
 	dsp->sbleftright = 0;
 	dsp->sbdacpos = 0;
-	} else {
+    } else {
 	dsp->sb_16_length = len;
 	dsp->sb_16_format = format;
 	dsp->sb_16_autoinit = autoinit;
@@ -380,14 +382,14 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
 	dsp->sb_16_output = 1;
 	if (!timer_is_enabled(&dsp->output_timer))
 		timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho);
-	}
+    }
 }
 
 
 void
 sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
 {
-	if (dma8) {
+    if (dma8) {
 	dsp->sb_8_length = len;
 	dsp->sb_8_format = format;
 	dsp->sb_8_autoinit = autoinit;
@@ -398,7 +400,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
 	dsp->sb_8_output = 0;
 	if (!timer_is_enabled(&dsp->input_timer))
 		timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi);
-	} else {
+    } else {
 	dsp->sb_16_length = len;
 	dsp->sb_16_format = format;
 	dsp->sb_16_autoinit = autoinit;
@@ -409,76 +411,83 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
 	dsp->sb_16_output = 0;
 	if (!timer_is_enabled(&dsp->input_timer))
 		timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi);
-	}
+    }
 
-	memset(dsp->record_buffer,0,sizeof(dsp->record_buffer));
+    memset(dsp->record_buffer,0,sizeof(dsp->record_buffer));
 }
 
 
 int
 sb_8_read_dma(sb_dsp_t *dsp)
 {
-	return dma_channel_read(dsp->sb_8_dmanum);
+    return dma_channel_read(dsp->sb_8_dmanum);
 }
 
 
 void
 sb_8_write_dma(sb_dsp_t *dsp, uint8_t val)
 {
-	dma_channel_write(dsp->sb_8_dmanum, val);
+    dma_channel_write(dsp->sb_8_dmanum, val);
 }
 
 
 int
 sb_16_read_dma(sb_dsp_t *dsp)
 {
-	return dma_channel_read(dsp->sb_16_dmanum);
+    return dma_channel_read(dsp->sb_16_dmanum);
 }
 
 
 int
 sb_16_write_dma(sb_dsp_t *dsp, uint16_t val)
 {
-	int ret = dma_channel_write(dsp->sb_16_dmanum, val);
+    int ret = dma_channel_write(dsp->sb_16_dmanum, val);
 
-	return (ret == DMA_NODATA);
+    return (ret == DMA_NODATA);
 }
 
 
 void
 sb_dsp_setirq(sb_dsp_t *dsp, int irq)
 {
-	dsp->sb_irqnum = irq;
+    dsp->sb_irqnum = irq;
 }
 
 
 void
 sb_dsp_setdma8(sb_dsp_t *dsp, int dma)
 {
-	dsp->sb_8_dmanum = dma;
+    dsp->sb_8_dmanum = dma;
 }
 
 
 void
 sb_dsp_setdma16(sb_dsp_t *dsp, int dma)
 {
-	dsp->sb_16_dmanum = dma;
+    dsp->sb_16_dmanum = dma;
 }
 
 void
 sb_exec_command(sb_dsp_t *dsp)
 {
-	int temp, c;
+    int temp, c;
 
-	sb_dsp_log("sb_exec_command : SB command %02X\n", dsp->sb_command);
+    sb_dsp_log("sb_exec_command : SB command %02X\n", dsp->sb_command);
 
-	switch (dsp->sb_command) {
+
+    /* Update 8051 ram with the current DSP command.
+       See https://github.com/joncampbell123/dosbox-x/issues/1044 */
+    if (dsp->sb_type >= SB16)
+	dsp->sb_8051_ram[0x20] = dsp->sb_command;
+
+    switch (dsp->sb_command) {
 	case 0x01:	/* ???? */
 		if (dsp->sb_type >= SB16)
 			dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1;
 		break;
 	case 0x03:	/* ASP status */
-		sb_add_data(dsp, 0);
+		if (dsp->sb_type >= SB16)
+			sb_add_data(dsp, 0);
 		break;
 	case 0x10:	/* 8-bit direct mode */
 		sb_dsp_update(dsp);
@@ -581,6 +590,8 @@ sb_exec_command(sb_dsp_t *dsp)
 			dsp->sb_timei = dsp->sb_timeo;
 			if (dsp->sb_freq != temp && dsp->sb_type >= SB16)
 				recalc_sb16_filter(0, dsp->sb_freq);
+			dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff;
+			dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff;
 		}
 		break;
 	case 0x48:	/* Set DSP block transfer size */
@@ -767,7 +778,7 @@ sb_exec_command(sb_dsp_t *dsp)
 		break;
 	case 0x07: case 0xFF:	/* No, that's not how you program auto-init DMA */
 		break;
-	case 0x08:	/* ASP get version */
+	case 0x08:	/* ASP get version / AZTECH type/EEPROM access */
 		if (IS_AZTECH(dsp)) {
 			if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55)&& dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11)
 				sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */
@@ -791,36 +802,76 @@ sb_exec_command(sb_dsp_t *dsp)
 				sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */
 			break;
 		}
-		if (dsp->sb_type >= SB16)
+		if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */
+			sb_add_data(dsp, 0xFF);
+		else if (dsp->sb_type >= SB16)
 			sb_add_data(dsp, 0x18);
 		break;
 	case 0x0E:	/* ASP set register */
-		if (dsp->sb_type >= SB16)
+		if (dsp->sb_type >= SB16) {
 			dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1];
+
+			if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */
+				if (dsp->sb_asp_mode & 8)
+					dsp->sb_asp_ram_index = 0;
+
+				dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1];
+
+				if (dsp->sb_asp_mode & 2) {
+					dsp->sb_asp_ram_index++;
+					if (dsp->sb_asp_ram_index >= 2048)
+						dsp->sb_asp_ram_index = 0;
+				}
+			}
+			sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]);
+		}
 		break;
 	case 0x0F:	/* ASP get register */
-		if (dsp->sb_type >= SB16)
+		if (dsp->sb_type >= SB16) {
+			if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */
+				if (dsp->sb_asp_mode & 8)
+					dsp->sb_asp_ram_index = 0;
+
+				dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index];
+
+				if (dsp->sb_asp_mode & 1) {
+					dsp->sb_asp_ram_index++;
+					if (dsp->sb_asp_ram_index >= 2048)
+						dsp->sb_asp_ram_index = 0;
+				}
+			} else if (dsp->sb_data[0] == 0x83) {
+				dsp->sb_asp_regs[0x83] = 0x18;
+			}
 			sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]);
+			sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]);
+		}
 		break;
 	case 0xF8:
 		if (dsp->sb_type < SB16)
 			sb_add_data(dsp, 0);
 		break;
-	case 0xF9:
-		if (dsp->sb_type >= SB16) {
- 			sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]);
-		}
+	case 0xF9: /* SB16 8051 RAM read */
+		if (dsp->sb_type >= SB16)
+			sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]);
 		break;
-	case 0xFA:
-		if(dsp->sb_type >= SB16)
-		{
+	case 0xFA: /* SB16 8051 RAM write */
+		if (dsp->sb_type >= SB16)
 			dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1];
+		break;
+	case 0x04: /* ASP set mode register */
+		if (dsp->sb_type >= SB16) {
+			dsp->sb_asp_mode = dsp->sb_data[0];
+			if (dsp->sb_asp_mode & 4)
+				dsp->sb_asp_ram_index = 0;
+			sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode);
 		}
 		break;
-	case 0x04: case 0x05:
+	case 0x05: /* ASP set codec parameter */
+		if (dsp->sb_type >= SB16)
+			sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]);
 		break;
 
-	case 0x09: /*AZTECH mode set*/
+	case 0x09: /* AZTECH mode set */
 		if (IS_AZTECH(dsp)) {
 			if (dsp->sb_data[0] == 0x00) {
 				sb_dsp_log("AZT2316A: WSS MODE!\n");
@@ -846,22 +897,22 @@ sb_exec_command(sb_dsp_t *dsp)
 	 *  0FCh           DSP Auxiliary Status                                SB16
 	 *  0FDh           DSP Command Status                                  SB16
 	 */
-	}
-	if(dsp->sb_type >= SB16)
-	{
-		//Update 8051 ram with the last DSP command.
-		//See https://github.com/joncampbell123/dosbox-x/issues/1044
-		dsp->sb_8051_ram[0x30] = dsp->sb_command;
-	}
+    }
+
+
+    /* Update 8051 ram with the last DSP command.
+       See https://github.com/joncampbell123/dosbox-x/issues/1044 */
+    if (dsp->sb_type >= SB16)
+	dsp->sb_8051_ram[0x30] = dsp->sb_command;
 }
 
 
 void
 sb_write(uint16_t a, uint8_t v, void *priv)
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) priv;
+    sb_dsp_t *dsp = (sb_dsp_t *) priv;
 
-	switch (a & 0xF) {
+    switch (a & 0xF) {
 	case 6:		/* Reset */
 		if (!dsp->uart_midi) {
 			if (!(v & 1) && (dsp->sbreset & 1)) {
@@ -913,17 +964,17 @@ sb_write(uint16_t a, uint8_t v, void *priv)
 			}
 		}
 		break;
-	}
+    }
 }
 
 
 uint8_t
 sb_read(uint16_t a, void *priv)
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) priv;
-	uint8_t ret = 0x00;
+    sb_dsp_t *dsp = (sb_dsp_t *) priv;
+    uint8_t ret = 0x00;
 
-	switch (a & 0xf) {
+    switch (a & 0xf) {
 	case 0xA:	/* Read data */
 		if (dsp->mpu && dsp->uart_midi) {
 			ret = MPU401_ReadData(dsp->mpu);
@@ -978,134 +1029,136 @@ sb_read(uint16_t a, void *priv)
 		sb_dsp_log("SB 16-bit ACK read 0xFF\n");
 		ret = 0xff;
 		break;
-		}
+        }
 
-		return ret;
+        return ret;
 }
 
 
 void 
 sb_dsp_input_msg(void *p, uint8_t *msg) 
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) p;
-	uint8_t len = msg[3], i = 0;
+    sb_dsp_t *dsp = (sb_dsp_t *) p;
+    uint8_t len = msg[3], i = 0;
 
-	sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, msg[3]);
+    sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, msg[3]);
 
-	if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) {
+    if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) {
 	MPU401_InputMsg(dsp->mpu, msg);
 	return;
-	}
+    }
 
-	if (dsp->midi_in_sysex)
+    if (dsp->midi_in_sysex)
 	return;
 
-	if (dsp->uart_irq) {
+    if (dsp->uart_irq) {
 	for (i = 0; i < len; i++)
 		sb_add_data(dsp, msg[i]);
 	sb_irq(dsp, 1);
-	} else if (dsp->midi_in_poll) { 
+    } else if (dsp->midi_in_poll) { 
 	for (i = 0; i < len; i++) 
 		sb_add_data(dsp, msg[i]);
-	}
+    }
 }
 
 
 int 
 sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) 
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) p;
-	uint32_t i;
+    sb_dsp_t *dsp = (sb_dsp_t *) p;
+    uint32_t i;
 
-	if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL))
+    if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL))
 	return MPU401_InputSysex(dsp->mpu, buffer, len, abort);
 
-	if (abort) {
+    if (abort) {
 	dsp->midi_in_sysex = 0;
 	return 0;
-	}
+    }
 
-	dsp->midi_in_sysex = 1;
+    dsp->midi_in_sysex = 1;
 
-	for (i = 0; i < len; i++) {
+    for (i = 0; i < len; i++) {
 	if (dsp->sb_read_rp == dsp->sb_read_wp) {
 		sb_dsp_log("Length sysex SB = %d\n", len - i);
 		return (len - i);
 	}
 
 	sb_add_data(dsp, buffer[i]);
-	}
+    }
 
-	dsp->midi_in_sysex = 0;
+    dsp->midi_in_sysex = 0;
 
-	return 0;
+    return 0;
 }
 
 
 void
 sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
 {
-	dsp->sb_type = type;
-	dsp->sb_subtype = subtype;
-	dsp->parent = parent;
+    dsp->sb_type = type;
+    dsp->sb_subtype = subtype;
+    dsp->parent = parent;
 
-	/* Default values. Use sb_dsp_setxxx() methods to change. */
-	dsp->sb_irqnum = 7;
-	dsp->sb_8_dmanum = 1;
-	dsp->sb_16_dmanum = 5;
-	dsp->mpu = NULL;
+    /* Default values. Use sb_dsp_setxxx() methods to change. */
+    dsp->sb_irqnum = 7;
+    dsp->sb_8_dmanum = 1;
+    dsp->sb_16_dmanum = 5;
+    dsp->mpu = NULL;
 
-	sb_doreset(dsp);
+    sb_doreset(dsp);
 
-	timer_add(&dsp->output_timer, pollsb, dsp, 0);
-	timer_add(&dsp->input_timer, sb_poll_i, dsp, 0);
-	timer_add(&dsp->wb_timer, NULL, dsp, 0);
+    timer_add(&dsp->output_timer, pollsb, dsp, 0);
+    timer_add(&dsp->input_timer, sb_poll_i, dsp, 0);
+    timer_add(&dsp->wb_timer, NULL, dsp, 0);
 
-	/* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when
-	   a set frequency command is sent. */
-	recalc_sb16_filter(0, 3200*2);
-	recalc_sb16_filter(1, 44100);
+    /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when
+       a set frequency command is sent. */
+    recalc_sb16_filter(0, 3200*2);
+    recalc_sb16_filter(1, 44100);
 
-	// Initialize SB16 8051 RAM
-	memset(dsp->sb_8051_ram, 0, 256);
-	dsp->sb_8051_ram[0x0e] = 0xff;
-	dsp->sb_8051_ram[0x0f] = 0x07;
-	dsp->sb_8051_ram[0x37] = 0x38;
+    /* Initialize SB16 8051 RAM and ASP internal RAM */
+    memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram));
+    dsp->sb_8051_ram[0x0e] = 0xff;
+    dsp->sb_8051_ram[0x0f] = 0x07;
+    dsp->sb_8051_ram[0x37] = 0x38;
+
+    memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram));
 }
 
 
 void
 sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr)
 {
-	sb_dsp_log("sb_dsp_setaddr : %04X\n", addr);
-	if (dsp->sb_addr != 0) {
+    sb_dsp_log("sb_dsp_setaddr : %04X\n", addr);
+    if (dsp->sb_addr != 0) {
 	io_removehandler(dsp->sb_addr + 6,   0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);
 	io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);
-	}
-	dsp->sb_addr = addr;
-	if (dsp->sb_addr != 0) {
+    }
+    dsp->sb_addr = addr;
+    if (dsp->sb_addr != 0) {
 	io_sethandler(dsp->sb_addr + 6,   0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);
 	io_sethandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);
-	}
+    }
 }
 
 
 void
 sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo)
 {
-	dsp->stereo = stereo;
+    dsp->stereo = stereo;
 }
 
 
 void
 pollsb(void *p)
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) p;
-	int tempi, ref;
-	int data[2];
+    sb_dsp_t *dsp = (sb_dsp_t *) p;
+    int tempi, ref;
+    int data[2];
 
-	timer_advance_u64(&dsp->output_timer, dsp->sblatcho);
-	if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) {
+    timer_advance_u64(&dsp->output_timer, dsp->sblatcho);
+    if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) {
 	sb_dsp_update(dsp);
 
 	switch (dsp->sb_8_format) {
@@ -1294,8 +1347,8 @@ pollsb(void *p)
 		}
 		sb_irq(dsp, 1);
 	}
-	}
-	if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) {
+    }
+    if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) {
 	sb_dsp_update(dsp);
 
 	switch (dsp->sb_16_format) {
@@ -1343,8 +1396,8 @@ pollsb(void *p)
 		}
 		sb_irq(dsp, 0);
 	}
-	}
-	if (dsp->sb_pausetime > -1) {
+    }
+    if (dsp->sb_pausetime > -1) {
 	dsp->sb_pausetime--;
 	if (dsp->sb_pausetime < 0) {
 		sb_irq(dsp, 1);
@@ -1352,19 +1405,19 @@ pollsb(void *p)
 			timer_disable(&dsp->output_timer);
 		sb_dsp_log("SB pause over\n");
 	}
-	}
+    }
 }
 
 
 void
 sb_poll_i(void *p)
 {
-	sb_dsp_t *dsp = (sb_dsp_t *) p;
-	int processed = 0;
+    sb_dsp_t *dsp = (sb_dsp_t *) p;
+    int processed = 0;
 
-	timer_advance_u64(&dsp->input_timer, dsp->sblatchi);
+    timer_advance_u64(&dsp->input_timer, dsp->sblatchi);
 
-	if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) {
+    if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) {
 	switch (dsp->sb_8_format) {
 		case 0x00:	/* Mono unsigned As the manual says, only the left channel is recorded */
 			sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80);
@@ -1404,8 +1457,8 @@ sb_poll_i(void *p)
 		sb_irq(dsp, 1);
 	}
 	processed = 1;
-	}
-	if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && !dsp->sb_16_output) {
+    }
+    if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && !dsp->sb_16_output) {
 	switch (dsp->sb_16_format) {
 		case 0x00:	/* Unsigned mono. As the manual says, only the left channel is recorded */
 			if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000))
@@ -1449,25 +1502,25 @@ sb_poll_i(void *p)
 		sb_irq(dsp, 0);
 	}
 	processed = 1;
-	}
-	/* Assume this is direct mode */
-	if (!processed) {
+    }
+    /* Assume this is direct mode */
+    if (!processed) {
 	dsp->record_pos_read += 2;
 	dsp->record_pos_read &= 0xFFFF;
-	}
+    }
 }
 
 
 void sb_dsp_update(sb_dsp_t *dsp)
 {
-	if (dsp->muted) {
+    if (dsp->muted) {
 	dsp->sbdatl = 0;
 	dsp->sbdatr = 0;
-	}
-	for (; dsp->pos < sound_pos_global; dsp->pos++) {
+    }
+    for (; dsp->pos < sound_pos_global; dsp->pos++) {
 	dsp->buffer[dsp->pos*2] = dsp->sbdatl;
 	dsp->buffer[dsp->pos*2 + 1] = dsp->sbdatr;
-	}
+    }
 }
 
 
diff --git a/src/unix/unix.c b/src/unix/unix.c
index c583f7f50..d7db5cbef 100644
--- a/src/unix/unix.c
+++ b/src/unix/unix.c
@@ -708,6 +708,9 @@ plat_pause(int p)
     static wchar_t oldtitle[512];
     wchar_t title[512];
 
+    if ((p == 0) && (time_sync & TIME_SYNC_ENABLED))
+	nvr_time_sync();
+
     dopause = p;
     if (p) {
 	wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1);
diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c
index 7119e36b3..e0e8b0e2e 100644
--- a/src/video/vid_s3_virge.c
+++ b/src/video/vid_s3_virge.c
@@ -189,6 +189,7 @@ typedef struct virge_t
 
 	int pci;
         int chip;
+	int is_agp;
 
         int bilinear_enabled;
         int dithering_enabled;
@@ -3711,7 +3712,7 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p)
                 
                 case 0x07: ret = virge->pci_regs[0x07] & 0x36; break;
                                 
-                case 0x08: ret = 0; break; /*Revision ID*/
+                case 0x08: ret = virge->virge_rev; break; /*Revision ID*/
                 case 0x09: ret = 0; break; /*Programming interface*/
                 
                 case 0x0a: ret = 0x00; break; /*Supports VGA interface*/
@@ -3734,6 +3735,8 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p)
                 case 0x32: ret = virge->pci_regs[0x32]; break;
                 case 0x33: ret = virge->pci_regs[0x33]; break;
 
+                case 0x34: ret = (virge->chip >= S3_VIRGEGX2) ? 0xdc : 0x00; break;
+
                 case 0x3c: ret = virge->pci_regs[0x3c]; break;
                                 
                 case 0x3d: ret = PCI_INTA; break; /*INTA*/
@@ -3741,6 +3744,26 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p)
                 case 0x3e: ret = 0x04; break;
                 case 0x3f: ret = 0xff; break;
                 
+                case 0x80: ret = 0x02; break; /* AGP capability */
+                case 0x81: ret = 0x00; break;
+                case 0x82: ret = 0x10; break; /* assumed AGP 1.0 */
+
+                case 0x84: ret = (virge->chip >= S3_TRIO3D2X) ? 0x03 : 0x01; break;
+                case 0x87: ret = 0x1f; break;
+
+                case 0x88: ret = virge->pci_regs[0x88]; break;
+                case 0x89: ret = virge->pci_regs[0x89]; break;
+                case 0x8a: ret = virge->pci_regs[0x8a]; break;
+                case 0x8b: ret = virge->pci_regs[0x8b]; break;
+
+                case 0xdc: ret = 0x01; break; /* PCI Power Management capability */
+                case 0xdd: ret = virge->is_agp ? 0x80 : 0x00; break;
+                case 0xde: ret = 0x21; break;
+
+                case 0xe0: ret = virge->pci_regs[0xe0]; break;
+                case 0xe1: ret = virge->pci_regs[0xe1]; break;
+                case 0xe2: ret = virge->pci_regs[0xe2]; break;
+                case 0xe3: ret = virge->pci_regs[0xe3]; break;
         }
         return ret;
 }
@@ -3797,6 +3820,26 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
                 case 0x3c: 
                 virge->pci_regs[0x3c] = val;
                 return;
+
+                case 0x88:
+                virge->pci_regs[0x5c] = val & 0x27;
+                return;
+
+                case 0x89:
+                virge->pci_regs[0x89] = val & 0x03;
+                return;
+
+                case 0x8b: case 0xe1: case 0xe3:
+                virge->pci_regs[addr] = val;
+                return;
+
+                case 0xe0:
+                virge->pci_regs[0xe0] = val & 0x03;
+                return;
+
+                case 0xe2:
+                virge->pci_regs[0xe2] = val & 0xc0;
+                return;
         }
 }
 
@@ -3852,7 +3895,7 @@ static void s3_virge_reset(void *priv)
 	}
 
 	if (virge->chip >= S3_VIRGEGX2)
-		virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
+		virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5);
 	else {
 		switch (virge->memory_size) {
 			case 2:
@@ -3865,6 +3908,8 @@ static void s3_virge_reset(void *priv)
 				virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
 				break;
 		}	
+		if (virge->local == S3_VIRGE_GX)
+			virge->svga.crtc[0x36] |= (1 << 2);
 	}
 
 	virge->svga.crtc[0x37] = 1 | (7 << 5);
@@ -3983,6 +4028,7 @@ static void *s3_virge_init(const device_t *info)
         
         virge->virge_rev = 0;
         virge->virge_id = 0xe1;
+        virge->is_agp = !!(info->flags & DEVICE_AGP);
 
 	switch(info->local) {
 		case S3_VIRGE_325:
@@ -4011,7 +4057,7 @@ static void *s3_virge_init(const device_t *info)
 			virge->svga.crtc[0x59] = 0x70;
 			virge->svga.vblank_start = s3_virge_vblank_start;
 			virge->chip = S3_VIRGEGX2;
-			video_inform(VIDEO_FLAG_TYPE_SPECIAL, (info->flags & DEVICE_AGP) ? &timing_virge_agp : &timing_virge_dx_pci);
+			video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci);
 			break;
 
 		case S3_TRIO_3D2X:
@@ -4023,9 +4069,12 @@ static void *s3_virge_init(const device_t *info)
 			virge->svga.crtc[0x59] = 0x70;
 			virge->svga.vblank_start = s3_virge_vblank_start;
 			virge->chip = S3_TRIO3D2X;
-			video_inform(VIDEO_FLAG_TYPE_SPECIAL, (info->flags & DEVICE_AGP) ? &timing_virge_agp : &timing_virge_dx_pci);
+			video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci);
 			break;
 
+		case S3_VIRGE_GX:
+			virge->virge_rev = 0x01;
+			/*FALLTHROUGH*/
 		default:
 			virge->svga.decode_mask = (4 << 20) - 1;
 			virge->virge_id_high = 0x8a;
@@ -4042,7 +4091,7 @@ static void *s3_virge_init(const device_t *info)
 		virge->vram_mask = (4 << 20) - 1;
 		virge->svga.vram_mask = (4 << 20) - 1;
 		virge->svga.vram_max = 4 << 20;
-		virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
+		virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5);
 	} else {
 		switch (virge->memory_size) {
 			case 2:
@@ -4064,6 +4113,8 @@ static void *s3_virge_init(const device_t *info)
 				virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
 				break;
 		}	
+		if (info->local == S3_VIRGE_GX)
+			virge->svga.crtc[0x36] |= (1 << 2);
 	}
 
 	virge->svga.crtc[0x37] = 1 | (7 << 5);
@@ -4071,7 +4122,7 @@ static void *s3_virge_init(const device_t *info)
 
 	memset(virge->dmabuffer, 0, 65536);
 
-    virge->card = pci_add_card((info->flags & DEVICE_AGP) ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge);
+	virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge);
 
 	virge->i2c = i2c_gpio_init("ddc_s3_virge");
 	virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c));
diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c
index cd2a5f33c..cf7974dd4 100644
--- a/src/win/win_media_menu.c
+++ b/src/win/win_media_menu.c
@@ -417,7 +417,9 @@ is_valid_fdd(int i)
 static inline int
 is_valid_cdrom(int i)
 {
-    if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
+    if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !MACHINE_HAS_IDE &&
+	memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) &&
+	memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
 	return 0;
     if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !MACHINE_HAS_SCSI &&
 	(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
@@ -430,7 +432,9 @@ is_valid_cdrom(int i)
 static inline int
 is_valid_zip(int i)
 {
-    if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
+    if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !MACHINE_HAS_IDE &&
+	memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) &&
+	memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
 	return 0;
     if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !MACHINE_HAS_SCSI &&
 	(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
@@ -443,7 +447,9 @@ is_valid_zip(int i)
 static inline int
 is_valid_mo(int i)
 {
-    if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
+    if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !MACHINE_HAS_IDE &&
+	memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) &&
+	memcmp(hdc_get_internal_name(hdc_current), "ide", 3))
 	return 0;
     if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !MACHINE_HAS_SCSI &&
 	(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
diff --git a/src/win/win_settings.c b/src/win/win_settings.c
index da91c271d..2f2324e2e 100644
--- a/src/win/win_settings.c
+++ b/src/win/win_settings.c
@@ -1258,6 +1258,9 @@ mpu401_standalone_allow(void)
 {
     char *md, *mdin;
 
+    if (!machine_has_bus(temp_machine, MACHINE_BUS_ISA) && !machine_has_bus(temp_machine, MACHINE_BUS_MCA))
+	return 0;
+
     md = midi_device_get_internal_name(temp_midi_device);
     mdin = midi_in_device_get_internal_name(temp_midi_input_device);
 
@@ -4902,21 +4905,25 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa
 
 			if (!device_name[0])
 				break;
-
-			if (d == 0) {
-				settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2103));
-				settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0);
-			} else
-				settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name);
-			settings_list_to_device[1][e] = d;
-			if (d == temp_isartc)
-				settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, e);
-			e++;
+			dev = isartc_get_device(d);
+			if (device_is_valid(dev, temp_machine)) {
+				if (d == 0) {
+					settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2103));
+					settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0);
+				} else
+					settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name);
+				settings_list_to_device[1][e] = d;
+				if (d == temp_isartc)
+					settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, e);
+				e++;
+			}
 		}
-		settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, temp_isartc != 0);
+		settings_enable_window(hdlg, IDC_COMBO_ISARTC, machine_has_bus(temp_machine, MACHINE_BUS_ISA));
+		settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, ((temp_isartc != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA)));
 
 		/* Populate the ISA memory card dropdowns. */
 		for (c = 0; c < ISAMEM_MAX; c++) {
+			e = 0;
 			settings_reset_content(hdlg, IDC_COMBO_ISAMEM_1 + c);
 			for (d = 0; ; d++) {
 				generate_device_name(isamem_get_device(d), (char *) isamem_get_internal_name(d), 0);
@@ -4924,16 +4931,24 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa
 				if (!device_name[0])
 					break;
 
-				if (d == 0) {
-					settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2103));
-					settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0);
-				} else
-					settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name);
+				dev = isamem_get_device(d);
+				if (device_is_valid(dev, temp_machine)) {
+					if (d == 0) {
+						settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2103));
+						settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0);
+					} else
+						settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name);
+					settings_list_to_device[0][e] = d;
+					if (d == temp_isamem[c])
+						settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, e);
+					e++;
+				}
 			}
-			settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, temp_isamem[c]);
-			settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, temp_isamem[c] != 0);
+			settings_enable_window(hdlg, IDC_COMBO_ISAMEM_1 + c, machine_has_bus(temp_machine, MACHINE_BUS_ISA));
+			settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, ((temp_isamem[c] != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA)));
 		}
 
+		settings_enable_window(hdlg, IDC_CHECK_BUGGER, machine_has_bus(temp_machine, MACHINE_BUS_ISA));
 		settings_set_check(hdlg, IDC_CHECK_BUGGER, temp_bugger);
 		settings_set_check(hdlg, IDC_CHECK_POSTCARD, temp_postcard);
 
@@ -4957,21 +4972,23 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa
 			case IDC_COMBO_ISAMEM_1: case IDC_COMBO_ISAMEM_2:
 			case IDC_COMBO_ISAMEM_3: case IDC_COMBO_ISAMEM_4:
 				c = LOWORD(wParam) - IDC_COMBO_ISAMEM_1;
-				temp_isamem[c] = settings_get_cur_sel(hdlg, LOWORD(wParam));
+				temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, LOWORD(wParam))];
 				settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, temp_isamem[c] != 0);
 				break;
 
 			case IDC_CONFIGURE_ISAMEM_1: case IDC_CONFIGURE_ISAMEM_2:
 			case IDC_CONFIGURE_ISAMEM_3: case IDC_CONFIGURE_ISAMEM_4:
 				c = LOWORD(wParam) - IDC_CONFIGURE_ISAMEM_1;
-				dev = isamem_get_device(temp_isamem[c]);
-				temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *)dev, c + 1);
+				temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *)isamem_get_device(temp_isamem[c]), c + 1);
 				break;
 		}
 		return FALSE;
 
 	case WM_SAVESETTINGS:
 		temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)];
+		for (c = 0; c < ISAMEM_MAX; c++) {
+			temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c)];
+		}
 		temp_bugger = settings_get_check(hdlg, IDC_CHECK_BUGGER);
 		temp_postcard = settings_get_check(hdlg, IDC_CHECK_POSTCARD);
 
diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c
index f8107adb2..afc906215 100644
--- a/src/win/win_stbar.c
+++ b/src/win/win_stbar.c
@@ -573,7 +573,7 @@ ui_sb_update_panes(void)
     for (i=0; i<CDROM_NUM; i++) {
 	/* Could be Internal or External IDE.. */
 	if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
-	    !ide_int && memcmp(hdc_name, "ide", 3))
+	    !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3))
 		continue;
 
 	if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int &&
@@ -586,7 +586,7 @@ ui_sb_update_panes(void)
     for (i=0; i<ZIP_NUM; i++) {
 	/* Could be Internal or External IDE.. */
 	if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
-	    !ide_int && memcmp(hdc_name, "ide", 3))
+	    !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3))
 		continue;
 
 	if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int &&
@@ -599,7 +599,7 @@ ui_sb_update_panes(void)
     for (i=0; i<MO_NUM; i++) {
 	/* Could be Internal or External IDE.. */
 	if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
-	    !ide_int && memcmp(hdc_name, "ide", 3))
+	    !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3))
 		continue;
 
 	if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int &&
@@ -666,7 +666,7 @@ ui_sb_update_panes(void)
     for (i=0; i<CDROM_NUM; i++) {
 	/* Could be Internal or External IDE.. */
 	if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
-	    !ide_int && memcmp(hdc_name, "ide", 3))
+	    !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3))
 		continue;
 	if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !scsi_int &&
 	    (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
@@ -683,7 +683,7 @@ ui_sb_update_panes(void)
     for (i=0; i<ZIP_NUM; i++) {
 	/* Could be Internal or External IDE.. */
 	if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
-	    !ide_int && memcmp(hdc_name, "ide", 3))
+	    !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3))
 		continue;
 	if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !scsi_int &&
 	    (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
@@ -700,7 +700,7 @@ ui_sb_update_panes(void)
     for (i=0; i<MO_NUM; i++) {
 	/* Could be Internal or External IDE.. */
 	if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
-	    !ide_int && memcmp(hdc_name, "ide", 3))
+	    !ide_int && memcmp(hdc_name, "xtide", 5) && memcmp(hdc_name, "ide", 3))
 		continue;
 	if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !scsi_int &&
 	    (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
diff --git a/src/win/win_ui.c b/src/win/win_ui.c
index c6a8983a6..f2d00ef1c 100644
--- a/src/win/win_ui.c
+++ b/src/win/win_ui.c
@@ -1586,6 +1586,10 @@ plat_pause(int p)
 	ui_window_title(oldtitle);
     }
 
+    /* If un-pausing, synchronize the internal clock with the host's time. */
+    if ((p == 0) && (time_sync & TIME_SYNC_ENABLED))
+	nvr_time_sync();
+
     dopause = p;
 
     /* Update the actual menu. */