summaryrefslogtreecommitdiffstats
path: root/Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMVIRT.C
diff options
context:
space:
mode:
authorSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
committerSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
commit33613a85afc4b1481367fbe92a17ee59c240250b (patch)
tree670b842326116b376b505ec2263878912fca97e2 /Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMVIRT.C
downloadStudium-master.tar.gz
Studium-master.tar.bz2
add new repoHEADmaster
Diffstat (limited to 'Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMVIRT.C')
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMVIRT.C871
1 files changed, 871 insertions, 0 deletions
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMVIRT.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMVIRT.C
new file mode 100644
index 0000000..70ec5d0
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMVIRT.C
@@ -0,0 +1,871 @@
+/***************************************************************************
+ * armvirt.c
+ * ARMulator II virtual memory interface.
+ * Copyright (C) 1991 Advanced RISC Machines Limited. All rights reserved.
+ ***************************************************************************/
+
+/*
+ * RCS $Revision: 1.19.2.4 $
+ * Checkin $Date: 1995/08/31 09:36:54 $
+ * Revising $Author: plg $
+ */
+
+/* This file contains a complete ARMulator memory model, modelling a
+"virtual memory" system. A much simpler model can be found in
+armfast.c, and that model goes faster too, but has a fixed amount of
+memory. This model's memory has 64K pages, allocated on demand from a
+64K entry page table, when the page is first written. Reads to an
+unwritten (un-allocated) page are serviced by an access to a dummy page.
+Pages are never freed as they might be needed again. A single area of
+memory can be defined to generate aborts. */
+
+#include "armdefs.h"
+
+/* The following hack, if defined, uses the F counter to count 32 bit
+ word accesses. This is useful when pretending to have 16 bit wide memory.
+ */
+/* #define RUN_IN_16_BIT_MEMORY_HACK */
+
+
+#ifdef VALIDATE /* for running the validate suite */
+#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
+#define ABORTS 1
+#endif
+
+#ifdef ABORTS /* the memory system will abort */
+/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
+ For the new test suite Abort between 8 Mbytes and 26 Mbytes */
+#define LOWABORT 32 * 1024
+#define HIGHABORT 32 * 1024 * 1024
+/* #define LOWABORT 8 * 1024 * 1024
+#define HIGHABORT 26 * 1024 * 1024 */
+#endif
+
+#define TOP_OF_MEM 0x80000000 /* 2Gb to avoid stack-checking probs */
+#define NUMPAGES 64 * 1024
+#define PAGESIZE 64 * 1024
+#define PAGEBITS 16
+#define WORDOFFSETBITS 0xfffc
+#define HWRDOFFSETBITS 0xfffe
+#define BYTEOFFSETBITS 0xffff
+#define ENDSWAP(addr) (addr ^ 3)
+#define ENDSWAPH(addr) (addr ^ 2)
+static unsigned HostEndian ;
+
+#define PAGETABLE ((unsigned char **)state->MemDataPtr)
+#define DUMMYPAGE ((unsigned char *)state->MemSparePtr)
+
+/***************************************************************************\
+* Get a Word/Byte from Virtual Memory *
+\***************************************************************************/
+
+#define GetWord(state, address) \
+ *( (ARMword *) \
+ ( *(PAGETABLE + (address >> PAGEBITS)) + (address & WORDOFFSETBITS) ) \
+ )
+
+#define GetHalfWord(state, address) \
+ (HostEndian ? \
+ ( \
+ (*( *(PAGETABLE + (address >> PAGEBITS)) + (address & HWRDOFFSETBITS)) << 8) + \
+ *( *(PAGETABLE + (address >> PAGEBITS)) + (address & HWRDOFFSETBITS) + 1) \
+ ) : \
+ ( \
+ *( *(PAGETABLE + (address >> PAGEBITS)) + (address & HWRDOFFSETBITS)) + \
+ (*( *(PAGETABLE + (address >> PAGEBITS)) + (address & HWRDOFFSETBITS) + 1) << 8) \
+ ))
+
+#define GetByte(state, address) \
+ *( \
+ ( *(PAGETABLE + (address >> PAGEBITS)) + (address & BYTEOFFSETBITS) ) \
+ )
+
+/***************************************************************************\
+* Put a Word/Byte into Virtual Memory, maybe allocating the page *
+\***************************************************************************/
+
+#define PutWord(state, address, data) \
+ {unsigned char *xxpageptr; \
+ if ((xxpageptr = PAGETABLE[address >> PAGEBITS]) == DUMMYPAGE) \
+ xxpageptr = AllocatePage(state,address); \
+ *(ARMword *)(xxpageptr + (address & WORDOFFSETBITS)) = data; \
+ }
+
+#define PutHalfWord(state, address, data) \
+ {unsigned char *xxpageptr; \
+ ARMword xxaddr; \
+ if ((xxpageptr = PAGETABLE[(address) >> PAGEBITS]) == DUMMYPAGE) \
+ xxpageptr = AllocatePage(state, address); \
+ xxaddr = (address) & HWRDOFFSETBITS; \
+ if (HostEndian) { \
+ xxpageptr[xxaddr] = (unsigned char)(((data) & 0xff00) >> 8); \
+ xxpageptr[xxaddr + 1] = (unsigned char)((data) & 0xff); \
+ } else { \
+ xxpageptr[xxaddr] = (unsigned char)((data) & 0xff); \
+ xxpageptr[xxaddr + 1] = (unsigned char)(((data) & 0xff00) >> 8); \
+ } \
+ }
+
+#define PutByte(state, address, data) \
+ {unsigned char *xxpageptr ; \
+ if ((xxpageptr = PAGETABLE[address >> PAGEBITS]) == DUMMYPAGE) \
+ xxpageptr = AllocatePage(state,address) ; \
+ xxpageptr[address & BYTEOFFSETBITS] = (unsigned char)data ; \
+ }
+
+/***************************************************************************\
+* Allocate and return a memory page *
+\***************************************************************************/
+
+static unsigned char * AllocatePage(ARMul_State *state, ARMword address)
+{unsigned char *pageptr ;
+
+ pageptr = (unsigned char *)malloc(PAGESIZE) ;
+ if (pageptr == NULL) {
+ perror("ARMulator can't allocate VM page") ;
+ exit(13) ;
+ }
+ *(PAGETABLE + (address >> PAGEBITS)) = pageptr ;
+ return(pageptr) ;
+ }
+
+/***************************************************************************\
+* Initialise the memory interface *
+\***************************************************************************/
+
+unsigned ARMul_MemoryInit(ARMul_State *state, unsigned long initmemsize)
+{unsigned char **pagetable ;
+ unsigned page ;
+ unsigned char *dummypage ;
+
+ if (initmemsize == 0)
+ state->MemSize = TOP_OF_MEM; /* initialise to 4Gb if no size specified */
+ else
+ state->MemSize = initmemsize;
+ if ((pagetable = (unsigned char **)malloc(sizeof(ARMword *)*NUMPAGES))==NULL)
+ return(FALSE) ;
+ if ((dummypage = (unsigned char *)malloc(PAGESIZE))==NULL)
+ return(FALSE) ;
+ for (page = 0 ; page < NUMPAGES ; page++)
+ *(pagetable + page) = dummypage ;
+ state->MemDataPtr = (unsigned char *)pagetable ;
+ state->MemSparePtr = (unsigned char *)dummypage ;
+ *(ARMword *)dummypage = 1 ;
+ HostEndian = (*dummypage != 1) ; /* 1 for big endian, 0 for little */
+ *(ARMword *)dummypage = 0 ;
+#ifdef BIGEND
+ state->bigendSig = HIGH ;
+#endif
+#ifdef LITTLEEND
+ state->bigendSig = LOW ;
+#endif
+ if (state->MemSize >= 10 * 1024 * 1024)
+ ARMul_ConsolePrint(state, ", %dMbyte",state->MemSize/1024/1024);
+ else
+ ARMul_ConsolePrint(state, ", %dKbyte",state->MemSize/1024);
+ return(TRUE) ;
+}
+
+/***************************************************************************\
+* Remove the memory interface *
+\***************************************************************************/
+
+void ARMul_MemoryExit(ARMul_State *state)
+{ARMword page ;
+ unsigned char *pageptr ;
+
+ for (page = 0 ; page < NUMPAGES ; page++) {
+ pageptr = *(PAGETABLE + page) ;
+ if (pageptr != DUMMYPAGE)
+ free((unsigned char *)pageptr) ;
+ }
+ free((unsigned char *)DUMMYPAGE) ;
+ free((unsigned char *)PAGETABLE) ;
+ return ;
+ }
+
+/***************************************************************************\
+* Load Instruction, Sequential Cycle *
+\***************************************************************************/
+
+#define NS_PER_S 1000000000
+#define ADDNS(p,t) \
+ do { \
+ (p)->a.ns += (p)->t; \
+ if ((p)->a.ns >= NS_PER_S) (p)->a.ns -= NS_PER_S, (p)->a.s++; } \
+ while (0)
+
+ARMword ARMul_LoadInstrS(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+
+ state->NumScycles++ ;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Sreads += 4L >> m->md.width;
+ ADDNS(m, ns_LoadInstrS);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef HOURGLASS_RATE
+ if( ( state->NumScycles & HOURGLASS_RATE ) == 0 ) {
+ armsd_hourglass();
+ }
+#endif
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_PREFETCHABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ return(GetWord(state,address)) ;
+}
+
+/***************************************************************************\
+* Load Instruction, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstrN(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+
+ state->NumNcycles++ ;
+#ifdef RUN_IN_16_BIT_MEMORY_HACK
+state->NumFcycles++ ;
+#endif
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nreads++;
+ m->a.Sreads += (4L >> m->md.width) - 1;
+ ADDNS(m, ns_LoadInstrN);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_PREFETCHABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ return(GetWord(state,address)) ;
+}
+
+/***************************************************************************\
+* Load 16 bit Instruction, Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstr16S(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+ ARMword temp ;
+
+ state->NumScycles++ ;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ if ((m->md.access & 4) && (address & 2) && m->md.width == 2) {
+ m->a.ns += state->cpu_ns;
+ } else {
+ m->a.Sreads++;
+ if (m->md.width == 0) m->a.Sreads++;
+ m->a.ns += m->ns_LoadInstr16S;
+ }
+ if (m->a.ns >= NS_PER_S) m->a.ns -= NS_PER_S, m->a.s++;
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef HOURGLASS_RATE
+ if( ( state->NumScycles & HOURGLASS_RATE ) == 0 ) {
+ armsd_hourglass();
+ }
+#endif
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_PREFETCHABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAPH(address) ;
+ return((ARMword)GetHalfWord(state,temp)) ;
+}
+
+/***************************************************************************\
+* Load 16 bit Instruction, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstr16N(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+ ARMword temp ;
+
+ state->NumNcycles++ ;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nreads++;
+ if (m->md.width == 0) m->a.Sreads++;
+ ADDNS(m, ns_LoadInstr16N);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_PREFETCHABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAPH(address) ;
+ return((ARMword)GetHalfWord(state,temp)) ;
+ }
+
+/***************************************************************************\
+* Load Word, Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordS(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+
+ state->NumScycles++ ;
+#ifdef RUN_IN_16_BIT_MEMORY_HACK
+state->NumFcycles++ ;
+#endif
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Sreads += 4L >> m->md.width;
+ ADDNS(m, ns_LoadWordS);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(0) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ return(GetWord(state,address)) ;
+ }
+
+/***************************************************************************\
+* Load Word, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordN(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+
+ state->NumNcycles++ ;
+#ifdef RUN_IN_16_BIT_MEMORY_HACK
+state->NumFcycles++ ;
+#endif
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nreads++;
+ m->a.Sreads += (4L >> m->md.width) - 1;
+ ADDNS(m, ns_LoadWordN);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(0) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ return(GetWord(state,address)) ;
+ }
+
+/***************************************************************************\
+* Load Halfword, (Non Sequential Cycle) *
+\***************************************************************************/
+
+ARMword ARMul_LoadHalfWord(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+ ARMword temp ;
+
+ state->NumNcycles++ ;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nreads++;
+ if (m->md.width == 0) m->a.Sreads++;
+ ADDNS(m, ns_LoadHalfWord);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(0) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAPH(address) ;
+ return((ARMword)GetHalfWord(state,temp)) ;
+ }
+
+/***************************************************************************\
+* Load Byte, (Non Sequential Cycle) *
+\***************************************************************************/
+
+ARMword ARMul_LoadByte(ARMul_State *state,ARMword address)
+{
+ MemDescr *m;
+ ARMword temp ;
+
+ state->NumNcycles++ ;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nreads++;
+ ADDNS(m, ns_LoadByte);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(0) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAP(address) ;
+ return((ARMword)GetByte(state,temp)) ;
+ }
+
+/***************************************************************************\
+* Store Word, Sequential Cycle *
+\***************************************************************************/
+
+void ARMul_StoreWordS(ARMul_State *state,ARMword address, ARMword data)
+{
+ MemDescr *m;
+
+ state->NumScycles++ ;
+#ifdef RUN_IN_16_BIT_MEMORY_HACK
+state->NumFcycles++ ;
+#endif
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Swrites += 4L >> m->md.width;
+ ADDNS(m, ns_StoreWordS);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ PutWord(state,address,data) ;
+ }
+
+/***************************************************************************\
+* Store Word, Non Sequential Cycle *
+\***************************************************************************/
+
+void ARMul_StoreWordN(ARMul_State *state, ARMword address, ARMword data)
+{
+ MemDescr *m;
+
+ state->NumNcycles++ ;
+#ifdef RUN_IN_16_BIT_MEMORY_HACK
+state->NumFcycles++ ;
+#endif
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nwrites++;
+ m->a.Swrites += (4L >> m->md.width) - 1;
+ ADDNS(m, ns_StoreWordN);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ PutWord(state,address,data) ;
+ }
+
+/***************************************************************************\
+* Store HalfWord, Non Sequential Cycle *
+\***************************************************************************/
+
+void ARMul_StoreHalfWord(ARMul_State *state, ARMword address, ARMword data)
+{
+ MemDescr *m;
+ ARMword temp ;
+
+ state->NumNcycles++ ;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nwrites++;
+ if (m->md.width == 0) m->a.Swrites++;
+ ADDNS(m, ns_StoreHalfWord);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAPH(address) ;
+ PutHalfWord(state,temp,data) ;
+}
+
+/***************************************************************************\
+* Store Byte, (Non Sequential Cycle) *
+\***************************************************************************/
+
+void ARMul_StoreByte(ARMul_State *state, ARMword address, ARMword data)
+{
+ MemDescr *m;
+
+ ARMword temp ;
+
+ state->NumNcycles++ ;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nwrites++;
+ ADDNS(m, ns_StoreByte);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef VALIDATE
+ if (address == TUBE) {
+ if (data == 4)
+ state->Emulate = FALSE ;
+ else
+ (void)putc((char)data,stderr) ; /* Write Char */
+ return ;
+ }
+#endif
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAP(address) ;
+ PutByte(state,temp,(unsigned char)data) ;
+ }
+
+/***************************************************************************\
+* Swap Word, (Two Non Sequential Cycles) *
+\***************************************************************************/
+
+ARMword ARMul_SwapWord(ARMul_State *state, ARMword address, ARMword data)
+{
+ MemDescr *m;
+ ARMword temp ;
+
+ state->NumNcycles+=2;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nreads++;
+ m->a.Nwrites++;
+ m->a.Sreads += (4L >> m->md.width) - 1;
+ m->a.Swrites += (4L >> m->md.width) - 1;
+ ADDNS(m, ns_SwapWord);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = GetWord(state,address) ;
+ PutWord(state,address,data) ;
+ return(temp) ;
+}
+
+/***************************************************************************\
+* Swap Byte, (Two Non Sequential Cycles) *
+\***************************************************************************/
+
+ARMword ARMul_SwapByte(ARMul_State *state, ARMword address, ARMword data)
+{
+ MemDescr *m;
+ ARMword temp ;
+
+ state->NumNcycles+=2;
+ for (m = state->MemInfoPtr; m != NULL; m = m->next)
+ if (address >= m->md.start && address < m->md.limit) {
+ m->a.Nreads++;
+ m->a.Nwrites++;
+ ADDNS(m, ns_SwapByte);
+ break;
+ }
+ if (!m) {
+ state->ns += state->cpu_ns;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ }
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = ARMul_LoadByte(state,address) ;
+ ARMul_StoreByte(state,address,data) ;
+ return(temp) ;
+ }
+
+/***************************************************************************\
+* Count I Cycles *
+\***************************************************************************/
+
+void ARMul_Icycles(ARMul_State *state, unsigned number, ARMword address)
+{
+ state->NumIcycles += number ;
+ state->ns += state->cpu_ns * number;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ ARMul_CLEARABORT ;
+ }
+
+/***************************************************************************\
+* Count C Cycles *
+\***************************************************************************/
+
+void ARMul_Ccycles(ARMul_State *state, unsigned number, ARMword address)
+{
+ state->NumCcycles += number ;
+ state->ns += state->cpu_ns * number;
+ if (state->ns >= NS_PER_S) state->ns -= NS_PER_S, state->s++;
+ ARMul_CLEARABORT ;
+ }
+
+/***************************************************************************\
+* Read Word (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadWord(ARMul_State *state, ARMword address)
+{
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ return(GetWord(state,address)) ;
+ }
+
+/***************************************************************************\
+* Read HalfWord (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadHalfWord(ARMul_State *state, ARMword address)
+{ARMword temp;
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAPH(address) ;
+ return((ARMword)GetHalfWord(state,temp)) ;
+ }
+
+/***************************************************************************\
+* Read Byte (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadByte(ARMul_State *state, ARMword address)
+{ARMword temp ;
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return(ARMul_ABORTWORD) ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAP(address) ;
+ return((ARMword)GetByte(state,temp)) ;
+ }
+
+/***************************************************************************\
+* Write Word (but don't tell anyone!) *
+\***************************************************************************/
+
+void ARMul_WriteWord(ARMul_State *state, ARMword address, ARMword data)
+{
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ PutWord(state,address,data) ;
+ }
+
+/***************************************************************************\
+* Write HalfWord (but don't tell anyone!) *
+\***************************************************************************/
+
+void ARMul_WriteHalfWord(ARMul_State *state, ARMword address, ARMword data)
+{ARMword temp;
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAPH(address) ;
+ PutHalfWord(state,temp,data) ;
+ }
+
+/***************************************************************************\
+* Write Byte (but don't tell anyone!) *
+\***************************************************************************/
+
+void ARMul_WriteByte(ARMul_State *state, ARMword address, ARMword data)
+{ARMword temp ;
+
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ ARMul_DATAABORT(address) ;
+ return ;
+ }
+ else {
+ ARMul_CLEARABORT ;
+ }
+#endif
+
+ temp = (HostEndian == state->bigendSig)?address:ENDSWAP(address) ;
+ PutByte(state,temp,(unsigned char)data) ;
+ }
+ \ No newline at end of file