[PATCH] Tracing and run-time configuration for MegaSTE/TT VME/SCU regs access

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Run-time configuration is needed because TOS v2 / v3 fail to boot on
MegaSTE / TT unless SCU register access is allowed, but that causes
Linux boot to fail on them, due to missing VME SCU interrupt
emulation.
---
 doc/hatari.1                 |  11 ++
 doc/manual.html              |  15 +++
 src/CMakeLists.txt           |   2 +-
 src/configuration.c          |   5 +
 src/debug/log.c              |   2 +
 src/debug/log.h              |   2 +
 src/includes/configuration.h |   7 ++
 src/includes/vme.h           |  14 +++
 src/ioMem.c                  |  11 +-
 src/ioMemTabTT.c             |   9 +-
 src/options.c                |  20 ++++
 src/reset.c                  |   6 +-
 src/vme.c                    | 219 +++++++++++++++++++++++++++++++++++
 13 files changed, 306 insertions(+), 17 deletions(-)
 create mode 100644 src/includes/vme.h
 create mode 100644 src/vme.c

diff --git a/doc/hatari.1 b/doc/hatari.1
index 8940400c..2892484b 100644
--- a/doc/hatari.1
+++ b/doc/hatari.1
@@ -484,6 +484,17 @@ Enable blitter emulation (ST only)
 .B \-\-dsp <x>
 Falcon DSP emulation (x = none, dummy or emu, Falcon only)
 .TP
+.B \-\-vme <x>
+Hatari doesn't have proper MegaSTE/TT VME emulation yet, but this
+controls access to related SCU registers (MegaSTE/TT only).
+
+With "dummy", (no-op) access is allowed (=VME HW), otherwise TOS v2
+and v3 crash on bootup on MegaSTE and TT.  Supports VME tracing.
+
+With "none", register access causes errors (=no VME HW), which is
+needed for Linux to boot with TT emulation until there's full SCU
+interrupt support.  No VME tracing support.
+.TP
 .B \-\-timer\-d <bool>
 Patch redundantly high Timer-D frequency set by TOS.  This about doubles
 Hatari speed (for ST/e emulation) as the original Timer-D frequency causes
diff --git a/doc/manual.html b/doc/manual.html
index fc8b5628..6032c8f3 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -997,6 +997,21 @@ megaste, tt or falcon)</p>
 <p class="parameter">--blitter
 &lt;bool&gt;</p>
 <p class="paramdesc">Enable blitter emulation (ST only)</p>
+<p class="parameter">--vme &lt;x&gt;</p>
+<p class="paramdesc">
+Hatari doesn't have proper MegaSTE/TT VME emulation yet, but this
+controls access to related SCU registers (MegaSTE/TT only).
+</br></br>
+With "dummy", (no-op) access is allowed (=VME HW), otherwise TOS v2
+and v3 crash on bootup on MegaSTE and TT.  Supports VME tracing.
+</br></br>
+With "empty", there's experimental, partial VME / SCU interrupt
+emulation, with no VME device.
+</br></br>
+With "none", register access causes errors (=no VME HW), which is
+needed for Linux to boot with TT emulation until there's full SCU
+interrupt support.  No VME tracing support.
+</p>
 <p class="parameter">--dsp &lt;x&gt;</p>
 <p class="paramdesc">Falcon DSP emulation (x = none, dummy
 or emu, Falcon only)</p>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 390deca7..cec05b0a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,7 +9,7 @@ set(SOURCES
 	ncr5380.c paths.c  psg.c printer.c resolution.c rs232.c reset.c rtc.c
 	scandir.c scc.c stMemory.c screen.c screenConvert.c screenSnapShot.c
 	shortcut.c sound.c spec512.c statusbar.c str.c tos.c utils.c
-	vdi.c inffile.c video.c wavFormat.c xbios.c ymFormat.c lilo.c)
+	vdi.c vme.c inffile.c video.c wavFormat.c xbios.c ymFormat.c lilo.c)
 
 # Disk image code is shared with the hmsa tool, so we put it into a library:
 add_library(Floppy createBlankImage.c dim.c msa.c st.c zip.c)
diff --git a/src/configuration.c b/src/configuration.c
index cd43fbc6..339e469e 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -603,6 +603,7 @@ static const struct Config_Tag configs_System[] =
 	{ "nModelType", Int_Tag, &ConfigureParams.System.nMachineType },
 	{ "bBlitter", Bool_Tag, &ConfigureParams.System.bBlitter },
 	{ "nDSPType", Int_Tag, &ConfigureParams.System.nDSPType },
+	{ "nVMEType", Int_Tag, &ConfigureParams.System.nVMEType },
 	{ "bPatchTimerD", Bool_Tag, &ConfigureParams.System.bPatchTimerD },
 	{ "bFastBoot", Bool_Tag, &ConfigureParams.System.bFastBoot },
 	{ "bFastForward", Bool_Tag, &ConfigureParams.System.bFastForward },
@@ -885,6 +886,7 @@ void Configuration_SetDefault(void)
 	ConfigureParams.System.nCpuLevel = 0;
 	ConfigureParams.System.nCpuFreq = 8;	nCpuFreqShift = 0;
 	ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
+	ConfigureParams.System.nVMEType = VME_TYPE_DUMMY; /* for TOS MegaSTE detection */
 	ConfigureParams.System.bAddressSpace24 = true;
 	ConfigureParams.System.n_FPUType = FPU_NONE;
 	ConfigureParams.System.bCompatibleFPU = true; /* JIT */
@@ -1283,6 +1285,9 @@ void Configuration_MemorySnapShot_Capture(bool bSave)
 	MemorySnapShot_Store(&ConfigureParams.System.nMachineType, sizeof(ConfigureParams.System.nMachineType));
 	MemorySnapShot_Store(&ConfigureParams.System.bBlitter, sizeof(ConfigureParams.System.bBlitter));
 	MemorySnapShot_Store(&ConfigureParams.System.nDSPType, sizeof(ConfigureParams.System.nDSPType));
+	/* TODO: enable after VME_TYPE_EMPTY VME/SCU interrupt emulation is implemented
+	MemorySnapShot_Store(&ConfigureParams.System.nVMEType, sizeof(ConfigureParams.System.nVMEType));
+	 */
 	MemorySnapShot_Store(&bOldRealTimeClock, sizeof(bOldRealTimeClock));	/* TODO: Can be removed later */
 	MemorySnapShot_Store(&ConfigureParams.System.bPatchTimerD, sizeof(ConfigureParams.System.bPatchTimerD));
 	MemorySnapShot_Store(&ConfigureParams.System.bAddressSpace24, sizeof(ConfigureParams.System.bAddressSpace24));
diff --git a/src/debug/log.c b/src/debug/log.c
index e52033cb..eb437479 100644
--- a/src/debug/log.c
+++ b/src/debug/log.c
@@ -150,6 +150,8 @@ static flagname_t TraceFlags[] = {
 
 	{ TRACE_MEM		 , "mem" } ,
 
+	{ TRACE_VME		 , "vme" } ,
+
 	{ TRACE_ALL		 , "all" }
 };
 #endif /* ENABLE_TRACING */
diff --git a/src/debug/log.h b/src/debug/log.h
index bed5754e..9be233f9 100644
--- a/src/debug/log.h
+++ b/src/debug/log.h
@@ -182,6 +182,8 @@ extern char *Log_MatchTrace(const char *text, int state);
     
 #define TRACE_MEM		 (1ll<<54)
 
+#define TRACE_VME		 (1ll<<55)
+
 #define	TRACE_NONE		 (0)
 #define	TRACE_ALL		 (~0)
 
diff --git a/src/includes/configuration.h b/src/includes/configuration.h
index 464e04d0..2b86203b 100644
--- a/src/includes/configuration.h
+++ b/src/includes/configuration.h
@@ -354,6 +354,12 @@ typedef enum
   DSP_TYPE_EMU
 } DSPTYPE;
 
+typedef enum
+{
+  VME_TYPE_NONE,
+  VME_TYPE_DUMMY
+} VMETYPE;
+
 typedef enum
 {
   FPU_NONE = 0,
@@ -379,6 +385,7 @@ typedef struct
   MACHINETYPE nMachineType;
   bool bBlitter;                  /* TRUE if Blitter is enabled */
   DSPTYPE nDSPType;               /* how to "emulate" DSP */
+  VMETYPE nVMEType;               /* how to "emulate" SCU/VME */
   bool bPatchTimerD;
   bool bFastBoot;                 /* Enable to patch TOS for fast boot */
   bool bFastForward;
diff --git a/src/includes/vme.h b/src/includes/vme.h
new file mode 100644
index 00000000..0d788d9c
--- /dev/null
+++ b/src/includes/vme.h
@@ -0,0 +1,14 @@
+/*
+  Hatari - vme.h
+
+  This file is distributed under the GNU General Public License, version 2
+  or at your option any later version. Read the file gpl.txt for details.
+*/
+
+#ifndef HATARI_VME_H
+#define HATARI_VME_H
+
+extern void VME_SetAccess(void (**readtab)(void), void (**writetab)(void));
+extern void VME_Reset(void);
+
+#endif
diff --git a/src/ioMem.c b/src/ioMem.c
index 6b3c92e8..42f2b4cc 100644
--- a/src/ioMem.c
+++ b/src/ioMem.c
@@ -41,6 +41,7 @@ const char IoMem_fileid[] = "Hatari ioMem.c";
 #include "log.h"
 #include "scc.h"
 #include "fdc.h"
+#include "vme.h"
 
 
 static void (*pInterceptReadTable[0x8000])(void);	/* Table with read access handlers */
@@ -202,13 +203,6 @@ static void IoMem_FixAccessForMegaSTE(void)
 	pInterceptReadTable[0xff8e23 - 0xff8000] = IoMem_VoidRead;
 	pInterceptWriteTable[0xff8e23 - 0xff8000] = IoMem_VoidWrite;
 
-	/* VME bus - we don't support it yet, but TOS uses FF8E09 to detect the Mega-STE */
-	for (addr = 0xff8e01; addr <= 0xff8e0f; addr += 2)
-	{
-		pInterceptReadTable[addr - 0xff8000] = IoMem_ReadWithoutInterception;
-		pInterceptWriteTable[addr - 0xff8000] = IoMem_WriteWithoutInterception;
-	}
-
 	/* The Mega-STE has a Z85C30 SCC serial port, too: */
 	for (addr = 0xff8c80; addr <= 0xff8c87; addr++)
 	{
@@ -328,6 +322,9 @@ void IoMem_Init(void)
 	else if ( ConfigureParams.System.nMachineType == MACHINE_MEGA_STE )
 		IoMem_FixAccessForMegaSTE();
 
+	/* Whether to support VME / SCU register access */
+	if (Config_IsMachineTT() || Config_IsMachineMegaSTE())
+		VME_SetAccess(pInterceptReadTable, pInterceptWriteTable);
 
 	/* Set registers for Falcon */
 	if (Config_IsMachineFalcon())
diff --git a/src/ioMemTabTT.c b/src/ioMemTabTT.c
index 4de5f246..8db2bc9e 100644
--- a/src/ioMemTabTT.c
+++ b/src/ioMemTabTT.c
@@ -180,14 +180,7 @@ const INTERCEPT_ACCESS_FUNC IoMemTable_TT[] =
 	{ 0xff8c80, 8, SCC_IoMem_ReadByte, SCC_IoMem_WriteByte },                               /* SCC */
 	{ 0xff8c88, 8, IoMem_VoidRead_00, IoMem_VoidWrite },                                    /* No bus error here */
 
-	{ 0xff8e01, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU system interrupt mask */
-	{ 0xff8e03, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU system interrupt state */
-	{ 0xff8e05, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU system interrupter */
-	{ 0xff8e07, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU VME interrupter */
-	{ 0xff8e09, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU general purpose 1 */
-	{ 0xff8e0b, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU general purpose 2 */
-	{ 0xff8e0d, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU VME interrupt mask */
-	{ 0xff8e0f, 1, IoMem_ReadWithoutInterception, IoMem_WriteWithoutInterception },         /* SCU VME interrupt state */
+	/* VME/SCU 0xff8e01-0xff8e0f registers set set at run-time in ioMem.c/vme.c for MegaSTE & TT */
 
 	{ 0xff9000, SIZE_WORD, IoMem_VoidRead, IoMem_VoidWrite },                /* No bus error here */
 	{ 0xff9200, SIZE_WORD, IoMemTabTT_ReadDIPSwitches, IoMem_VoidWrite },    /* DIP switches */
diff --git a/src/options.c b/src/options.c
index 7f852373..a4ccf3c0 100644
--- a/src/options.c
+++ b/src/options.c
@@ -157,6 +157,7 @@ enum {
 	OPT_MMU,
 	OPT_MACHINE,		/* system options */
 	OPT_BLITTER,
+	OPT_VME,
 	OPT_DSP,
 	OPT_TIMERD,
 	OPT_FASTBOOT,
@@ -434,6 +435,8 @@ static const opt_t HatariOptions[] = {
 	  "<bool>", "Use blitter emulation (ST only)" },
 	{ OPT_DSP,       NULL, "--dsp",
 	  "<x>", "DSP emulation (x = none/dummy/emu, Falcon only)" },
+	{ OPT_VME,	NULL, "--vme",
+	  "<x>", "VME mode (x = none/dummy, MegaSTE/TT only)" },
 	{ OPT_TIMERD,    NULL, "--timer-d",
 	  "<bool>", "Patch Timer-D (about doubles ST emulation speed)" },
 	{ OPT_FASTBOOT, NULL, "--fast-boot",
@@ -1977,6 +1980,23 @@ bool Opt_ParseParameters(int argc, const char * const argv[])
 			bLoadAutoSave = false;
 			break;
 
+		case OPT_VME:
+			i += 1;
+			if (strcasecmp(argv[i], "dummy") == 0)
+			{
+				ConfigureParams.System.nVMEType = VME_TYPE_DUMMY;
+			}
+			else if (strcasecmp(argv[i], "none") == 0)
+			{
+				ConfigureParams.System.nVMEType = VME_TYPE_NONE;
+			}
+			else
+			{
+				return Opt_ShowError(OPT_VME, argv[i], "Unknown VME type");
+			}
+			bLoadAutoSave = false; /* TODO: needed? */
+			break;
+
 			/* sound options */
 		case OPT_YM_MIXING:
 			i += 1;
diff --git a/src/reset.c b/src/reset.c
index 83c18d73..3f668be5 100644
--- a/src/reset.c
+++ b/src/reset.c
@@ -36,6 +36,7 @@ const char Reset_fileid[] = "Hatari reset.c";
 #include "vdi.h"
 #include "nvram.h"
 #include "video.h"
+#include "vme.h"
 #include "falcon/videl.h"
 #include "falcon/dsp.h"
 #include "debugcpu.h"
@@ -84,7 +85,10 @@ static int Reset_ST(bool bCold)
 	{
 		Ncr5380_Reset();
 	}
-
+	if (Config_IsMachineTT() || Config_IsMachineMegaSTE())
+	{
+		VME_Reset();
+	}
 	if (Config_IsMachineFalcon())
 	{
 		DSP_Reset();                  /* Reset the DSP */
diff --git a/src/vme.c b/src/vme.c
new file mode 100644
index 00000000..9cd328e0
--- /dev/null
+++ b/src/vme.c
@@ -0,0 +1,219 @@
+/*
+  Hatari - vme.c
+
+  This file is distributed under the GNU General Public License, version 2
+  or at your option any later version. Read the file gpl.txt for details.
+
+  VMEbus / SCU (System Control Unit) interrupt handling.
+
+  TODO: Non-cacheable TT VME card address mapping (word based data transfer):
+  - FE000000-FEFEFFFF VMEbus A24:D16
+  - FEFF0000-FEFFFFFF VMEbus A16:D16
+
+  TODO: more limited MegaSTE VME card address mapping:
+  - 00A00000-00DEFFFF VMEbus A24:D16
+  - 00DF0000-00DFFFFF VMEbus A16:D16
+
+  SCU IRQ info from TT HW reference:
+  - SCU generated IRQ1 is detected only by the MPU not the VMEbus
+  - SCU generated IRQ1 and IRQ3 are hardwired to the corresponding
+    priorities and are always auto vectored
+  - only interrupts 5 and 6 have external IACK pins and are capable
+    of generating vectored interrupts on the motherboard (and also
+    cause VME IRQ5 and IRQ6 respectively)
+  - VMEbus SYSFAIL generates a system (motherboard) IRQ7 to the MPU,
+    but does not not generate an IRQ7 to the VMEbus. The only other
+    source of an IRQ7 is a VMEbus card
+*/
+const char vme_fileid[] = "Hatari vme.c";
+
+#include "main.h"
+#include "configuration.h"
+#include "ioMem.h"
+#include "log.h"
+#include "vme.h"
+
+#define IOTAB_OFFSET 0xff8000
+
+/**
+ * SCU trace logging
+ */
+static void SCU_Trace(const char *access, const char *info)
+{
+	int addr = IoAccessCurrentAddress;
+	LOG_TRACE(TRACE_VME, "VME: SCU %s (0x%x): 0x%02x %s\n", access, addr, IoMem[addr], info);
+}
+
+/**
+ * Generic SCU reg read access function
+ */
+static void SCU_TraceRead(void)
+{
+	SCU_Trace("read ", "");
+}
+
+/**
+ * 0xff8e01 - masks interrupts generated on the system (board)
+ *
+ * Bits 1-7 -> IRQ 0-6, Bit 0 unused
+ *
+ * IRQ5 & IRQ6 can be serviced either by 68030 or VMEbus master,
+ * so they cannot be masked independently by VME & system masks.
+ */
+static void SCU_SysIntMask_WriteByte(void)
+{
+	SCU_Trace("write", "(system interrupt mask)");
+	/* TODO: implement interrupt masking */
+}
+/**
+ * 0xff8e03 - system interrupt status before they are masked with above
+ */
+static void SCU_SysIntState_ReadByte(void)
+{
+	SCU_Trace("read ", "(system interrupt state)");
+	/* TODO: provide non-masked interrupt status */
+}
+static void SCU_SysIntState_WriteByte(void)
+{
+	SCU_Trace("write", "(system interrupt state - READ ONLY)");
+}
+
+/**
+ * 0xff8e05 - SCU system interrupter
+ *
+ * Bit 0 controls VME IRQ1 setting/clearing
+ */
+static void SCU_SysInterrupter_WriteByte(void)
+{
+	if (IoMem[0xff8e05] & 0x1) {
+		SCU_Trace("write", "(system interrupter, IRQ1 set)");
+		/* TODO: generate auto vectored level 1 interrupt (IRQ1),
+		 * interrupt CPU immediately unless masked off
+		 */
+	} else {
+		SCU_Trace("write", "(system interrupter, IRQ1 clear)");
+		/* TODO: clear VMEbus IRQ1 */
+	}
+}
+/**
+ * 0xff8e07 - SCU VME interrupter
+ *
+ * Bit 0 controls VME IRQ3 setting/clearing
+ */
+static void SCU_VmeInterrupter_WriteByte(void)
+{
+	if (IoMem[0xff8e07] & 0x1) {
+		SCU_Trace("write", "(VME interrupter, IRQ3 set)");
+		/* TODO: generate VMEbus level 3 interrupt (IRQ3),
+		 * interrupt CPU immediately unless masked off
+		 *
+		 * System responds to interrupt acknowledge cycle
+		 * with the status ID of 0xFF
+		 *
+		 * Status word supplied by the card during acknowledge
+		 * cycle is used as 030 interrupt vector.
+		 */
+	} else {
+		SCU_Trace("write", "(VME interrupter, IRQ3 clear)");
+		/* TODO: clear VMEbus IRQ3 */
+	}
+}
+
+/**
+ * 0xff8e09 - SCU general purpose reg 1
+ */
+static void SCU_GenReg1_WriteByte(void)
+{
+	SCU_Trace("write", "(general reg 1)");
+}
+/**
+ * 0xff8e0b - SCU general purpose reg 2
+ */
+static void SCU_GenReg2_WriteByte(void)
+{
+	SCU_Trace("write", "(general reg 2)");
+}
+
+/**
+ * 0xff8e0d - masks interrupts generated by VMEbus sources
+ *
+ * Bits 1-7 -> IRQ 0-6, Bit 0 unused
+ */
+static void SCU_VmeIntMask_WriteByte(void)
+{
+	SCU_Trace("write", "(VME interrupt mask)");
+	/* TODO: implement interrupt masking */
+}
+/**
+ * 0xff8e0f - VME interrupt status before they are masked with above
+ */
+static void SCU_VmeIntState_ReadByte(void)
+{
+	SCU_Trace("read ", "(VME interrupt state)");
+	/* TODO: provide non-masked interrupt status */
+}
+static void SCU_VmeIntState_WriteByte(void)
+{
+	SCU_Trace("write", "(VME interrupt state - READ ONLY)");
+}
+
+/**
+ * Allow VME SCU register access and set up tracing
+ */
+static void SCUSetupTracing(void (**reads)(void), void (**writes)(void))
+{
+	reads[0xff8e01 - IOTAB_OFFSET] = SCU_TraceRead;
+	reads[0xff8e03 - IOTAB_OFFSET] = SCU_SysIntState_ReadByte;
+	reads[0xff8e05 - IOTAB_OFFSET] = SCU_TraceRead;
+	reads[0xff8e07 - IOTAB_OFFSET] = SCU_TraceRead;
+	reads[0xff8e09 - IOTAB_OFFSET] = SCU_TraceRead;
+	reads[0xff8e0b - IOTAB_OFFSET] = SCU_TraceRead;
+	reads[0xff8e0d - IOTAB_OFFSET] = SCU_TraceRead;
+	reads[0xff8e0f - IOTAB_OFFSET] = SCU_VmeIntState_ReadByte;
+
+	writes[0xff8e01 - IOTAB_OFFSET] = SCU_SysIntMask_WriteByte;      /* SCU system interrupt mask */
+	writes[0xff8e03 - IOTAB_OFFSET] = SCU_SysIntState_WriteByte;     /* SCU system interrupt state (RO) */
+	writes[0xff8e05 - IOTAB_OFFSET] = SCU_SysInterrupter_WriteByte;  /* SCU system interrupter */
+	writes[0xff8e07 - IOTAB_OFFSET] = SCU_VmeInterrupter_WriteByte;  /* SCU VME interrupter */
+	writes[0xff8e09 - IOTAB_OFFSET] = SCU_GenReg1_WriteByte;         /* SCU general purpose 1 */
+	writes[0xff8e0b - IOTAB_OFFSET] = SCU_GenReg2_WriteByte;         /* SCU general purpose 2 */
+	writes[0xff8e0d - IOTAB_OFFSET] = SCU_VmeIntMask_WriteByte;      /* SCU VME interrupt mask */
+	writes[0xff8e0f - IOTAB_OFFSET] = SCU_VmeIntState_WriteByte;     /* SCU VME interrupt state (RO) */
+}
+
+/**
+ * Set VME (SCU) register accessors based on Hatari configuration
+ * VME type setting
+ */
+void VME_SetAccess(void (**readtab)(void), void (**writetab)(void))
+{
+	/*
+	 * Hatari does't emulate VME / SCU interrupts yet, but:
+	 * - TOS2 crashes on MegaSTE unless it can access SCU regs
+	 * - TOS3 crashes on TT unless it can access SCU regs
+	 * - Linux freezes on boot if it can access SCU regs
+	 *   (as it tries then to use them, and they aren't
+	 *   fully emulated)
+	 *
+	 * => Use "dummy" mode for TOS 2 & 3, "none" for m68k Linux
+	 */
+	if (ConfigureParams.System.nVMEType == VME_TYPE_DUMMY) {
+		SCUSetupTracing(readtab, writetab);
+	}
+}
+
+/**
+ * Reset VME / SCU registers and interrupts
+ */
+void VME_Reset(void)
+{
+	int addr;
+	/* docs say that all SCU regs are cleared on reset */
+	for (addr = 0xff8e01; addr <= 0xff8e0f; addr += 2) {
+		IoMem[addr] = 0;
+	}
+	/* TODO: TOS v2 & v3 crash unless gen reg 1 has this value, why? */
+	IoMem[0xff8e09] = 0x1;
+
+	/* TODO: clear all SCU interrupts */
+}
-- 
2.20.1


--------------B13909ECEF288043F33E2AFA--



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/