diff options
| author | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
|---|---|---|
| committer | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
| commit | 33613a85afc4b1481367fbe92a17ee59c240250b (patch) | |
| tree | 670b842326116b376b505ec2263878912fca97e2 /Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMPROTO.C | |
| download | Studium-master.tar.gz Studium-master.tar.bz2 | |
Diffstat (limited to 'Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMPROTO.C')
| -rw-r--r-- | Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMPROTO.C | 512 |
1 files changed, 512 insertions, 0 deletions
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMPROTO.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMPROTO.C new file mode 100644 index 0000000..5d7ec12 --- /dev/null +++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/SOURCE/WIN32/ARMUL/ARMPROTO.C @@ -0,0 +1,512 @@ +/***************************************************************************\
+* armproto.c *
+* Version 1.20 *
+* ARMulator II Fast Prototype Memory Interface. *
+* Copyright (C) 1991 Advanced RISC Machines Limited. All rights reserved. *
+* Written by Dave Jaggar. *
+* Project started on 1st July 1991. *
+\***************************************************************************/
+
+/*
+ * RCS $Revision: 1.12 $
+ * Checkin $Date: 1995/01/18 12:27:02 $
+ * Revising $Author: hmeekings $
+ */
+
+/* This file contains the ARMulator interface to the memory model
+designed for fast prototyping. This model is also the closest to the
+real ARM memory interface. Two routines must be written to build a
+memory interface, ARMul_MemoryInit and ARMul_MemoryAccess. An example
+memory interface is implemented, with 64K pages, allocated on demand
+from a 64K entry page table. The routines PutWord and GetWord implement
+this, lifted from armvirt.c, the virtual memory model. Pages are never
+freed as they might be needed again. A single area of memory may be
+defined to generate aborts. */
+
+#include "armdefs.h"
+
+#ifdef VALIDATE /* for running the validate suite */
+#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
+#define ABORTS
+#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 TRACEBUS */
+
+#define NUMPAGES 64 * 1024
+#define PAGESIZE 64 * 1024
+#define PAGEBITS 16
+#define OFFSETBITS 0xffff
+
+static ARMword GetWord(ARMul_State *state,ARMword address) ;
+static void PutWord(ARMul_State *state,ARMword address, ARMword word) ;
+
+/***************************************************************************\
+* Initialise the memory interface *
+\***************************************************************************/
+
+unsigned ARMul_MemoryInit(ARMul_State *state, unsigned long initmemsize)
+{ARMword **pagetable ;
+ unsigned page ;
+
+ state->MemSize = initmemsize ;
+ pagetable = (ARMword **)malloc(sizeof(ARMword)*NUMPAGES) ;
+ if (pagetable == NULL)
+ return(FALSE) ;
+ for (page = 0 ; page < NUMPAGES ; page++)
+ *(pagetable + page) = NULL ;
+ state->MemDataPtr = (unsigned char *)pagetable ;
+#ifdef BIGEND
+ state->bigendSig = HIGH ;
+#endif
+#ifdef LITTLEEND
+ state->bigendSig = LOW ;
+#endif
+ ARMul_ConsolePrint(state, ", 4 Gb memory") ;
+ return(TRUE) ;
+}
+
+/***************************************************************************\
+* Remove the memory interface *
+\***************************************************************************/
+
+void ARMul_MemoryExit(ARMul_State *state)
+{ARMword page ;
+ ARMword **pagetable ;
+ ARMword *pageptr ;
+
+ pagetable = (ARMword **)state->MemDataPtr ;
+ for (page = 0 ; page < NUMPAGES ; page++) {
+ pageptr = *(pagetable + page) ;
+ if (pageptr != NULL)
+ free((char *)pageptr) ;
+ }
+ free((char *)pagetable) ;
+ return ;
+ }
+
+/***************************************************************************\
+* Generic memory interface. Just alter this for a prototype memory system. *
+\***************************************************************************/
+
+ARMword ARMul_MemAccess(ARMul_State *state,
+ ARMword address,
+ ARMword dataOut,
+ ARMword mas1,
+ ARMword mas0,
+ ARMword rw,
+ ARMword seq,
+ ARMword mreq,
+ ARMword opc,
+ ARMword lock,
+ ARMword trans,
+ ARMword account)
+{ARMword dataIn = 0 ;
+
+#ifdef TRACEBUS
+ ARMul_DebugPrint(state, "A=%08x, M=%01x, S=%01x, O=%01x\n",
+ address,mreq,seq,opc) ;
+#endif
+
+ ARMul_CLEARABORT ;
+ if (mreq == LOW) { /* memory request */
+ if (account == TRUE) { /* a "real" memory access */
+ if (seq == LOW) /* non-sequential (N) cycle */
+ state->NumNcycles++ ;
+ else
+ state->NumScycles++ ;
+ }
+#ifdef ABORTS
+ if (address >= LOWABORT && address < HIGHABORT) {
+ if (opc == LOW) { /* opcode fetch */
+ ARMul_PREFETCHABORT(address) ;
+ }
+ else { /* data access */
+ ARMul_DATAABORT(address) ;
+ }
+#ifdef TRACEBUS
+ ARMul_DebugPrint(state, "ABORT\n") ;
+#endif
+ return(ARMul_ABORTWORD) ;
+ } /* abort */
+#endif
+ if (rw == LOW) { /* read */
+ /* it's always a word, bytes and halfwords are extracted by ARM */
+ dataIn = GetWord(state,address) ;
+ } /* read */
+ else { /* write */
+ if (mas0 == LOW) { /* byte or word */
+ if (mas1 == LOW) { /* byte */
+ ARMword word, offset ;
+
+#ifdef VALIDATE
+ if (address == TUBE) {
+ if (dataOut == 4)
+ state->Emulate = FALSE ;
+ else
+ (void)putc((char)dataOut,stderr) ; /* Write Char */
+ return(0) ;
+ }
+#endif
+ word = GetWord(state,address) ;
+ offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3 ; /* bit offset into the word */
+ PutWord(state,address,(word & ~(0xffL << offset)) | ((dataOut & 0xffL) << offset)) ;
+ }
+ else { /* write word */
+ PutWord(state,address,dataOut) ;
+ }
+ } /* byte or word */
+ else { /* halfword or reserved */
+ if (mas1 == LOW) { /* halfword */
+ ARMword word, offset ;
+ word = GetWord(state,address) ;
+ offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3 ; /* bit offset into the word */
+ PutWord(state,address,(word & ~(0xffffL << offset)) | ((dataOut & 0xffffL) << offset)) ;
+ } else { /* reserved */
+ ARMul_ConsolePrint(state, "Reserved memory access\n") ;
+ }
+ } /* halfword or reserved */
+ } /* write */
+ } /* memory request */
+ else { /* not a memory request */
+ if (seq == LOW) /* internal (I) cycle */
+ state->NumIcycles++ ;
+ else /* co-processor (C) cycle */
+ state->NumCcycles++ ;
+ }
+ return(dataIn) ;
+ }
+
+/***************************************************************************\
+* Get a Word from Virtual Memory, maybe allocating the page *
+\***************************************************************************/
+
+static ARMword GetWord(ARMul_State *state, ARMword address)
+{ARMword page, offset ;
+ ARMword **pagetable ;
+ ARMword *pageptr ;
+
+ page = address >> PAGEBITS ;
+ offset = (address & OFFSETBITS) >> 2 ;
+ pagetable = (ARMword **)state->MemDataPtr ;
+ pageptr = *(pagetable + page) ;
+
+ if (pageptr == NULL) {
+ pageptr = (ARMword *)malloc(PAGESIZE) ;
+ if (pageptr == NULL) {
+ perror("ARMulator can't allocate VM page") ;
+ exit(12) ;
+ }
+ *(pagetable + page) = pageptr ;
+ }
+
+ return(*(pageptr + offset)) ;
+ }
+
+/***************************************************************************\
+* Put a Word into Virtual Memory, maybe allocating the page *
+\***************************************************************************/
+
+static void PutWord(ARMul_State *state, ARMword address, ARMword data)
+{ARMword page, offset ;
+ ARMword **pagetable ;
+ ARMword *pageptr ;
+
+ page = address >> PAGEBITS ;
+ offset = (address & OFFSETBITS) >> 2 ;
+ pagetable = (ARMword **)state->MemDataPtr ;
+ pageptr = *(pagetable + page) ;
+
+ if (pageptr == NULL) {
+ pageptr = (ARMword *)malloc(PAGESIZE) ;
+ if (pageptr == NULL) {
+ perror("ARMulator can't allocate VM page") ;
+ exit(13) ;
+ }
+ *(pagetable + page) = pageptr ;
+ }
+
+ *(pageptr + offset) = data ;
+ }
+
+/*-------------------------------------------------------------------------*\
+* *
+| NOTHING BELOW HERE SHOULD NEED CHANGING |
+* *
+\*-------------------------------------------------------------------------*/
+
+
+/***************************************************************************\
+* Load Instruction, Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstrS(ARMul_State *state, ARMword address)
+{ARMword temp ;
+
+#ifdef HOURGLASS_RATE
+ if( ( state->NumScycles & HOURGLASS_RATE ) == 0 ) {
+ armsd_hourglass();
+ }
+#endif
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ temp = ARMul_MemAccess(state,address,0L, 1L,0L,0L, 1L,0L, 0L, 0L,1L, 1L) ;
+ return(temp) ;
+}
+
+/***************************************************************************\
+* Load Instruction, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstrN(ARMul_State *state, ARMword address)
+{ARMword temp ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ temp = ARMul_MemAccess(state,address,0L, 1L,0L,0L, 0L,0L, 0L, 0L,1L, 1L) ;
+ return(temp) ;
+ }
+
+/***************************************************************************\
+* Load 16 bit Instruction, Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstr16S(ARMul_State *state, ARMword address)
+{ARMword temp, offset ;
+
+#ifdef HOURGLASS_RATE
+ if( ( state->NumScycles & HOURGLASS_RATE ) == 0 ) {
+ armsd_hourglass();
+ }
+#endif
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ temp = ARMul_MemAccess(state,address,0L, 0L,1L,0L, 1L,0L, 0L, 0L,1L, 1L) ;
+ offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3 ; /* bit offset into the word */
+ return(temp >> offset & 0xffffL) ;
+}
+
+/***************************************************************************\
+* Load 16 bit Instruction, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstr16N(ARMul_State *state, ARMword address)
+{ARMword temp, offset ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ temp = ARMul_MemAccess(state,address,0L, 0L,1L,0L, 0L,0L, 0L, 0L,1L, 1L) ;
+ offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3 ; /* bit offset into the word */
+ return(temp >> offset & 0xffffL) ;
+ }
+
+/***************************************************************************\
+* Load Word, Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordS(ARMul_State *state, ARMword address)
+{ARMword temp ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ temp = ARMul_MemAccess(state,address,0L, 1L,0L,0L, 1L,0L, 1L, 0L,1L, 1L) ;
+ return(temp) ;
+ }
+
+/***************************************************************************\
+* Load Word, Non Sequential Cycle *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordN(ARMul_State *state, ARMword address)
+{ARMword temp ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ temp = ARMul_MemAccess(state,address,0L, 1L,0L,0L, 0L,0L, 1L, 0L,1L, 1L) ;
+ return(temp) ;
+ }
+
+/***************************************************************************\
+* Load Halfword, (Non Sequential Cycle) *
+\***************************************************************************/
+
+ARMword ARMul_LoadHalfWord(ARMul_State *state, ARMword address)
+{ARMword word, offset ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ word = ARMul_MemAccess(state,address,0L, 0L,1L,0L, 0L,0L, 1L, 0L,1L, 1L) ;
+ offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3 ; /* bit offset into the word */
+ return(word >> offset & 0xffffL) ;
+ }
+
+/***************************************************************************\
+* Load Byte, (Non Sequential Cycle) *
+\***************************************************************************/
+
+ARMword ARMul_LoadByte(ARMul_State *state, ARMword address)
+{ARMword word, offset ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ word = ARMul_MemAccess(state,address,0L, 0L,0L,0L, 0L,0L, 1L, 0L,1L, 1L) ;
+ offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3 ; /* bit offset into the word */
+ return(word >> offset & 0xffL) ;
+ }
+
+/***************************************************************************\
+* Store Word, Sequential Cycle *
+\***************************************************************************/
+
+void ARMul_StoreWordS(ARMul_State *state, ARMword address, ARMword data)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ (void)ARMul_MemAccess(state,address,data, 1L,0L,1L, 1L,0L, 1L, 0L,1L, 1L) ;
+}
+/***************************************************************************\
+* Store Word, Sequential Cycle *
+\***************************************************************************/
+
+void ARMul_StoreWordN(ARMul_State *state, ARMword address, ARMword data)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ (void)ARMul_MemAccess(state,address,data, 1L,0L,1L, 0L,0L, 1L, 0L,1L, 1L) ;
+}
+
+/***************************************************************************\
+* Store Halfword, (Non Sequential Cycle) *
+\***************************************************************************/
+
+void ARMul_StoreHalfWord(ARMul_State *state, ARMword address, ARMword data)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ (void)ARMul_MemAccess(state,address,data, 0L,1L,1L, 0L,0L, 1L, 0L,1L, 1L) ;
+ }
+
+/***************************************************************************\
+* Store Byte, (Non Sequential Cycle) *
+\***************************************************************************/
+
+void ARMul_StoreByte(ARMul_State *state, ARMword address, ARMword data)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ (void)ARMul_MemAccess(state,address,data, 0L,0L,1L, 0L,0L, 1L, 0L,1L, 1L) ;
+ }
+
+/***************************************************************************\
+* Swap Word, (Two Non Sequential Cycles) *
+\***************************************************************************/
+
+ARMword ARMul_SwapWord(ARMul_State *state, ARMword address, ARMword data)
+{ARMword temp ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ temp = ARMul_MemAccess(state,address,0L, 1L,0L,0L, 0L,0L, 1L, 1L,1L, 1L) ;
+ (void)ARMul_MemAccess(state,address,data, 1L,0L,1L, 0L,0L, 1L, 0L,1L, 1L) ;
+ return(temp) ;
+ }
+
+/***************************************************************************\
+* Swap Byte, (Two Non Sequential Cycles) *
+\***************************************************************************/
+
+ARMword ARMul_SwapByte(ARMul_State *state, ARMword address, ARMword data)
+{ARMword word, offset ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ word = ARMul_MemAccess(state,address,0L, 0L,0L,0L, 0L,0L, 1L, 1L,1L, 1L) ;
+ (void)ARMul_MemAccess(state,address,data, 0L,0L,1L, 0L,0L, 1L, 0L,1L, 1L) ;
+ offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3 ; /* bit offset into the word */
+ return(word >> offset & 0xffL) ;
+ }
+
+/***************************************************************************\
+* Count I Cycles *
+\***************************************************************************/
+
+void ARMul_Icycles(ARMul_State *state, unsigned number, ARMword address)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ while (number--)
+ (void)ARMul_MemAccess(state,address,0L, 0L,0L,0L, 0L,1L, 1L, 0L,1L, 1L) ;
+ }
+/***************************************************************************\
+* Count C Cycles *
+\***************************************************************************/
+
+void ARMul_Ccycles(ARMul_State *state, unsigned number, ARMword address)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ while (number--)
+ (void)ARMul_MemAccess(state,address,0L, 0L,0L,0L, 1L,1L, 1L, 0L,1L, 1L) ;
+ }
+
+/***************************************************************************\
+* Read Word (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadWord(ARMul_State *state, ARMword address)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ return(ARMul_MemAccess(state,address,0L, 1L,0L,0L, 0L,0L, 1L, 0L,1L, 0L)) ;
+ }
+
+/***************************************************************************\
+* Read Halfword (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadHalfWord(ARMul_State *state, ARMword address)
+{ARMword word, offset ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ word = ARMul_MemAccess(state,address,0L, 0L,1L,0L, 0L,0L, 1L, 0L,1L, 0L) ;
+ offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3 ; /* bit offset into the word */
+ return(word >> offset & 0xffffL) ;
+ }
+
+/***************************************************************************\
+* Read Byte (but don't tell anyone!) *
+\***************************************************************************/
+
+ARMword ARMul_ReadByte(ARMul_State *state, ARMword address)
+{ARMword word, offset ;
+
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ word = ARMul_MemAccess(state,address,0L, 0L,0L,0L, 0L,0L, 1L, 0L,1L, 0L) ;
+ offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3 ; /* bit offset into the word */
+ return(word >> offset & 0xffL) ;
+ }
+
+/***************************************************************************\
+* Write Word (but don't tell anyone!) *
+\***************************************************************************/
+
+void ARMul_WriteWord(ARMul_State *state, ARMword address, ARMword data)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ (void)ARMul_MemAccess(state,address,data, 1L,0L,1L, 0L,0L, 1L, 0L,1L, 0L) ;
+}
+
+/***************************************************************************\
+* Write HalfWord (but don't tell anyone!) *
+\***************************************************************************/
+
+void ARMul_WriteHalfWord(ARMul_State *state, ARMword address, ARMword data)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ (void)ARMul_MemAccess(state,address,data, 0L,1L,1L, 0L,0L, 1L, 0L,1L, 0L) ;
+ }
+
+/***************************************************************************\
+* Write Byte (but don't tell anyone!) *
+\***************************************************************************/
+
+void ARMul_WriteByte(ARMul_State *state, ARMword address, ARMword data)
+{
+ /* address, data, mas1, mas0, rw, seq, mreq, opc, lock, trans, account */
+ (void)ARMul_MemAccess(state,address,data, 0L,0L,1L, 0L,0L, 1L, 0L,1L, 0L) ;
+ }
+
+
\ No newline at end of file |
