summaryrefslogtreecommitdiffstats
path: root/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES
diff options
context:
space:
mode:
Diffstat (limited to 'Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES')
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.APJbin0 -> 81 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.S14
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.APJbin0 -> 78 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.S21
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.APJbin0 -> 78 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.S17
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.APJbin0 -> 78 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.S40
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.APJbin0 -> 82 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.S15
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.APJbin0 -> 82 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.S26
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.APJbin0 -> 82 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.S14
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.APJbin0 -> 82 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.S29
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.APJbin0 -> 88 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.S20
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.APJbin0 -> 82 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.S20
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_1.C10
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_2.C7
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_3.S22
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/HALF_STR.C10
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/INT64.H9
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.H4
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.S26
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.APJbin0 -> 103 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.C20
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/TWO_CH.C9
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/ERRTEST.C86
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/FPESTUB.S96
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.C23
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.H3
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMTEST.C89
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/README.TXT3
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.H52
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.S723
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.H56
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.S787
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/THUMB/RTSTAND.S819
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/ARMSD.MAP1
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.APJbin0 -> 112 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.H431
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_1.C395
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_2.C192
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/BYTEDEMO.C148
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/DIVC.C213
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDOM.S42
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDTEST.C20
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANTEST.APJbin0 -> 92 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UDIV10.S23
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA.APJbin0 -> 101 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA1.S60
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOATEST.C22
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/GETDATA.C17
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAIN.C55
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAININIT.S9
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAKEFILE27
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVERMGRS.S391
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVLIST2
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/STARTUP.S52
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/TEXT.TXT742
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/UUE.C23
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/PROGC/DSPDIV.C18
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/CONFIG.H74
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/DYNLINK.S72
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/INTERNS.H12
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAIN.S26
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAKEFILE101
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSHL34
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSTUB.APJbin0 -> 156 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.APJbin0 -> 103 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.C18
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C52
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S164
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C31
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/ARMSD.OB3
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/GETDATA.C16
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/INITAPP.S81
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAIN.C33
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAININIT.S12
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAKEFILE29
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/OVERMGRS.S326
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/README.TXT745
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATDES26
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATTER.APJbin0 -> 218 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/STARTUP.S52
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/UUE.C26
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/ARMSD.MAP1
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/SORTS.C135
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/HANDLE.S42
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALL.C105
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALLH.C17
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/NEWLINE.C6
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/READLINE.C9
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWI.APJbin0 -> 91 bytes
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWIMANIP.C9
-rw-r--r--Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/UNUSED/UNUSED.C14
99 files changed, 8224 insertions, 0 deletions
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.APJ
new file mode 100644
index 0000000..ea94b2c
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.S
new file mode 100644
index 0000000..c93e244
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/EXAMPLE.S
@@ -0,0 +1,14 @@
+ AREA Example, CODE, READONLY ; name this block of code
+ ENTRY ; mark first instruction
+ ; to execute
+start
+ MOV r0, #15 ; Set up parameters
+ MOV r1, #20
+ BL firstfunc ; Call subroutine
+ SWI 0x11 ; terminate
+
+firstfunc ; Subroutine firstfunc
+ ADD r0, r0, r1 ; r0 = r0 + r1
+ MOV pc, lr ; Return from subroutine
+ ; with result in r0
+ END ; mark end of file
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.APJ
new file mode 100644
index 0000000..b2853cb
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.S
new file mode 100644
index 0000000..fec499f
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD1.S
@@ -0,0 +1,21 @@
+ AREA gcd1, CODE, READONLY ; name this block of code
+ ENTRY ; mark first instruction
+ ; to execute
+start
+ MOV r0, #1 ; Set up parameters
+ MOV r1, #2
+ BL gcd ; Call subroutine
+ SWI 0x11 ; terminate
+
+gcd
+ CMP r0, r1
+ BEQ end
+ BLT less
+ SUB r0, r0, r1
+ BAL gcd
+less
+ SUB r1, r1, r0
+ BAL gcd
+end MOV pc,lr
+
+ END ; mark end of file \ No newline at end of file
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.APJ
new file mode 100644
index 0000000..30403da
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.S
new file mode 100644
index 0000000..8fbc660
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/GCD2.S
@@ -0,0 +1,17 @@
+ AREA gcd2, CODE, READONLY ; name this block of code
+ ENTRY ; mark first instruction
+ ; to execute
+start
+ MOV r0, #1 ; Set up parameters
+ MOV r1, #2
+ BL gcd ; Call subroutine
+ SWI 0x11 ; terminate
+
+gcd
+ CMP r0, r1
+ SUBGT r0, r0, r1
+ SUBLT r1, r1, r0
+ BNE gcd
+ MOV pc,lr
+
+ END ; mark end of file \ No newline at end of file
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.APJ
new file mode 100644
index 0000000..7728951
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.S
new file mode 100644
index 0000000..fbcb4eb
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/JUMP.S
@@ -0,0 +1,40 @@
+ AREA ArithGate, CODE ; name this block of code
+ ENTRY ; mark the first instruction to call
+main
+ MOV r0, #2 ; set up three parameters
+ MOV r1, #5
+ MOV r2, #15
+ BL arithfunc ; call the function
+ SWI 0x11 ; terminate
+
+arithfunc ; label the function
+ CMP r0, #4 ; Treat code as unsigned integer
+ BHI ReturnA1 ; If code > 4 then return first
+ ; argument
+ ADR r3, JumpTable ; Load address of the jump table
+ LDR pc,[r3,r0,LSL #2] ; Jump to appropriate routine
+
+JumpTable
+ DCD ReturnA1
+ DCD ReturnA2
+ DCD DoAdd
+ DCD DoSub
+ DCD DoRsb
+
+ReturnA1
+ MOV r0, r1 ; Operation 0, >4
+ MOV pc,lr
+ReturnA2
+ MOV r0, r2 ; Operation 1
+ MOV pc,lr
+DoAdd
+ ADD r0, r1, r2 ; Operation 2
+ MOV pc,lr
+DoSub
+ SUB r0, r1, r2 ; Operation 3
+ MOV pc,lr
+DoRsb
+ RSB r0, r1, r2 ; Operation 4
+ MOV pc,lr
+
+ END ; mark the end of this file
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.APJ
new file mode 100644
index 0000000..7641f19
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.S
new file mode 100644
index 0000000..0cfc12a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON1.S
@@ -0,0 +1,15 @@
+ AREA loadcon1, CODE
+ ENTRY ; mark first instruction
+
+ MOV r0, #0 ; => MOV r0, #0
+ MOV r1, #0xFF000000 ; => MOV r1, #0xFF, 8
+ MOV r2, #0xFFFFFFFF ; => MVN r2, #0
+ MVN r0, #1 ; => MVN r0, #1
+ MOV r1, #0xFC000003 ; => MOV r1, #0xFF, 6
+ MOV r2, #0x03FFFFFC ; => MVN r2, #0xFF, 6
+ ;MOV r3, #0x55555555 ; Reports an error (it cannot
+ ; be constructed)
+
+ SWI 0x11 ; terminate
+ END
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.APJ
new file mode 100644
index 0000000..08e91df
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.S
new file mode 100644
index 0000000..53deb76
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON2.S
@@ -0,0 +1,26 @@
+ AREA Loadcon2, CODE
+ ENTRY ; Mark first instruction
+ BL func1 ; Branch to first subroutine
+ BL func2 ; Branch to second subroutine
+ SWI 0x11 ; Terminate
+func1
+ LDR r0, =42 ; => MOV R0, #42
+ LDR r1, =0x55555555 ; => LDR R1, [PC, #offset to Literal
+ ; Pool 1]
+ LDR r2, =0xFFFFFFFF ; => MVN R2, #0
+ MOV pc, lr
+
+ LTORG ; Literal Pool 1 contains
+ ; literal &55555555
+func2
+ LDR r3, =0x55555555 ; => LDR R3, [PC, #offset to Literal
+ ; Pool 1]
+ ; LDR r4, =0x66666666 ; If this is uncommented it will
+ ; fail, as Literal Pool 2 is not
+ ; accessible (out of reach)
+ MOV pc, lr
+
+LargeTable % 4200 ; Clears a 4200 byte area of memory,
+ ; starting at the current location,
+ ; to zero.
+ END ;Literal Pool 2 is empty
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.APJ
new file mode 100644
index 0000000..4b82261
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.S
new file mode 100644
index 0000000..425c1de
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON3.S
@@ -0,0 +1,14 @@
+ AREA Example, CODE
+ ENTRY ; Mark first instruction
+Start
+ ADR r0, Start ; => SUB r0, PC, #offset to Start
+ ADR r1, DataArea ; => ADD r1, PC, #offset to DataArea
+ ; ADR r2, DataArea+4300 ; This would fail as the offset is
+ ; cannot be expressed by operand2
+ ; of an ADD
+ ADRL r3, DataArea+4300 ; => ADD r2, PC, #offset1
+ ; ADD r2, r2, #offset2
+ SWI 0x11 ; Terminate
+DataArea % 8000
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.APJ
new file mode 100644
index 0000000..575662f
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.S
new file mode 100644
index 0000000..5f046c9
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/LOADCON4.S
@@ -0,0 +1,29 @@
+ AREA Loadcon4, CODE
+ ENTRY ; Mark first instruction
+Start
+ BL func1 ; Branch to first subroutine
+ BL func2 ; Branch to second subroutine
+ SWI 0x11 ; Terminate
+
+func1
+ LDR r0, =Start ; => LDR R0,[PC, #offset to
+ ; Litpool 1]
+ LDR r1, =Darea +12 ; => LDR R1,[PC, #offset to
+ ; Litpool 1]
+ LDR r2, =Darea + 6000 ; => LDR R2, [PC, #offset to
+ ; Litpool 1]
+ MOV pc,lr ; Return
+
+ LTORG ; Literal Pool 1 contains 3 literals
+
+func2
+ LDR r3, =Darea +6000 ; => LDR r3, [PC, #offset to
+ ; Litpool 1]
+ ; (sharing with previous literal)
+ ; LDR r4, =Darea +6004 ; If uncommented will produce an
+ ; error as Litpool 2 is out of range
+ MOV pc, lr ; Return
+
+Darea % 8000
+ END ; Literal Pool 2 is out of range of
+ ; the LDR instructions above
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.APJ
new file mode 100644
index 0000000..1e19af0
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.S
new file mode 100644
index 0000000..d719799
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY1.S
@@ -0,0 +1,20 @@
+ AREA StrCopy1, CODE
+ ENTRY ; mark the first instruction
+main
+ ADR r1, srcstr ; pointer to first string
+ ADR r0, dststr ; pointer to second string
+ BL strcopy ; copy the first into second
+ SWI 0x11 ; and exit
+
+srcstr DCB "This is my first (source) string",0
+dststr DCB "This is my second (destination) string",0
+
+ ALIGN ; realign address to word boundary
+
+strcopy
+ LDRB r2, [r1], #1 ; load byte, then update address
+ STRB r2, [r0], #1 ; store byte, then update address
+ CMP r2, #0 ; check for zero terminator
+ BNE strcopy ; keep going if not
+ MOV pc, lr ; return
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.APJ
new file mode 100644
index 0000000..174fca4
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.S
new file mode 100644
index 0000000..aa3e954
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/BASICASM/STRCOPY2.S
@@ -0,0 +1,20 @@
+ AREA StrCopy2, CODE
+ ENTRY ; mark the first instruction
+main
+ LDR r1, =srcstr ; pointer to first string
+ LDR r0, =dststr ; pointer to second string
+ BL strcopy ; copy the first into second
+ SWI 0x11 ; and exit
+
+srcstr DCB "This is my first (source) string",0
+dststr DCB "This is my second (destination) string",0
+
+ ALIGN ; realign address to word boundary
+
+strcopy
+ LDRB r2, [r1], #1 ; load byte, then update address
+ STRB r2, [r0], #1 ; store byte, then update address
+ CMP r2, #0 ; check for zero terminator
+ BNE strcopy ; keep going if not
+ MOV pc, lr ; return
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_1.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_1.C
new file mode 100644
index 0000000..9a7744f
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_1.C
@@ -0,0 +1,10 @@
+#include "int64.h"
+
+void add_64(int64 *dest, int64 *src1, int64 *src2)
+{ unsigned hibit1=src1->lo >> 31, hibit2=src2->lo >> 31, hibit3;
+ dest->lo=src1->lo + src2->lo;
+ hibit3=dest->lo >> 31;
+ dest->hi=src1->hi + src2->hi +
+ ((hibit1 & hibit2) || (hibit1!= hibit3));
+ return;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_2.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_2.C
new file mode 100644
index 0000000..96735fb
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_2.C
@@ -0,0 +1,7 @@
+#include "int64.h"
+
+void add_64(int64 *dest, int64 *src1, int64 *src2)
+{ dest->lo=src1->lo + src2->lo;
+ dest->hi=src1->hi + src2->hi;
+ return;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_3.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_3.S
new file mode 100644
index 0000000..17a0f36
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/ADD64_3.S
@@ -0,0 +1,22 @@
+; generated by Norcroft ARM C vsn 4.41 (Advanced RISC Machines) [Aug 26 1992]
+
+ AREA |C$$code|, CODE, READONLY
+|x$codeseg|
+
+ EXPORT add_64
+add_64
+ LDR a4,[a2,#0]
+ LDR ip,[a3,#0]
+ ADDS a4,a4,ip
+ STR a4,[a1,#0]
+ LDR a2,[a2,#4]
+ LDR a3,[a3,#4]
+ ADC a2,a2,a3
+ STR a2,[a1,#4]
+ MOV pc,lr
+
+ AREA |C$$data|,DATA
+
+|x$dataseg|
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/HALF_STR.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/HALF_STR.C
new file mode 100644
index 0000000..0f00e81
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/HALF_STR.C
@@ -0,0 +1,10 @@
+typedef struct half_words_struct
+{ unsigned field1:16;
+ unsigned field2:16;
+} half_words;
+
+half_words max( half_words a, half_words b )
+{ half_words x;
+ x= (a.field1>b.field1) ? a : b;
+ return x;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/INT64.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/INT64.H
new file mode 100644
index 0000000..0b017f4
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/INT64.H
@@ -0,0 +1,9 @@
+#ifndef __int64_h
+#define __int64_h
+
+typedef struct int64_struct {
+ unsigned int lo;
+ unsigned int hi;
+} int64;
+
+#endif
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.H
new file mode 100644
index 0000000..6d4135e
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.H
@@ -0,0 +1,4 @@
+/* Declaration of mul64, specifying that the int64 */
+#include "int64.h"
+
+__value_in_regs extern int64 mul64(unsigned a, unsigned b);
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.S
new file mode 100644
index 0000000..1b4beb6
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MUL64.S
@@ -0,0 +1,26 @@
+; 32-bit by 32-bit multiplication routine for use with C
+
+ AREA |mul64$$code|, CODE, READONLY
+
+|x$codeseg|
+
+ EXPORT mul64
+
+; On entry a1 and a2 contain the 32-bit integers to be multiplied (a, b)
+; On exit a1 and a2 contain the result (a1 bits 0-31, a2 bits 32-63)
+mul64
+ MOV ip, a1, LSR #16 ; ip = a_hi
+ MOV a4, a2, LSR #16 ; a4 = b_hi
+ BIC a1, a1, ip, LSL #16 ; a1 = a_lo
+ BIC a2, a2, a4, LSL #16 ; a2 = b_lo
+ MUL a3, a1, a2 ; a3 = a_lo * b_lo (m_lo)
+ MUL a2, ip, a2 ; a2 = a_hi * b_lo (m_mid1)
+ MUL a1, a4, a1 ; a1 = a_lo * b_hi (m_mid2)
+ MUL a4, ip, a4 ; a4 = a_hi * b_hi (m_hi)
+ ADDS ip, a2, a1 ; ip = m_mid1 + m_mid2 (m_mid)
+ ADDCS a4, a4, #&10000 ; a4 = m_hi + carry (m_hi')
+ ADDS a1, a3, ip, LSL #16 ; a1 = m_lo + (m_mid<<16)
+ ADC a2, a4, ip, LSR #16 ; a2 = m_hi' + (m_mid>>16) + carry
+ MOV pc, lr
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.APJ
new file mode 100644
index 0000000..ce0107e
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.C
new file mode 100644
index 0000000..5dc30e6
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/MULTEST.C
@@ -0,0 +1,20 @@
+/* Demonstrate mul64 */
+
+#include <stdio.h>
+#include "int64.h"
+#include "mul64.h"
+
+int main()
+{ int64 res;
+ unsigned a,b;
+
+ printf( "Enter two unsigned 32-bit numbers in hex eg.(100 FF43D)\n" );
+ if( scanf( "%x %x", &a, &b ) != 2 )
+ { puts( "Bad numbers" );
+ } else
+ { res=mul64(a,b);
+ printf( "Least significant word of result is %8X\n", res.lo );
+ printf( "Most significant word of result is %8X\n", res.hi );
+ }
+ return( 0 );
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/TWO_CH.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/TWO_CH.C
new file mode 100644
index 0000000..9f4c72f
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CANDASM/TWO_CH.C
@@ -0,0 +1,9 @@
+typedef struct two_ch_struct
+{ char ch1;
+ char ch2;
+} two_ch;
+
+two_ch max( two_ch a, two_ch b )
+{
+ return (a.ch1>b.ch1) ? a : b;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/ERRTEST.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/ERRTEST.C
new file mode 100644
index 0000000..1315b8f
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/ERRTEST.C
@@ -0,0 +1,86 @@
+/*
+ * Standalone Hello World program - tests for presence of the FP
+ * support code and also shows how to interface to the
+ * standalone C kernel's error handler.
+ *
+ * Copyright (C) 1993 Advanced RISC Machines Limited.
+ */
+
+#include "rtstand.h"
+
+extern void __swi(0) put_char(int ch);
+extern void __swi(2) put_string(char *string);
+
+/* First let's roll our own, primitive hex number printer.
+ * Strictly %#.8X format.
+ */
+static void puth(unsigned n) {
+ int j;
+ put_string("0X");
+ for (j = 0; j < 8; ++j) {
+ put_char("0123456789ABCDEF"[n >> 28]);
+ n <<= 4;
+ }
+}
+
+static jmp_buf err_label;
+
+/* This is the function weakly-referenced from the standalone C kernel.
+ * If it exists, it will be called when a run-time error occurs.
+ * If the error is a 'pseudo-error', raised because the error-handler
+ * has been called directly, then the user's register set *r will contain
+ * random values for a1-a4 and ip (r[0-3], r[12]) and r[15] will be
+ * identical to r[14].
+ */
+void __err_handler(__rt_error *e, __rt_registers *r) {
+ put_string("errhandler called: code = ");
+ puth(e->errnum);
+ put_string(": "); put_string(e->errmess); put_string("\r\n");
+ put_string("caller's pc = "); puth(r->r[15]);
+ put_string("\r\nreturning...\r\n");
+#ifdef LONGJMP
+ longjmp(err_label, e->errnum);
+#endif
+}
+
+#ifdef DIVIDE_ERROR
+#define LIMIT 0
+#else
+#define LIMIT 1
+#endif
+
+int main(int argc, char *argv[]) {
+ int rc;
+
+ put_string("(the floating point instruction-set is ");
+ if (!__rt_fpavailable()) put_string("not ");
+ put_string("available)\r\n");
+
+/* Set up the jmp_buffer, and if returning due to longjmp then
+ * goto errlabel
+ */
+ if ((rc = setjmp(err_label)) != 0) goto errlabel;
+
+ if (__rt_fpavailable()) {
+ float a;
+ put_string("Using Floating point, but casting to int ...\r\n");
+ for (a=(float) 10.0;a>=(float) LIMIT;a-=(float) 1.0) {
+ put_string("10000 / "); puth((int) a); put_string(" = ");
+ puth((int) (10000.0/a)); put_string("\r\n");
+ }
+ } else {
+ int a;
+ put_string("Using integer arithmetic ...\r\n");
+ for (a=10;a>=LIMIT;a--) {
+ put_string("10000 / "); puth(a); put_string(" = ");
+ puth(10000/a); put_string("\r\n");
+ }
+ }
+ return 0;
+
+errlabel:
+ put_string("\nReturning from __err_handler() with errnum = ");
+ puth(rc);
+ put_string("\r\n\n");
+ return 0;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/FPESTUB.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/FPESTUB.S
new file mode 100644
index 0000000..f015a18
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/FPESTUB.S
@@ -0,0 +1,96 @@
+;;; fpestub.s: library stub for fpe400 (emulator for fp instruction set 3)
+;;;
+;;; Copyright (C) Advanced RISC Machines Ltd., 1993
+
+;;; RCS $Revision: 1.5 $
+;;; Checkin $Date: 1994/01/24 14:19:42 $
+;;; Revising $Author: irickard $
+
+ AREA |FP$$code|, CODE
+
+ IMPORT __rt_trap, WEAK ; from run-time kernel...
+
+; change FPE_ to FPS_ to allow FPA support code to be incorporated in library
+; (there is currently no veneer support for the combined FPE/FPASC)
+ IMPORT FPE_Install
+ IMPORT FPE_DeInstall
+ EXPORT FPE_GenerateError ; to FPE
+
+ EXPORT __fp_initialise ; to client
+ EXPORT __fp_finalise ; to client
+ EXPORT __fp_address_in_emulator ; to client
+
+ IMPORT |FP$$code$$Base|
+ IMPORT |FP$$code$$Limit|
+
+
+; RISCOS SWI names (for use in very_standalone only).
+
+Write0 * 2 + (1:SHL:17)
+NewLine * 3 + (1:SHL:17)
+Exit * &11
+
+;******************************************************************************
+;
+
+
+__fp_initialise
+ B FPE_Install
+
+__fp_finalise
+ B FPE_DeInstall
+
+;******************************************************************************
+;
+; Come here for a floating point exception, such as divide by zero.
+;
+; r0 = error descriptor
+; r1 -> cpu register dump
+;
+
+FPE_GenerateError
+; still in some non-user mode...
+ LDR r2, =|__rt_trap|
+ CMP r2, #0
+ BEQ very_standalone
+ ADD r3, r1, #r13*4
+ LDMIA r3, {r13}^ ; retrieve user's sp
+ NOP
+ MOVS pc, r2 ; to __rt_ in user mode
+
+
+very_standalone
+ [ {CONFIG} = 26
+ TEQP pc, #0 ; to user mode
+ |
+ MSR CPSR_ctl, #&10 ; to user32
+ ]
+ ADD r0, r0, #4 ; ignore the error code
+ SWI Write0 ; write the message
+ SWI NewLine
+ BL |__fp_finalise| ; tidy the ill-instr vector
+ SWI Exit ; and exit
+
+|__fp_address_in_emulator|
+ ; for the benefit of abort handling, determine whether an address
+ ; is within the code of the fp emulator. (Allowing a data abort or
+ ; address exception in a floating-point load or store to be reported
+ ; as occurring at that instruction, rather than somewhere in the code
+ ; of the emulator).
+ [ {CONFIG} = 26
+ BIC r0, r0, #&fc000003 ; remove PSR bits in case
+ ]
+ LDR r1, =|FP$$code$$Base|
+ CMP r0, r1
+ LDRGT r1, =|FP$$code$$Limit|
+ CMPGT r1, r0
+ MOVLE r0, #0
+ MOVGT r0, #1
+ [ {CONFIG} = 26
+ MOVS pc, lr
+ |
+ MOV pc, lr
+ ]
+ LTORG
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.C
new file mode 100644
index 0000000..8039f11
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.C
@@ -0,0 +1,23 @@
+#include "memmove.h"
+
+void *__rt_memmove(void *a, const void *b, size_t n)
+/* copy memory taking care of overlap */
+/* Relies on sizeof(int)=sizeof(void *) and byte addressing.
+ Also that memory does not wrap round for direction test. */
+{
+ /* do it fast if word aligned ... */
+ if ((((int)a | (int)b | (int)n) & 3) == 0)
+ { int *wa,*wb;
+ n >>= 2;
+ if (a < (void *)b)
+ for (wa = (int *)a, wb = (int *)b; n-- > 0;) *wa++ = *wb++;
+ else for (wa = n+(int *)a, wb = n+(int *)b; n-- > 0;) *--wa = *--wb;
+ }
+ else
+ { char *ca,*cb;
+ if (a < (void *)b)
+ for (ca = (char *)a, cb = (char *)b; n-- > 0;) *ca++ = *cb++;
+ else for (ca = n+(char *)a, cb = n+(char *)b; n-- > 0;) *--ca = *--cb;
+ }
+ return a;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.H
new file mode 100644
index 0000000..480df1b
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMMOVE.H
@@ -0,0 +1,3 @@
+typedef unsigned int size_t; /* others (e.g. <stdio.h>) define */
+
+extern void *__rt_memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/);
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMTEST.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMTEST.C
new file mode 100644
index 0000000..46e8f1a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/MEMTEST.C
@@ -0,0 +1,89 @@
+/*
+ * Standalone run-time system test.
+ *
+ * This program checks that stack overflow checking works and that it
+ * interacts properly with heap extension.
+ *
+ * Copyright (C) 1991 Advanced RISC Machines Limited.
+ */
+
+#include "rtstand.h"
+
+extern void __swi(0) put_char(int ch);
+extern void __swi(2) put_string(char *string);
+
+/* First, we make a function to claim a large(-ish) stack frame.
+ * Some obfuscation in case the compiler optimises us away...
+ */
+static int stack(int n, int v) {
+ /* claim n KB of stack */
+ int x[256],i;
+
+ if (n > 1) v = stack(n-1, v);
+ for (i = 0; i < 256; ++i) x[i] = v + i;
+ return x[0] + x[255];
+}
+
+/* Now we roll our own decimal output function - strictly %d format...
+ */
+static void puti(int n) {
+ if (n < 0) {
+ put_char('-');
+ n = -n;
+ }
+ if (n > 9) {
+ int n1 = n / 10;
+ n = n % 10;
+ puti(n1);
+ }
+ put_char(n + '0');
+}
+
+/* ...and a hex outputter... strictly %#.8X format.
+ */
+static void puth(unsigned n) {
+ int j;
+ put_string("0X");
+ for (j = 0; j < 8; ++j) {
+ put_char("0123456789ABCDEF"[n >> 28]);
+ n <<= 4;
+ }
+}
+
+/* Finally, we sit in a loop extending the heap and claiming ever bigger
+ * stack franes until something gives. Probably, the heap will give first,
+ * as currently tuned, and the program will announce "memory exhausted".
+ * If you tune it differently, it can be made to fail will a stack overflow
+ * run-time error. Try compiling this -DSTACK_OVERFLOW to provoke it.
+ */
+int main(int argc, char *argv[]) {
+ unsigned size, ask, got, total;
+ void *base;
+
+ put_string("kernel memory management test\r\n");
+
+ size = 4; /* KB */
+ ask = 0;
+ for (total = 0;;) {
+ put_string("force stack to "); puti(size); put_string("KB\r\n");
+ stack(size, 0);
+ put_string("request "); puti(ask); put_string(" words of heap - ");
+ got = __rt_alloc(ask, &base);
+ total += got;
+ put_string("allocate "); puti(got);
+ put_string(" words at "); puth((unsigned)base); put_string("\r\n");
+ if (got < ask) break;
+ ask += got / 2;
+#ifdef STACK_OVERFLOW
+ size *= 2;
+#else
+ size += 4;
+#endif
+ }
+
+ put_string("memory exhausted, ");
+ puti(total); put_string(" words of heap, ");
+ puti(size); put_string("KB of stack\r\n");
+
+ return 0;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/README.TXT b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/README.TXT
new file mode 100644
index 0000000..bc81770
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/README.TXT
@@ -0,0 +1,3 @@
+For details of how to use the files in this directory refer to the ARM
+Programming Techniques, and in particular to the section on
+Deeply Embedded Programming in C.
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.H
new file mode 100644
index 0000000..1b956ea
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.H
@@ -0,0 +1,52 @@
+/*
+ * Standalone C run-time kernel.
+ * Copyright (C) 1991 Advanced RISC Machines Limited.
+ */
+
+#ifndef __rtstand_h
+#define __rtstand_h
+
+
+extern void __rt_exit(int /* code */); /*
+ * Terminate execution; equivalent to returning from main.
+ * NOTE: all other details are determined by your implementation.
+ */
+
+typedef struct {unsigned errnum; char errmess[252];} __rt_error;
+typedef struct {int r[16];} __rt_registers;
+
+extern void __err_handler(__rt_error *, __rt_registers *);
+
+extern int __rt_fpavailable(void);
+/*
+ * Return non-0 iff there is support for the floating-point instruction set.
+ */
+
+extern unsigned __rt_alloc(unsigned /*minwords*/, void ** /*block*/);
+/*
+ * Tries to allocate a block of sensible size >= minwords. Failing that,
+ * it allocates the largest possible block (may have size zero).
+ * Sensible size is determined by your implementation (default: 256 words).
+ * *block is set to a pointer to the start of the allocated block
+ * (NULL if 'a block of size zero' has been allocated).
+ */
+
+#ifdef __JMP_BUF_SIZE
+typedef int jmp_buf[__JMP_BUF_SIZE];
+#else
+typedef int jmp_buf[22]; /* size suitable for the ARM */
+#endif /* an array type suitable for holding the data */
+ /* needed to restore a calling environment. */
+#ifdef __STDC__
+/* setjmp is a macro so that it cannot be used other than directly called. */
+/* NB that ANSI declare that anyone who undefined the setjmp macro or uses */
+/* (or defines) the name setjmp without including this header will get */
+/* what they deserve. NOTE: -pcc mode doesn't allow circular definitions...*/
+#define setjmp(jmp_buf) (setjmp(jmp_buf))
+#endif
+
+extern int setjmp(jmp_buf /*env*/);
+
+extern int longjmp(jmp_buf /*env*/, int /*val*/);
+
+#endif
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.S
new file mode 100644
index 0000000..325b494
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND.S
@@ -0,0 +1,723 @@
+; Issue: 0.03/23-Feb-93
+;
+; Purpose: Minimal, standalone, C-library kernel.
+;
+; Copyright (C) 1993 Advanced RISC Machines Limited. All rights reserved.
+;
+; Advanced RISC Machines Limited does not assume any liability arising out
+; of this program or use thereof neither does it convey any licence under
+; its intellectual property rights.
+;
+; Conditions of use:
+;
+; The terms and conditions under which this software is supplied to you and
+; under which you may use it are described in your licence agreement with
+; your supplier.
+;
+;----------------------------------------------------------------------------;
+; ABOUT THIS CODE ;
+; ;
+; This code shows you how to write your own minimal, standalone, run-time ;
+; support system for code compiled by Advanced RISC Machines's C Compiler. ;
+; It can be assembled using Advanced RISC Machines's ARM assembler (armasm) ;
+; or any assembler comaptible with it. ;
+; ;
+; This example code has been written to run under Advanced RISC Machines's ;
+; ARM emulation system (ARMulator). It can also run without modification ;
+; under Acorm Computer's "RISC OS" operating system for its ARM-based ;
+; personal workstations. ;
+; ;
+; In fact, this code depends hardly at all on its target environment and is ;
+; designed to be very easy to adapt to your particular ARM-based system. ;
+; You can expect it to take about a couple of hours to re-target. ;
+; ;
+; Much of the code below is generic to the ARM processor and is completely ;
+; independent of your ARM-based hardware or any operating system kernel that ;
+; may run on it. To get going, you need write only 4 simple fns. ;
+; ;
+; WHAT THIS CODE PROVIDES: ;
+; ;
+; - Example, executable implementations (for the ARMulator) of the few ;
+; simple functions you need to implement to customise this code to your ;
+; environment. These include: ;
+; - setting up the initial stack and heap and calling main (__main) ;
+; - program termination (__rt_exit) ;
+; - determining FP instruction-set availability (__rt_fpavailable) ;
+; ;
+; - Functions to help with heap allocation, stack-limit checking, setjmp ;
+; and longjmp. These may need to be customised for your environment, ;
+; but can almost certainly be used as-is in a first re-targetting. ;
+; ;
+; - Fully 'rolled' divide (and remainder) functions. ;
+; ;
+; WHAT THIS CODE DOES NOT PROVIDE ;
+; ;
+; - Support for handling traps, faults, escapes, exceptions or interrupts. ;
+; ;
+; - A way to print to the debugging channel (use in line SWIs) ;
+; ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; The following constant is the Top Of Memory - Adjust this for your system ;
+;----------------------------------------------------------------------------;
+
+TopOfMemory EQU 0x80000 ; 512Kb
+
+;----------------------------------------------------------------------------;
+; Things you may wish to tune, but which you don't need to alter, follow. ;
+;----------------------------------------------------------------------------;
+
+DefaultStackSize EQU 4*1024 ; The stack starts of this big unless
+ ; over-ridden by __root_stack_size.
+
+DefaultStackIncrement EQU 1*1024 ; At each overflow it grows by at
+ ; at least this many bytes.
+
+StackSlop EQU 512 ; sl is kept this far above the real
+ ; stack low-water mark. NOTE: MUST be
+ ; >= 256 or the compiled limit checks
+ ; will be invalidated.
+
+MinHeapIncrement EQU 256 ; Min number of WORDS to extend the
+ ; heap by on calling __rt_alloc.
+
+ GBLL EnsureNoFPSupport
+EnsureNoFPSupport SETL {FALSE} ; If {TRUE} then the availability of
+ ; Floating Point Support is ignored.
+ ; If {FALSE} then FP availability is
+ ; checked for.
+ ; Setting to {TRUE} saves a little
+ ; space.
+
+;----------------------------------------------------------------------------;
+; Symbols defined in other, separately-assembled modules, must be IMPORTed. ;
+; We import them WEAKly so that they need not be defined. ;
+;----------------------------------------------------------------------------;
+
+ IF EnsureNoFPSupport = {FALSE}
+ IMPORT |__fp_initialise|, WEAK
+ IMPORT |__fp_finalise|, WEAK
+ ENDIF
+
+;----------------------------------------------------------------------------;
+; The existence of __fp_initialise (imported WEAKly) indicates that floating ;
+; point support code (or the access stub thereof) has been linked with this ;
+; application. If you wish to load the FP support code separately, you may ;
+; want to define some other mechanism for detecting the presence/absence of ;
+; floating point support. Note that setjmp and longjmp must know whether the ;
+; floating-point instruction set is supported. ;
+; __fp_initialise is called by __main and __fp_finalise is called by _exit. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT |__root_stack_size|, WEAK
+
+;----------------------------------------------------------------------------;
+; If __root_stack_size, also imported WEAKly, exists, the value it addresses ;
+; is used as the initial size of the stack. It can be defined in your C ;
+; program as, e.g. int __root_stack_size = 10000; /* 10KB initial stack */ ;
+;----------------------------------------------------------------------------;
+
+ IMPORT |__err_handler|, WEAK
+
+;----------------------------------------------------------------------------;
+; If __err_handler exists, errors are passed to it; otherwise, we print a ;
+; simple diagnostic message and exit. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT |Image$$RW$$Limit|
+
+;----------------------------------------------------------------------------;
+; Image$$RW$$Limit is a linker-created symbol marking the end of the image. ;
+; Its value is used as the heap base. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT main
+
+;----------------------------------------------------------------------------;
+; The symbol main identifies the C function entered from this code. ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; THE MEMORY MODEL ASSUMED BY THIS IMPLEMENTATION ;
+; ;
+; +----------------+ <--- top of memory (high address) ;
+; | Stack space | ;
+; |................| <--- stack pointer (sp) ;
+; | Free stack | ;
+; |................| <--- stack limit pointer (sl) ;
+; +----------------+ <--- stack low-water mark (sl - StackSlop) ;
+; | | ;
+; | Unused memory | ;
+; | | ;
+; +----------------+ <--- top of heap (HeapLimit) ;
+; | | ;
+; | Heap space | ;
+; | | ;
+; +----------------+ <--- top of application (Image$$RW$$Limit) ;
+; | Static data | } ;
+; |................| } the application's memory image ;
+; | Code | } ;
+; +----------------+ <--- application load address ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; Now the symbols we define and EXPORT from this this module. ;
+;----------------------------------------------------------------------------;
+; First, symbols identifying the four functions you have to implement to ;
+; make this run-time kernel work on your hardware. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__main|
+ EXPORT |__rt_exit|
+ EXPORT |__rt_fpavailable|
+ EXPORT |__rt_trap|
+
+;----------------------------------------------------------------------------;
+; Then some simple support for C heap management. It interacts with stack- ;
+; limit checking but should require no attention in a first re-targetting. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__rt_alloc|
+
+;----------------------------------------------------------------------------;
+; Next, optional support for C stack-limit checking. This code should need ;
+; no attention in a first re-targetting. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__rt_stkovf_split_small| ; veneer
+ EXPORT |__rt_stkovf_split_big|
+
+;----------------------------------------------------------------------------;
+; Then two C-specific functions which should require no attention in a first ;
+; re-targetting. Note that they depend on __rt_fpavailable. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |setjmp|
+ EXPORT |longjmp|
+
+;----------------------------------------------------------------------------;
+; And, finally, generic ARM functions, referred to by the C compiler. ;
+; You should not need to alter any of these unless you wish to incorporate ;
+; them in your operating system kernel. See also later comments. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__rt_udiv|
+ EXPORT |__rt_udiv10|
+ EXPORT |__rt_sdiv|
+ EXPORT |__rt_sdiv10|
+ EXPORT |__rt_divtest|
+
+;----------------------------------------------------------------------------;
+ AREA |C$$data| ; This module's data area ;
+;----------------------------------------------------------------------------;
+
+HeapLimit
+ DCD |Image$$RW$$Limit| ; initialised by the linker.
+
+;----------------------------------------------------------------------------;
+; This code has to run in but 26-bit ARM modes and 32-bit modes. To allow ;
+; for this, the code is carefully written so that all PSR restoration in ;
+; 26-bit mode is via the following macro. ;
+;----------------------------------------------------------------------------;
+
+ MACRO
+ RET $cond
+ IF {CONFIG} = 26
+ MOV$cond.S pc, lr
+ ELSE
+ MOV$cond pc, lr
+ ENDIF
+ MEND
+
+;----------------------------------------------------------------------------;
+; The following four SWI definitions are specific to ARMulator/RISC OS. ;
+; However, you will need to replace the whole of this following section... ;
+; and all uses of these SWIs should also be replaced. ;
+;----------------------------------------------------------------------------;
+
+WriteC EQU 0 ; Write r0 to error/debug stream.
+Write0 EQU 2 ; Write 0-terminated string pointed
+ ; to by r0 to error/debug stream.
+Exit EQU 17 ; Terminate program execution.
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__main|, CODE, READONLY
+; The code area containing __main, __rt_exit ;
+;----------------------------------------------------------------------------;
+
+ ENTRY ; Define the image entry point.
+
+|__main|
+;
+; This is the initial entry point to the image.
+; Have to establish a stack for C
+; No arguments are passed to main from an embedded application,
+; so argc and argv are set up to 0
+
+ MOV sp, #TopOfMemory ; Initial stack pointer...
+ MOV fp, #0 ; No previous frame, so fp=0
+
+ LDR a3, RootStackSize
+ CMP a3, #0 ; Is RootStackSize defined?
+ LDRNE a3, [a3] ; Yes: use value...
+ CMPNE a3, #DefaultStackSize ; but check caller not being silly.
+ MOVLE a3, #DefaultStackSize ; No/silly: use default size.
+
+ SUB sl, sp, a3 ; stack low-water mark
+ ADD sl, sl, #StackSlop ; sl = LWM + StackSlop
+
+ IF EnsureNoFPSupport = {FALSE}
+ LDR a1, fp_initialise ; initialise FP code if present
+ CMP a1, #0
+ MOVNE lr, pc
+ MOVNE pc, a1
+ ENDIF
+
+ MOV a1, #0 ; set argc to 0
+ MOV a2, #0 ; and argv to NUL
+ BL main ; Call main, falling through to
+ ; exit on return.
+
+|__rt_exit| ; exit
+;
+; void __rt_exit(int code);
+; Terminate execution, optionally setting return code (ignored here).
+; MUST NOT RETURN.
+
+ IF EnsureNoFPSupport = {FALSE}
+ LDR a2, fp_finalise ; finalise FP code if present
+ CMP a2, #0
+ MOVNE lr, pc
+ MOVNE pc, a2
+ ENDIF
+ SWI Exit ; suicide...
+
+RootStackSize
+ DCD |__root_stack_size|
+
+ IF EnsureNoFPSupport = {FALSE}
+fp_initialise
+ DCD |__fp_initialise|
+fp_finalise
+ DCD |__fp_finalise|
+ ENDIF
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_fpavailable|, CODE, READONLY
+; The code area containing __rt_fpavailable ;
+;----------------------------------------------------------------------------;
+
+|__rt_fpavailable|
+;
+; int __rt_fpavailable(); return non-0 if FP support code linked.
+
+ IF EnsureNoFPSupport = {FALSE}
+ LDR a1, fp_initialise
+ ELSE
+ MOV a1, #0
+ ENDIF
+ RET
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_trap|, CODE, READONLY
+; The code area containing __rt_trap ;
+;----------------------------------------------------------------------------;
+; Support for low-level failures - currently stack overflow, divide by 0 and ;
+; floating-point exceptions. If there is a higher level handler, call it; ;
+; otherwise, print a message and exit gracefully. ;
+; ;
+; NOTES ;
+; ;
+; typedef struct { unsigned code; char message[252];} __rt_error; ;
+; typedef struct { unsigned r[16];} __rt_registers; ;
+; ;
+;----------------------------------------------------------------------------;
+
+|__rt_trap|
+;
+; void __rt_trap(__rt_error *e, __rt_registers *r);
+
+ STMFD sp!, {a1} ; save e in case handler returns...
+ LDR ip, err_handler
+ CMP ip, #0
+ MOVNE lr, pc
+ IF {CONFIG} = 26
+ MOVNES pc, ip ; if got a handler, use it and
+ ELSE
+ MOVNE pc, ip ; if got a handler, use it and
+ ENDIF
+ LDMFD sp!, {v1} ; hope not to return...
+
+ ADR a1, RTErrorHead
+ SWI Write0 ; write preamble...
+ ADD a1, v1, #4
+ SWI Write0 ; write error diagnosis
+ ADR a1, RTErrorTail
+ SWI Write0 ; write postlude
+ MOV a1, #255
+ B |__rt_exit| ; and terminate with non-zero exit code
+err_handler
+ DCD |__err_handler|
+
+save_regs_and_trap
+ STMFD sp!, {sp, lr, pc}
+ STMFD sp!, {r0-r12}
+ STR lr, [sp, #4*15] ; caller's pc is my lr
+ MOV a2, sp
+ MOV a1, ip
+ B |__rt_trap|
+
+RTErrorHead
+ DCB 10, 13, "run time error: ", 0
+
+RTErrorTail
+ DCB 10, 13, "program terminated", 10, 13, 10, 13, 0
+
+ ALIGN
+
+;----------------------------------------------------------------------------;
+; YOU SHOULDN'T NEED TO ALTER ANY OF THE FOLLOWING IN A FIRST RETARGETTING. ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_alloc|, CODE, READONLY
+; The code area containing __rt_alloc ;
+;----------------------------------------------------------------------------;
+; Primitive support for heap memory management. ;
+; ;
+; NOTES ;
+; ;
+; 1/ The allocator embeds knowledge of the memory layout and interacts with ;
+; the stack limit checking code. Here we assume a single address space ;
+; with the stack at the top growing down and the heap below it growing ;
+; up, with a gap (free memory) in between. ;
+; ;
+; 2/ Failure of the stack-limit check is fatal. However, failure of the low- ;
+; level heap allocator is passed back to its caller. ;
+;----------------------------------------------------------------------------;
+
+
+|__rt_alloc| ; alloc
+;
+; unsigned __rt_alloc(unsigned minwords, void **block);
+;
+; This tries to allocate a block of sensible size >= minwords. Failing that,
+; it allocates the largest possible block of sensible size. If it can't do
+; that, it returns zero. *block is set to point to the start of the allocated
+; block (NULL if none has been allocated).
+;
+; NOTE: works in units of WORDS, NOT bytes.
+;
+; In this implementation, sl - StackSlop marks the end of allocatable store.
+
+ CMP a1, #MinHeapIncrement ; round up to at least
+ MOVLT a1, #MinHeapIncrement ; MinHeapIncrement words...
+ LDR a3, HeapLimitAdr
+ LDR a4, [a3] ; current heap high-water mark
+ SUB ip, sl, #StackSlop ; current stack low-water mark
+ CMP a4, ip
+ MOVGE a4, #0 ; no space, *block = NULL
+ STR a4, [a2]
+ MOVGE a1, #0 ; no space, return 0
+ ADD a4, a4, a1, LSL #2 ; proposed new heap limit
+ CMP a4, ip
+ SUBGT a2, a4, ip ; byte overlap, >= 0 by earlier code
+ SUBGT a1, a1, a2, LSR #2 ; reduce word request
+ MOVGT a4, ip ; new high-water = stack low-water
+ STR a4, [a3]
+ RET
+HeapLimitAdr
+ DCD HeapLimit
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_stkovf|, CODE, READONLY
+; The code area containing __rt_stkovf_* ;
+;----------------------------------------------------------------------------;
+; C stack-limit checking support. ;
+; ;
+; NOTES ;
+; ;
+; 1/ Stack-limit-checking is optional - you can compile your C code without ;
+; stack-limit checks (#pragma nocheck_stack or cc -zps0). However, the ;
+; cost of the check is (very) small and the value sometimes considerable. ;
+; ;
+; 2/ The limit check embeds knowledge of the memory layout and interacts ;
+; with the primitive memory management supported by __rt_alloc. Here, we ;
+; assume a single address space with the stack at the top growing down ;
+; and the heap below it growing up, with a gap (free memory) in between. ;
+; ;
+; 3/ Failure of the stack-limit check is fatal. However, failure of the low- ;
+; level heap allocator is passed back to its caller. ;
+; ;
+; 4/ This implementation never reduces the size of the stack. It simply ;
+; moves the low-water mark monatonically downwards. It is easy to do ;
+; better, but, of course, it takes more code and is more target-specific. ;
+;----------------------------------------------------------------------------;
+
+|__rt_stkovf_split_small| ; stkovf_split_small_frame ;
+;
+; Enter here when a C function with frame size <= 256 bytes underflows
+; the stack low-water mark + StackSlop (sl). The stack space required has
+; already been claimed by decrementing sp, so we set the proposed sp (ip)
+; to the actual sp and fall into the big-frame case.
+
+ MOV ip, sp ; fall into big-frame case with size of 0.
+
+|__rt_stkovf_split_big| ; stkovf_split_big_frame ;
+;
+; Enter here when a C function with frame size > 256 bytes would underflow
+; the stack low-water mark + StackSlop (sl). No stack space has been claimed
+; but the proposed new stack pointer is in ip.
+
+ SUB ip, sp, ip ; frame size required...
+ CMP ip, #DefaultStackIncrement ; rounded up to at least
+ MOVLT ip, #DefaultStackIncrement ; the default increment
+
+ SUB sl, sl, ip
+ SUB sl, sl, #StackSlop ; new stack low-water mark
+
+ LDR ip, HeapLimitAdr ; check doesn't collide with
+ LDR ip, [ip] ; the heap.
+ CMP ip, sl
+ ADD sl, sl, #StackSlop ; restore safety margin
+ BGT stackoverflow
+ RET ; and return if OK...
+
+stackoverflow
+ ADR ip, StackOverflowError
+ B save_regs_and_trap
+
+StackOverflowError
+ DCD 3
+ DCB "stack overflow", 0
+ ALIGN
+
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__jmp|, CODE, READONLY
+; The code area containing setjmp, longjmp ;
+;----------------------------------------------------------------------------;
+; Setjmp and longjmp support. ;
+; ;
+; NOTES ;
+; ;
+; 1/ Specific to C and not implementable in C. ;
+; ;
+; 2/ Interacts with stack management and possibly with memory management. ;
+; e.g. on a chunked stack, longjmp must de-allocate jumped-over chunks. ;
+; ;
+; 3/ Must know whether the floating-point instruction-set is supported! ;
+; (DEPENDS ON __rt_fpavailable to discover this). ;
+; ;
+;----------------------------------------------------------------------------;
+
+ MAP 0 ; This structure maps the jmp_buf
+sj_v1 # 4 ; data type assumed by the C compiler.
+sj_v2 # 4 ; First, space to save the v-registers...
+sj_v3 # 4
+sj_v4 # 4
+sj_v5 # 4
+sj_v6 # 4
+sj_sl # 4 ; then the frame registers sl, fp, sp (ap),
+sj_fp # 4 ; and pc/lr...
+sj_ap # 4
+sj_pc # 4
+sj_f4 # 3*4 ; and finally the floating-point reisters,
+sj_f5 # 3*4 ; used only if floating point support is
+sj_f6 # 3*4 ; available.
+sj_f7 # 3*4
+
+
+|setjmp| ; setjmp
+;
+; int setjmp(jmp_buf env);
+; Saves everything that might count as a register variable in 'env'.
+
+ STMIA a1!, {v1-v6, sl, fp, sp, lr}
+ MOV v6, a1 ; v6 safe in env - use to point past
+ ; saved lr (at 1st FP slot)
+ BL |__rt_fpavailable|
+ CMP a1, #0
+ BEQ setjmp_return ; no fp
+ STFE f4, [v6, #sj_f4-sj_f4]
+ STFE f5, [v6, #sj_f5-sj_f4]
+ STFE f6, [v6, #sj_f6-sj_f4]
+ STFE f7, [v6, #sj_f7-sj_f4]
+ MOV a1, #0 ; must return 0 from a direct call
+setjmp_return
+ LDMDB v6, {v6, sl, fp, sp, lr}
+ RET
+
+|longjmp| ; longjmp ;
+; int longjmp(jmp_buf env, int val);
+
+ MOV v1, a1 ; save env ptr over call to fpavailable
+ MOVS v6, a2 ; ensure non-0 return value...
+ MOVEQ v6, #1 ; (must NOT return 0 on longjmp(env, 0))
+ BL |__rt_fpavailable|
+ CMP a1, #0
+ BEQ longjmp_return
+ LDFE f7, [v1, #sj_f7]
+ LDFE f6, [v1, #sj_f6]
+ LDFE f5, [v1, #sj_f5]
+ LDFE f4, [v1, #sj_f4]
+longjmp_return
+ MOV a1, v6
+ LDMIA v1, {v1-v6, sl, fp, sp, lr}
+ RET
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__divide|, CODE, READONLY
+; The code area containing __rt_sdiv, __rt_udiv, __rt_sdiv_10, __rt_udiv10 ;
+;----------------------------------------------------------------------------;
+; GENERIC ARM FUNCTIONS - divide and remainder. ;
+; ;
+; NOTES ;
+; ;
+; 1/ You may wish to make these functions part of your O/S kernel, replacing ;
+; the implementations here by branches to the relevant entry addresses. ;
+; ;
+; 2/ Each divide function is a div-rem function, returning the quotient in ;
+; r0 and the remainder in r1. Thus (r0, r1) -> (r0/r1, r0%r1). This is ;
+; understood by the C compiler. ;
+; ;
+; 3/ Because of its importance in many applications, divide by 10 is treated ;
+; as a special case. The C compiler recognises divide by 10 and generates ;
+; calls to __rt_{u,s}div10, as appropriate. ;
+; ;
+; 4/ Each of the implementations below has been coded with smallness as a ;
+; higher priority than speed. Unrolling the loops will allow faster ;
+; execution, but will produce much larger code. If the speed of divides ;
+; is critical then unrolled versions can be extracted from the ARM ANSI C ;
+; Library. ;
+; ;
+;----------------------------------------------------------------------------;
+
+; div_core is used by __rt_sdiv and __rt_udiv, and corrupts a3, a4 and ip
+div_core
+ CMP a3, a4
+ MOVHI a4, a4, ASL #1
+ BHI div_core
+div_core2
+ CMP a2, a4
+ ADC ip, ip, ip
+ SUBHS a2, a2, a4
+ CMP a1, a4
+ MOVLO a4, a4, LSR #1
+ BLO div_core2
+ MOV a1, ip
+ RET
+
+; Signed divide of a2 by a1: returns quotient in a1, remainder in a2
+; Quotient is truncated (rounded towards zero).
+; Sign of remainder = sign of dividend.
+; Destroys a3, a4 and ip
+; Negates dividend and divisor, then does an unsigned divide; signs
+; get sorted out again at the end.
+
+|__rt_sdiv|
+ MOVS a3, a1
+ BEQ dividebyzero ; ip now unwanted
+
+ RSBMI a1, a1, #0 ; absolute value of divisor
+ EOR a3, a3, a2
+ ANDS ip, a2, #&80000000
+ ORR a3, ip, a3, LSR #1
+ STMFD sp!,{a3,lr}
+ ; saved a3:
+ ; bit 31 sign of dividend (= sign of remainder)
+ ; bit 30 sign of dividend EOR sign of divisor (= sign of quotient)
+ RSBNE a2, a2, #0 ; absolute value of dividend
+
+ MOV a3, a2
+ MOV a4, a1
+ MOV ip, #0
+ BL div_core
+ LDMFD sp!,{a3}
+ MOVS a3, a3, ASL #1
+ RSBMI a1, a1, #0
+ RSBCS a2, a2, #0
+ IF {CONFIG} = 26
+ LDMFD sp!,{pc}^
+ ELSE
+ LDMFD sp!,{pc}
+ ENDIF
+
+; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2
+; Destroys a4, ip and r5
+
+|__rt_udiv|
+ MOVS a4, a1
+ BEQ dividebyzero
+
+ MOV ip, #0
+ MOV a3, #&80000000
+ CMP a2, a3
+ MOVLO a3, a2
+ B div_core
+
+;
+; Fast unsigned divide by 10: dividend in a1, divisor in a2.
+; Returns quotient in a1, remainder in a2.
+; Also destroys a3.
+;
+; Calculate x / 10 as (x * 2**32/10) / 2**32.
+; That is, we calculate the most significant word of the double-length
+; product. In fact, we calculate an approximation which may be 1 off
+; because we've ignored a carry from the least significant word we didn't
+; calculate. We correct for this by insisting that the remainder < 10
+; and by incrementing the quotient if it isn't.
+
+|__rt_udiv10| ; udiv10 ;
+ MOV a2, a1
+ MOV a1, a1, LSR #1
+ ADD a1, a1, a1, LSR #1
+ ADD a1, a1, a1, LSR #4
+ ADD a1, a1, a1, LSR #8
+ ADD a1, a1, a1, LSR #16
+ MOV a1, a1, LSR #3
+ ADD a3, a1, a1, ASL #2
+ SUB a2, a2, a3, ASL #1
+ CMP a2, #10
+ ADDGE a1, a1, #1
+ SUBGE a2, a2, #10
+ RET
+
+;
+; Fast signed divide by 10: dividend in a1, divisor in a2.
+; Returns quotient in a1, remainder in a2.
+; Also destroys a3 and a4.
+; Quotient is truncated (rounded towards zero).
+; Make use of __rt_udiv10
+
+|__rt_sdiv10| ; sdiv10 ;
+ MOV ip, lr
+ MOVS a4, a1
+ RSBMI a1, a1, #0
+ BL __rt_udiv10
+ CMP a4, #0
+ RSBMI a1, a1, #0
+ RSBMI a2, a2, #0
+ IF {CONFIG} = 26
+ MOVS pc, ip
+ ELSE
+ MOV pc, ip
+ ENDIF
+
+;
+; Test for division by zero (used when division is voided).
+
+|__rt_divtest| ; divtest ;
+ CMPS a1, #0
+ RET NE
+dividebyzero
+ ADR ip, DivideByZeroError
+ B save_regs_and_trap
+
+DivideByZeroError
+ DCD 1
+ DCB "divide by 0", 0
+ ALIGN
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.H
new file mode 100644
index 0000000..0366f05
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.H
@@ -0,0 +1,56 @@
+/*
+ * Standalone C run-time kernel.
+ * Copyright (C) 1991 Advanced RISC Machines Limited.
+ */
+
+#ifndef __rtstand_h
+#define __rtstand_h
+
+
+extern void __rt_exit(int /* code */); /*
+ * Terminate execution; equivalent to returning from main.
+ * NOTE: all other details are determined by your implementation.
+ */
+
+typedef struct {unsigned errnum; char errmess[252];} __rt_error;
+typedef struct {int r[16];} __rt_registers;
+
+extern void __err_handler(__rt_error *, __rt_registers *);
+
+extern int __rt_fpavailable(void);
+/*
+ * Return non-0 iff there is support for the floating-point instruction set.
+ */
+
+extern unsigned __rt_alloc(unsigned /*minwords*/, void ** /*block*/);
+/*
+ * Tries to allocate a block of sensible size >= minwords. Failing that,
+ * it allocates the largest possible block (may have size zero).
+ * Sensible size is determined by your implementation (default: 256 words).
+ * *block is set to a pointer to the start of the allocated block
+ * (NULL if 'a block of size zero' has been allocated).
+ */
+
+#ifdef __JMP_BUF_SIZE
+typedef int jmp_buf[__JMP_BUF_SIZE];
+#else
+typedef int jmp_buf[22]; /* size suitable for the ARM */
+#endif /* an array type suitable for holding the data */
+ /* needed to restore a calling environment. */
+#ifdef __STDC__
+/* setjmp is a macro so that it cannot be used other than directly called. */
+/* NB that ANSI declare that anyone who undefined the setjmp macro or uses */
+/* (or defines) the name setjmp without including this header will get */
+/* what they deserve. NOTE: -pcc mode doesn't allow circular definitions...*/
+#define setjmp(jmp_buf) (setjmp(jmp_buf))
+#endif
+
+extern int setjmp(jmp_buf /*env*/);
+
+extern int longjmp(jmp_buf /*env*/, int /*val*/);
+
+typedef unsigned int size_t; /* others (e.g. <stdio.h>) define */
+
+extern void *__rt_memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/);
+
+#endif
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.S
new file mode 100644
index 0000000..7d85dfa
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/RTSTAND1.S
@@ -0,0 +1,787 @@
+; Issue: 0.03/23-Feb-93
+;
+; Purpose: Minimal, standalone, C-library kernel.
+;
+; Copyright (C) 1993 Advanced RISC Machines Limited. All rights reserved.
+;
+; Advanced RISC Machines Limited does not assume any liability arising out
+; of this program or use thereof neither does it convey any licence under
+; its intellectual property rights.
+;
+; Conditions of use:
+;
+; The terms and conditions under which this software is supplied to you and
+; under which you may use it are described in your licence agreement with
+; your supplier.
+;
+;----------------------------------------------------------------------------;
+; ABOUT THIS CODE ;
+; ;
+; This code shows you how to write your own minimal, standalone, run-time ;
+; support system for code compiled by Advanced RISC Machines's C Compiler. ;
+; It can be assembled using Advanced RISC Machines's ARM assembler (armasm) ;
+; or any assembler comaptible with it. ;
+; ;
+; This example code has been written to run under Advanced RISC Machines's ;
+; ARM emulation system (ARMulator). It can also run without modification ;
+; under Acorm Computer's "RISC OS" operating system for its ARM-based ;
+; personal workstations. ;
+; ;
+; In fact, this code depends hardly at all on its target environment and is ;
+; designed to be very easy to adapt to your particular ARM-based system. ;
+; You can expect it to take about a couple of hours to re-target. ;
+; ;
+; Much of the code below is generic to the ARM processor and is completely ;
+; independent of your ARM-based hardware or any operating system kernel that ;
+; may run on it. To get going, you need write only 4 simple fns. ;
+; ;
+; WHAT THIS CODE PROVIDES: ;
+; ;
+; - Example, executable implementations (for the ARMulator) of the few ;
+; simple functions you need to implement to customise this code to your ;
+; environment. These include: ;
+; - setting up the initial stack and heap and calling main (__main) ;
+; - program termination (__rt_exit) ;
+; - determining FP instruction-set availability (__rt_fpavailable) ;
+; ;
+; - Functions to help with heap allocation, stack-limit checking, setjmp ;
+; and longjmp. These may need to be customised for your environment, ;
+; but can almost certainly be used as-is in a first re-targetting. ;
+; ;
+; - Fully 'rolled' divide (and remainder) functions. ;
+; ;
+; WHAT THIS CODE DOES NOT PROVIDE ;
+; ;
+; - Support for handling traps, faults, escapes, exceptions or interrupts. ;
+; ;
+; - A way to print to the debugging channel (use in line SWIs) ;
+; ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; The following constant is the Top Of Memory - Adjust this for your system ;
+;----------------------------------------------------------------------------;
+
+TopOfMemory EQU 0x80000 ; 512Kb
+
+;----------------------------------------------------------------------------;
+; Things you may wish to tune, but which you don't need to alter, follow. ;
+;----------------------------------------------------------------------------;
+
+DefaultStackSize EQU 4*1024 ; The stack starts of this big unless
+ ; over-ridden by __root_stack_size.
+
+DefaultStackIncrement EQU 1*1024 ; At each overflow it grows by at
+ ; at least this many bytes.
+
+StackSlop EQU 512 ; sl is kept this far above the real
+ ; stack low-water mark. NOTE: MUST be
+ ; >= 256 or the compiled limit checks
+ ; will be invalidated.
+
+MinHeapIncrement EQU 256 ; Min number of WORDS to extend the
+ ; heap by on calling __rt_alloc.
+
+ GBLL EnsureNoFPSupport
+EnsureNoFPSupport SETL {FALSE} ; If {TRUE} then the availability of
+ ; Floating Point Support is ignored.
+ ; If {FALSE} then FP availability is
+ ; checked for.
+ ; Setting to {TRUE} saves a little
+ ; space.
+
+;----------------------------------------------------------------------------;
+; Symbols defined in other, separately-assembled modules, must be IMPORTed. ;
+; We import them WEAKly so that they need not be defined. ;
+;----------------------------------------------------------------------------;
+
+ IF EnsureNoFPSupport = {FALSE}
+ IMPORT |__fp_initialise|, WEAK
+ IMPORT |__fp_finalise|, WEAK
+ ENDIF
+
+;----------------------------------------------------------------------------;
+; The existence of __fp_initialise (imported WEAKly) indicates that floating ;
+; point support code (or the access stub thereof) has been linked with this ;
+; application. If you wish to load the FP support code separately, you may ;
+; want to define some other mechanism for detecting the presence/absence of ;
+; floating point support. Note that setjmp and longjmp must know whether the ;
+; floating-point instruction set is supported. ;
+; __fp_initialise is called by __main and __fp_finalise is called by _exit. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT |__root_stack_size|, WEAK
+
+;----------------------------------------------------------------------------;
+; If __root_stack_size, also imported WEAKly, exists, the value it addresses ;
+; is used as the initial size of the stack. It can be defined in your C ;
+; program as, e.g. int __root_stack_size = 10000; /* 10KB initial stack */ ;
+;----------------------------------------------------------------------------;
+
+ IMPORT |__err_handler|, WEAK
+
+;----------------------------------------------------------------------------;
+; If __err_handler exists, errors are passed to it; otherwise, we print a ;
+; simple diagnostic message and exit. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT |Image$$RW$$Limit|
+
+;----------------------------------------------------------------------------;
+; Image$$RW$$Limit is a linker-created symbol marking the end of the image. ;
+; Its value is used as the heap base. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT main
+
+;----------------------------------------------------------------------------;
+; The symbol main identifies the C function entered from this code. ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; THE MEMORY MODEL ASSUMED BY THIS IMPLEMENTATION ;
+; ;
+; +----------------+ <--- top of memory (high address) ;
+; | Stack space | ;
+; |................| <--- stack pointer (sp) ;
+; | Free stack | ;
+; |................| <--- stack limit pointer (sl) ;
+; +----------------+ <--- stack low-water mark (sl - StackSlop) ;
+; | | ;
+; | Unused memory | ;
+; | | ;
+; +----------------+ <--- top of heap (HeapLimit) ;
+; | | ;
+; | Heap space | ;
+; | | ;
+; +----------------+ <--- top of application (Image$$RW$$Limit) ;
+; | Static data | } ;
+; |................| } the application's memory image ;
+; | Code | } ;
+; +----------------+ <--- application load address ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; Now the symbols we define and EXPORT from this this module. ;
+;----------------------------------------------------------------------------;
+; First, symbols identifying the four functions you have to implement to ;
+; make this run-time kernel work on your hardware. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__main|
+ EXPORT |__rt_exit|
+ EXPORT |__rt_fpavailable|
+ EXPORT |__rt_trap|
+
+;----------------------------------------------------------------------------;
+; Then some simple support for C heap management. It interacts with stack- ;
+; limit checking but should require no attention in a first re-targetting. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__rt_alloc|
+
+;----------------------------------------------------------------------------;
+; Next, optional support for C stack-limit checking. This code should need ;
+; no attention in a first re-targetting. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__rt_stkovf_split_small| ; veneer
+ EXPORT |__rt_stkovf_split_big|
+
+;----------------------------------------------------------------------------;
+; Then two C-specific functions which should require no attention in a first ;
+; re-targetting. Note that they depend on __rt_fpavailable. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |setjmp|
+ EXPORT |longjmp|
+
+;----------------------------------------------------------------------------;
+; And, finally, generic ARM functions, referred to by the C compiler. ;
+; You should not need to alter any of these unless you wish to incorporate ;
+; them in your operating system kernel. See also later comments. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__rt_udiv|
+ EXPORT |__rt_udiv10|
+ EXPORT |__rt_sdiv|
+ EXPORT |__rt_sdiv10|
+ EXPORT |__rt_divtest|
+
+;----------------------------------------------------------------------------;
+ AREA |C$$data| ; This module's data area ;
+;----------------------------------------------------------------------------;
+
+HeapLimit
+ DCD |Image$$RW$$Limit| ; initialised by the linker.
+
+;----------------------------------------------------------------------------;
+; This code has to run in but 26-bit ARM modes and 32-bit modes. To allow ;
+; for this, the code is carefully written so that all PSR restoration in ;
+; 26-bit mode is via the following macro. ;
+;----------------------------------------------------------------------------;
+
+ MACRO
+ RET $cond
+ IF {CONFIG} = 26
+ MOV$cond.S pc, lr
+ ELSE
+ MOV$cond pc, lr
+ ENDIF
+ MEND
+
+;----------------------------------------------------------------------------;
+; The following four SWI definitions are specific to ARMulator/RISC OS. ;
+; However, you will need to replace the whole of this following section... ;
+; and all uses of these SWIs should also be replaced. ;
+;----------------------------------------------------------------------------;
+
+WriteC EQU 0 ; Write r0 to error/debug stream.
+Write0 EQU 2 ; Write 0-terminated string pointed
+ ; to by r0 to error/debug stream.
+Exit EQU 17 ; Terminate program execution.
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__main|, CODE, READONLY
+; The code area containing __main, __rt_exit ;
+;----------------------------------------------------------------------------;
+
+ ENTRY ; Define the image entry point.
+
+|__main|
+;
+; This is the initial entry point to the image.
+; Have to establish a stack for C
+; No arguments are passed to main from an embedded application,
+; so argc and argv are set up to 0
+
+ MOV sp, #TopOfMemory ; Initial stack pointer...
+ MOV fp, #0 ; No previous frame, so fp=0
+
+ LDR a3, RootStackSize
+ CMP a3, #0 ; Is RootStackSize defined?
+ LDRNE a3, [a3] ; Yes: use value...
+ CMPNE a3, #DefaultStackSize ; but check caller not being silly.
+ MOVLE a3, #DefaultStackSize ; No/silly: use default size.
+
+ SUB sl, sp, a3 ; stack low-water mark
+ ADD sl, sl, #StackSlop ; sl = LWM + StackSlop
+
+ IF EnsureNoFPSupport = {FALSE}
+ LDR a1, fp_initialise ; initialise FP code if present
+ CMP a1, #0
+ MOVNE lr, pc
+ MOVNE pc, a1
+ ENDIF
+
+ MOV a1, #0 ; set argc to 0
+ MOV a2, #0 ; and argv to NUL
+ BL main ; Call main, falling through to
+ ; exit on return.
+
+|__rt_exit| ; exit
+;
+; void __rt_exit(int code);
+; Terminate execution, optionally setting return code (ignored here).
+; MUST NOT RETURN.
+
+ IF EnsureNoFPSupport = {FALSE}
+ LDR a2, fp_finalise ; finalise FP code if present
+ CMP a2, #0
+ MOVNE lr, pc
+ MOVNE pc, a2
+ ENDIF
+ SWI Exit ; suicide...
+
+RootStackSize
+ DCD |__root_stack_size|
+
+ IF EnsureNoFPSupport = {FALSE}
+fp_initialise
+ DCD |__fp_initialise|
+fp_finalise
+ DCD |__fp_finalise|
+ ENDIF
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_fpavailable|, CODE, READONLY
+; The code area containing __rt_fpavailable ;
+;----------------------------------------------------------------------------;
+
+|__rt_fpavailable|
+;
+; int __rt_fpavailable(); return non-0 if FP support code linked.
+
+ IF EnsureNoFPSupport = {FALSE}
+ LDR a1, fp_initialise
+ ELSE
+ MOV a1, #0
+ ENDIF
+ RET
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_trap|, CODE, READONLY
+; The code area containing __rt_trap ;
+;----------------------------------------------------------------------------;
+; Support for low-level failures - currently stack overflow, divide by 0 and ;
+; floating-point exceptions. If there is a higher level handler, call it; ;
+; otherwise, print a message and exit gracefully. ;
+; ;
+; NOTES ;
+; ;
+; typedef struct { unsigned code; char message[252];} __rt_error; ;
+; typedef struct { unsigned r[16];} __rt_registers; ;
+; ;
+;----------------------------------------------------------------------------;
+
+|__rt_trap|
+;
+; void __rt_trap(__rt_error *e, __rt_registers *r);
+
+ STMFD sp!, {a1} ; save e in case handler returns...
+ LDR ip, err_handler
+ CMP ip, #0
+ MOVNE lr, pc
+ IF {CONFIG} = 26
+ MOVNES pc, ip ; if got a handler, use it and
+ ELSE
+ MOVNE pc, ip ; if got a handler, use it and
+ ENDIF
+ LDMFD sp!, {v1} ; hope not to return...
+
+ ADR a1, RTErrorHead
+ SWI Write0 ; write preamble...
+ ADD a1, v1, #4
+ SWI Write0 ; write error diagnosis
+ ADR a1, RTErrorTail
+ SWI Write0 ; write postlude
+ MOV a1, #255
+ B |__rt_exit| ; and terminate with non-zero exit code
+err_handler
+ DCD |__err_handler|
+
+save_regs_and_trap
+ STMFD sp!, {sp, lr, pc}
+ STMFD sp!, {r0-r12}
+ STR lr, [sp, #4*15] ; caller's pc is my lr
+ MOV a2, sp
+ MOV a1, ip
+ B |__rt_trap|
+
+RTErrorHead
+ DCB 10, 13, "run time error: ", 0
+
+RTErrorTail
+ DCB 10, 13, "program terminated", 10, 13, 10, 13, 0
+
+ ALIGN
+
+;----------------------------------------------------------------------------;
+; YOU SHOULDN'T NEED TO ALTER ANY OF THE FOLLOWING IN A FIRST RETARGETTING. ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_alloc|, CODE, READONLY
+; The code area containing __rt_alloc ;
+;----------------------------------------------------------------------------;
+; Primitive support for heap memory management. ;
+; ;
+; NOTES ;
+; ;
+; 1/ The allocator embeds knowledge of the memory layout and interacts with ;
+; the stack limit checking code. Here we assume a single address space ;
+; with the stack at the top growing down and the heap below it growing ;
+; up, with a gap (free memory) in between. ;
+; ;
+; 2/ Failure of the stack-limit check is fatal. However, failure of the low- ;
+; level heap allocator is passed back to its caller. ;
+;----------------------------------------------------------------------------;
+
+
+|__rt_alloc| ; alloc
+;
+; unsigned __rt_alloc(unsigned minwords, void **block);
+;
+; This tries to allocate a block of sensible size >= minwords. Failing that,
+; it allocates the largest possible block of sensible size. If it can't do
+; that, it returns zero. *block is set to point to the start of the allocated
+; block (NULL if none has been allocated).
+;
+; NOTE: works in units of WORDS, NOT bytes.
+;
+; In this implementation, sl - StackSlop marks the end of allocatable store.
+
+ CMP a1, #MinHeapIncrement ; round up to at least
+ MOVLT a1, #MinHeapIncrement ; MinHeapIncrement words...
+ LDR a3, HeapLimitAdr
+ LDR a4, [a3] ; current heap high-water mark
+ SUB ip, sl, #StackSlop ; current stack low-water mark
+ CMP a4, ip
+ MOVGE a4, #0 ; no space, *block = NULL
+ STR a4, [a2]
+ MOVGE a1, #0 ; no space, return 0
+ ADD a4, a4, a1, LSL #2 ; proposed new heap limit
+ CMP a4, ip
+ SUBGT a2, a4, ip ; byte overlap, >= 0 by earlier code
+ SUBGT a1, a1, a2, LSR #2 ; reduce word request
+ MOVGT a4, ip ; new high-water = stack low-water
+ STR a4, [a3]
+ RET
+HeapLimitAdr
+ DCD HeapLimit
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_stkovf|, CODE, READONLY
+; The code area containing __rt_stkovf_* ;
+;----------------------------------------------------------------------------;
+; C stack-limit checking support. ;
+; ;
+; NOTES ;
+; ;
+; 1/ Stack-limit-checking is optional - you can compile your C code without ;
+; stack-limit checks (#pragma nocheck_stack or cc -zps0). However, the ;
+; cost of the check is (very) small and the value sometimes considerable. ;
+; ;
+; 2/ The limit check embeds knowledge of the memory layout and interacts ;
+; with the primitive memory management supported by __rt_alloc. Here, we ;
+; assume a single address space with the stack at the top growing down ;
+; and the heap below it growing up, with a gap (free memory) in between. ;
+; ;
+; 3/ Failure of the stack-limit check is fatal. However, failure of the low- ;
+; level heap allocator is passed back to its caller. ;
+; ;
+; 4/ This implementation never reduces the size of the stack. It simply ;
+; moves the low-water mark monatonically downwards. It is easy to do ;
+; better, but, of course, it takes more code and is more target-specific. ;
+;----------------------------------------------------------------------------;
+
+|__rt_stkovf_split_small| ; stkovf_split_small_frame ;
+;
+; Enter here when a C function with frame size <= 256 bytes underflows
+; the stack low-water mark + StackSlop (sl). The stack space required has
+; already been claimed by decrementing sp, so we set the proposed sp (ip)
+; to the actual sp and fall into the big-frame case.
+
+ MOV ip, sp ; fall into big-frame case with size of 0.
+
+|__rt_stkovf_split_big| ; stkovf_split_big_frame ;
+;
+; Enter here when a C function with frame size > 256 bytes would underflow
+; the stack low-water mark + StackSlop (sl). No stack space has been claimed
+; but the proposed new stack pointer is in ip.
+
+ SUB ip, sp, ip ; frame size required...
+ CMP ip, #DefaultStackIncrement ; rounded up to at least
+ MOVLT ip, #DefaultStackIncrement ; the default increment
+
+ SUB sl, sl, ip
+ SUB sl, sl, #StackSlop ; new stack low-water mark
+
+ LDR ip, HeapLimitAdr ; check doesn't collide with
+ LDR ip, [ip] ; the heap.
+ CMP ip, sl
+ ADD sl, sl, #StackSlop ; restore safety margin
+ BGT stackoverflow
+ RET ; and return if OK...
+
+stackoverflow
+ ADR ip, StackOverflowError
+ B save_regs_and_trap
+
+StackOverflowError
+ DCD 3
+ DCB "stack overflow", 0
+ ALIGN
+
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__jmp|, CODE, READONLY
+; The code area containing setjmp, longjmp ;
+;----------------------------------------------------------------------------;
+; Setjmp and longjmp support. ;
+; ;
+; NOTES ;
+; ;
+; 1/ Specific to C and not implementable in C. ;
+; ;
+; 2/ Interacts with stack management and possibly with memory management. ;
+; e.g. on a chunked stack, longjmp must de-allocate jumped-over chunks. ;
+; ;
+; 3/ Must know whether the floating-point instruction-set is supported! ;
+; (DEPENDS ON __rt_fpavailable to discover this). ;
+; ;
+;----------------------------------------------------------------------------;
+
+ MAP 0 ; This structure maps the jmp_buf
+sj_v1 # 4 ; data type assumed by the C compiler.
+sj_v2 # 4 ; First, space to save the v-registers...
+sj_v3 # 4
+sj_v4 # 4
+sj_v5 # 4
+sj_v6 # 4
+sj_sl # 4 ; then the frame registers sl, fp, sp (ap),
+sj_fp # 4 ; and pc/lr...
+sj_ap # 4
+sj_pc # 4
+sj_f4 # 3*4 ; and finally the floating-point reisters,
+sj_f5 # 3*4 ; used only if floating point support is
+sj_f6 # 3*4 ; available.
+sj_f7 # 3*4
+
+
+|setjmp| ; setjmp
+;
+; int setjmp(jmp_buf env);
+; Saves everything that might count as a register variable in 'env'.
+
+ STMIA a1!, {v1-v6, sl, fp, sp, lr}
+ MOV v6, a1 ; v6 safe in env - use to point past
+ ; saved lr (at 1st FP slot)
+ BL |__rt_fpavailable|
+ CMP a1, #0
+ BEQ setjmp_return ; no fp
+ STFE f4, [v6, #sj_f4-sj_f4]
+ STFE f5, [v6, #sj_f5-sj_f4]
+ STFE f6, [v6, #sj_f6-sj_f4]
+ STFE f7, [v6, #sj_f7-sj_f4]
+ MOV a1, #0 ; must return 0 from a direct call
+setjmp_return
+ LDMDB v6, {v6, sl, fp, sp, lr}
+ RET
+
+|longjmp| ; longjmp ;
+; int longjmp(jmp_buf env, int val);
+
+ MOV v1, a1 ; save env ptr over call to fpavailable
+ MOVS v6, a2 ; ensure non-0 return value...
+ MOVEQ v6, #1 ; (must NOT return 0 on longjmp(env, 0))
+ BL |__rt_fpavailable|
+ CMP a1, #0
+ BEQ longjmp_return
+ LDFE f7, [v1, #sj_f7]
+ LDFE f6, [v1, #sj_f6]
+ LDFE f5, [v1, #sj_f5]
+ LDFE f4, [v1, #sj_f4]
+longjmp_return
+ MOV a1, v6
+ LDMIA v1, {v1-v6, sl, fp, sp, lr}
+ RET
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__divide|, CODE, READONLY
+; The code area containing __rt_sdiv, __rt_udiv, __rt_sdiv_10, __rt_udiv10 ;
+;----------------------------------------------------------------------------;
+; GENERIC ARM FUNCTIONS - divide and remainder. ;
+; ;
+; NOTES ;
+; ;
+; 1/ You may wish to make these functions part of your O/S kernel, replacing ;
+; the implementations here by branches to the relevant entry addresses. ;
+; ;
+; 2/ Each divide function is a div-rem function, returning the quotient in ;
+; r0 and the remainder in r1. Thus (r0, r1) -> (r0/r1, r0%r1). This is ;
+; understood by the C compiler. ;
+; ;
+; 3/ Because of its importance in many applications, divide by 10 is treated ;
+; as a special case. The C compiler recognises divide by 10 and generates ;
+; calls to __rt_{u,s}div10, as appropriate. ;
+; ;
+; 4/ Each of the implementations below has been coded with smallness as a ;
+; higher priority than speed. Unrolling the loops will allow faster ;
+; execution, but will produce much larger code. If the speed of divides ;
+; is critical then unrolled versions can be extracted from the ARM ANSI C ;
+; Library. ;
+; ;
+;----------------------------------------------------------------------------;
+
+; div_core is used by __rt_sdiv and __rt_udiv, and corrupts a3, a4 and ip
+div_core
+ CMP a3, a4
+ MOVHI a4, a4, ASL #1
+ BHI div_core
+div_core2
+ CMP a2, a4
+ ADC ip, ip, ip
+ SUBHS a2, a2, a4
+ CMP a1, a4
+ MOVLO a4, a4, LSR #1
+ BLO div_core2
+ MOV a1, ip
+ RET
+
+; Signed divide of a2 by a1: returns quotient in a1, remainder in a2
+; Quotient is truncated (rounded towards zero).
+; Sign of remainder = sign of dividend.
+; Destroys a3, a4 and ip
+; Negates dividend and divisor, then does an unsigned divide; signs
+; get sorted out again at the end.
+
+|__rt_sdiv|
+ MOVS a3, a1
+ BEQ dividebyzero ; ip now unwanted
+
+ RSBMI a1, a1, #0 ; absolute value of divisor
+ EOR a3, a3, a2
+ ANDS ip, a2, #&80000000
+ ORR a3, ip, a3, LSR #1
+ STMFD sp!,{a3,lr}
+ ; saved a3:
+ ; bit 31 sign of dividend (= sign of remainder)
+ ; bit 30 sign of dividend EOR sign of divisor (= sign of quotient)
+ RSBNE a2, a2, #0 ; absolute value of dividend
+
+ MOV a3, a2
+ MOV a4, a1
+ MOV ip, #0
+ BL div_core
+ LDMFD sp!,{a3}
+ MOVS a3, a3, ASL #1
+ RSBMI a1, a1, #0
+ RSBCS a2, a2, #0
+ IF {CONFIG} = 26
+ LDMFD sp!,{pc}^
+ ELSE
+ LDMFD sp!,{pc}
+ ENDIF
+
+; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2
+; Destroys a4, ip and r5
+
+|__rt_udiv|
+ MOVS a4, a1
+ BEQ dividebyzero
+
+ MOV ip, #0
+ MOV a3, #&80000000
+ CMP a2, a3
+ MOVLO a3, a2
+ B div_core
+
+;
+; Fast unsigned divide by 10: dividend in a1, divisor in a2.
+; Returns quotient in a1, remainder in a2.
+; Also destroys a3.
+;
+; Calculate x / 10 as (x * 2**32/10) / 2**32.
+; That is, we calculate the most significant word of the double-length
+; product. In fact, we calculate an approximation which may be 1 off
+; because we've ignored a carry from the least significant word we didn't
+; calculate. We correct for this by insisting that the remainder < 10
+; and by incrementing the quotient if it isn't.
+
+|__rt_udiv10| ; udiv10 ;
+ MOV a2, a1
+ MOV a1, a1, LSR #1
+ ADD a1, a1, a1, LSR #1
+ ADD a1, a1, a1, LSR #4
+ ADD a1, a1, a1, LSR #8
+ ADD a1, a1, a1, LSR #16
+ MOV a1, a1, LSR #3
+ ADD a3, a1, a1, ASL #2
+ SUB a2, a2, a3, ASL #1
+ CMP a2, #10
+ ADDGE a1, a1, #1
+ SUBGE a2, a2, #10
+ RET
+
+;
+; Fast signed divide by 10: dividend in a1, divisor in a2.
+; Returns quotient in a1, remainder in a2.
+; Also destroys a3 and a4.
+; Quotient is truncated (rounded towards zero).
+; Make use of __rt_udiv10
+
+|__rt_sdiv10| ; sdiv10 ;
+ MOV ip, lr
+ MOVS a4, a1
+ RSBMI a1, a1, #0
+ BL __rt_udiv10
+ CMP a4, #0
+ RSBMI a1, a1, #0
+ RSBMI a2, a2, #0
+ IF {CONFIG} = 26
+ MOVS pc, ip
+ ELSE
+ MOV pc, ip
+ ENDIF
+
+;
+; Test for division by zero (used when division is voided).
+
+|__rt_divtest| ; divtest ;
+ CMPS a1, #0
+ RET NE
+dividebyzero
+ ADR ip, DivideByZeroError
+ B save_regs_and_trap
+
+DivideByZeroError
+ DCD 1
+ DCB "divide by 0", 0
+ ALIGN
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_memmove|, CODE, READONLY
+; The code area containing __rt_memmove() extracted from the ARM C Library ;
+; Note that as this was produced using armcc -apcs 3/32bit it is only ;
+; intended for use in 32 bit modes ;
+;----------------------------------------------------------------------------;
+
+ EXPORT |__rt_memmove|
+|__rt_memmove|
+ ORR a4,a1,a2
+ ORR a4,a4,a3
+ ANDS a4,a4,#3
+ BNE |L000064.J4.__rt_memmove|
+ MOV a3,a3,LSR #2
+ CMP a1,a2
+ MOVLT a4,a1
+ BLT |L000034.J9.__rt_memmove|
+ ADD a4,a1,a3,LSL #2
+ ADD a2,a2,a3,LSL #2
+ B |L000050.J13.__rt_memmove|
+|L00002c.J8.__rt_memmove|
+ LDR ip,[a2],#4
+ STR ip,[a4],#4
+|L000034.J9.__rt_memmove|
+ MOV ip,a3
+ SUB a3,a3,#1
+ CMP ip,#0
+ BHI |L00002c.J8.__rt_memmove|
+ MOV pc,lr
+|L000048.J12.__rt_memmove|
+ LDR ip,[a2,#-4]!
+ STR ip,[a4,#-4]!
+|L000050.J13.__rt_memmove|
+ MOV ip,a3
+ SUB a3,a3,#1
+ CMP ip,#0
+ BHI |L000048.J12.__rt_memmove|
+ MOV pc,lr
+|L000064.J4.__rt_memmove|
+ CMP a1,a2
+ MOVLT a4,a1
+ BLT |L000084.J19.__rt_memmove|
+ ADD a4,a1,a3
+ ADD a2,a2,a3
+ B |L0000a0.J23.__rt_memmove|
+|L00007c.J18.__rt_memmove|
+ LDRB ip,[a2],#1
+ STRB ip,[a4],#1
+|L000084.J19.__rt_memmove|
+ MOV ip,a3
+ SUB a3,a3,#1
+ CMP ip,#0
+ BHI |L00007c.J18.__rt_memmove|
+ MOV pc,lr
+|L000098.J22.__rt_memmove|
+ LDRB ip,[a2,#-1]!
+ STRB ip,[a4,#-1]!
+|L0000a0.J23.__rt_memmove|
+ MOV ip,a3
+ SUB a3,a3,#1
+ CMP ip,#0
+ BHI |L000098.J22.__rt_memmove|
+ MOV pc,lr
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/THUMB/RTSTAND.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/THUMB/RTSTAND.S
new file mode 100644
index 0000000..605926f
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/CLSTAND/THUMB/RTSTAND.S
@@ -0,0 +1,819 @@
+; Issue: 1.00/19-Jan-95
+;
+; Purpose: Minimal, standalone, C-library kernel for Thumb
+;
+; Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+;
+; Advanced RISC Machines Limited does not assume any liability arising out
+; of this program or use thereof neither does it convey any licence under
+; its intellectual property rights.
+;
+; Conditions of use:
+;
+; The terms and conditions under which this software is supplied to you and
+; under which you may use it are described in your licence agreement with
+; your supplier.
+;
+;----------------------------------------------------------------------------;
+; ABOUT THIS CODE ;
+; ;
+; This code shows you how to write your own minimal, standalone, Thumb ;
+; run-time support system for code compiled by Advanced RISC Machines's ;
+; Thumb C Compiler. It can be assembled using Advanced RISC Machines's Thumb ;
+; assembler. ;
+; ;
+; This code may be used to build a ROM image. It may also be run under ;
+; Advanced RISC Machines's ARM emulation system (ARMulator). ;
+; ;
+; In fact, this code depends hardly at all on its target environment and is ;
+; designed to be very easy to adapt to your particular ARM-based system. ;
+; ;
+; Much of the code below is generic to the ARM processor and is completely ;
+; independent of your ARM-based hardware or any operating system kernel that ;
+; may run on it. To get going, you need write only 4 simple fns. ;
+; ;
+; WHAT THIS CODE PROVIDES: ;
+; ;
+; - Example, executable implementations of the few ;
+; simple functions you need to implement to customise this code to your ;
+; environment. These include: ;
+; - setting up the initial stack and heap and calling main (__main) ;
+; - program termination (__rt_exit) ;
+; ;
+; - Functions to help with heap allocation, stack-limit checking, setjmp ;
+; and longjmp. These may need to be customised for your environment, ;
+; but can almost certainly be used as-is in a first re-targetting. ;
+; ;
+; - Fully 'rolled' divide (and remainder) functions. ;
+; ;
+; WHAT THIS CODE DOES NOT PROVIDE ;
+; ;
+; - Support for handling traps, faults, escapes, exceptions or interrupts. ;
+; ;
+; - A way to print to the debugging channel (use in line SWIs) ;
+; ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; The following constant is the Top Of RAM - Adjust this for your system ;
+;----------------------------------------------------------------------------;
+
+TopOfMemory EQU 0x80000 ; 512Kb
+
+;----------------------------------------------------------------------------;
+; Things you may wish to tune, but which you don't need to alter, follow. ;
+;----------------------------------------------------------------------------;
+
+DefaultStackSize EQU 4*1024 ; The stack starts of this big unless
+ ; over-ridden by __root_stack_size.
+
+DefaultStackIncrement EQU 1*1024 ; At each overflow it grows by at
+ ; at least this many bytes.
+
+StackSlop EQU 512 ; sl is kept this far above the real
+ ; stack low-water mark. NOTE: MUST be
+ ; >= 256 or the compiled limit checks
+ ; will be invalidated.
+
+MinHeapIncrement EQU 256 ; Min number of WORDS to extend the
+ ; heap by on calling __rt_alloc.
+
+;----------------------------------------------------------------------------;
+; Symbols defined in other, separately-assembled modules, must be IMPORTed. ;
+; We import them WEAKly so that they need not be defined. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT __root_stack_size, WEAK
+
+;----------------------------------------------------------------------------;
+; If __root_stack_size, also imported WEAKly, exists, the value it addresses ;
+; is used as the initial size of the stack. It can be defined in your C ;
+; program as, e.g. int __root_stack_size = 10000; /* 10KB initial stack */ ;
+;----------------------------------------------------------------------------;
+
+ IMPORT __err_handler, WEAK
+
+;----------------------------------------------------------------------------;
+; If __err_handler exists, errors are passed to it; otherwise, we print a ;
+; simple diagnostic message and exit. ;
+;----------------------------------------------------------------------------;
+
+ IMPORT |Image$$RO$$Base|
+ IMPORT |Image$$RO$$Limit|
+ IMPORT |Image$$RW$$Base|
+ IMPORT |Image$$RW$$Limit|
+ IMPORT |Image$$ZI$$Base|
+ IMPORT |Image$$ZI$$Limit|
+
+;----------------------------------------------------------------------------;
+; The above symbols are created by the linker to define various sections in ;
+; the ROM/RAM image. ;
+; ;
+; Image$$RO$$Base defines the code (ROM) base address ;
+; Image$$RO$$Limit defines the code limit and the start of a section of ;
+; data initialisation values which are copied to RAM ;
+; in __main below before main is called. ;
+; Image$$RW$$Base defines the data (RAM) base address ;
+; Image$$RW$$Limit defines the data end address ;
+; Image$$ZI$$Base defines the base of a section to be initialised with 0s ;
+; Image$$ZI$$Limit defines the end of the region to be initialised with 0s ;
+; (must be the same as Image$$RW$$Limit in this model) ;
+;----------------------------------------------------------------------------;
+
+ IMPORT main
+
+;----------------------------------------------------------------------------;
+; The symbol main identifies the C function entered from this code. ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; THE MEMORY MODEL ASSUMED BY THIS IMPLEMENTATION ;
+; ;
+; RAM ;
+; ;
+; +------------------+ <--- top of memory (high address) ;
+; | Stack space | ;
+; |..................| <--- stack pointer (sp) ;
+; | Free stack | ;
+; |..................| <--- stack limit pointer (sl) ;
+; +------------------+ <--- stack low-water mark (sl - StackSlop) ;
+; | | ;
+; | Unused memory | ;
+; | | ;
+; +------------------+ <--- top of heap (HeapLimit) ;
+; | | ;
+; | Heap space | ;
+; | | ;
+; +------------------+ <--- top of fixed data (Image$$RW$$Limit) ;
+; | Zero init data | (=Image$$ZI$$Limit) ;
+; +------------------+ <--- top of initialised (Image$$ZI$$Base) ;
+; | Initialised data | data ;
+; +------------------+ <--- Data base address (Image$$RW$$Base) ;
+; ;
+; ROM ;
+; ;
+; +------------------+ <--- Top of ROM image ;
+; | Initial values | } Copied to "Initialised data" section in RAM ;
+; | for Init data | } on statup in __main below ;
+; +------------------+ <--- End of code (Image$$RO$$Limit) ;
+; | Code | ;
+; +------------------+ <--- Code base address (Image$$RO$$Base) ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+; Now the symbols we define and EXPORT from this module. ;
+;----------------------------------------------------------------------------;
+; First, symbols identifying the four functions you have to implement to ;
+; make this run-time kernel work on your hardware. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT __main
+ EXPORT __rt_exit
+ EXPORT __rt_trap
+
+;----------------------------------------------------------------------------;
+; Then some simple support for C heap management. It interacts with stack- ;
+; limit checking but should require no attention in a first re-targetting. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT __rt_alloc
+
+;----------------------------------------------------------------------------;
+; Next, optional support for C stack-limit checking. This code should need ;
+; no attention in a first re-targetting. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT __16__rt_stkovf_split_small ; veneer
+ EXPORT __16__rt_stkovf_split_big
+
+;----------------------------------------------------------------------------;
+; Then two C-specific functions which should require no attention in a first ;
+; re-targetting. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT setjmp
+ EXPORT longjmp
+
+;----------------------------------------------------------------------------;
+; And, finally, generic ARM functions, referred to by the C compiler. ;
+; You should not need to alter any of these unless you wish to incorporate ;
+; them in your operating system kernel. See also later comments. ;
+;----------------------------------------------------------------------------;
+
+ EXPORT __16__rt_udiv
+ EXPORT __16__rt_udiv10
+ EXPORT __16__rt_sdiv
+ EXPORT __16__rt_sdiv10
+ EXPORT __16__rt_divtest
+
+;----------------------------------------------------------------------------;
+ AREA |C$$data| ; This module's data area ;
+;----------------------------------------------------------------------------;
+
+HeapLimit
+ DCD |Image$$RW$$Limit| ; initialised by the linker.
+
+;----------------------------------------------------------------------------;
+; Macro to return from a function ;
+; We use the BX instruction below rather than MOV pc, lr so that the return ;
+; will work correctly if we are called from ARM state ;
+;----------------------------------------------------------------------------;
+
+ MACRO
+ RET
+ BX lr
+ MEND
+
+;----------------------------------------------------------------------------;
+; The following four SWI definitions are specific to ARMulator/RISC OS. ;
+; However, you will need to replace the whole of this following section... ;
+; and all uses of these SWIs should also be replaced. ;
+;----------------------------------------------------------------------------;
+
+WriteC EQU 0 ; Write r0 to error/debug stream.
+Write0 EQU 2 ; Write 0-terminated string pointed
+ ; to by r0 to error/debug stream.
+Exit EQU 17 ; Terminate program execution.
+
+ CODE16
+
+TBit EQU 1 ; Bit to set in register to enter
+ ; Thumb state with BX <reg>
+
+;----------------------------------------------------------------------------;
+; Use area name "!!!" so this area is placed first as AREAs are sorted by
+; area name.
+ AREA |!!!|, CODE, READONLY, INTERWORK
+; The code area containing __main, __rt_exit ;
+;----------------------------------------------------------------------------;
+
+ ENTRY ; Define the image entry point.
+
+__main
+ CODE32 ; Entered in ARM state presumeably
+ ADR lr, __main_16+TBit
+ BX lr
+ CODE16
+__main_16
+;
+; This is the initial entry point to the image.
+; Have to establish a stack for C
+; No arguments are passed to main from an embedded application,
+; so argc and argv are set up to 0
+
+ LDR r0, =TopOfMemory ; Set up initial stack pointer
+ MOV sp, r0
+
+ MOV r0, #0
+ MOV fp, r0 ; No previous frame, so fp=0
+
+ LDR r0, =DefaultStackSize
+ LDR r1, =__root_stack_size
+ CMP r1, #0 ; Is RootStackSize defined?
+ BEQ %F0 ; No => Use default
+ LDR r1, [r1] ; Yes => Get value
+ CMP r1, r0 ; But check value >= DefaultStackSize
+ BCC %F0 ; if >= use default in r0.
+ MOV r0, r1
+0
+ MOV r1, sp
+ SUB r1, r0 ; stack low limit
+ LDR r0, =StackSlop
+ ADD r1, r0 ; plus a bit spare
+ MOV sl, r1
+
+; Now initialise the data segment by copying the initial values from ROM
+; to RAM and by clearing the zero init segment to 0.
+
+ LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM initial values
+ LDR r1, =|Image$$RW$$Base| ; And RAM data segment
+ LDR r3, =|Image$$ZI$$Base| ; Zero init base = top of initialised segment
+ CMP r0, r1 ; Check that they are different, (they may be
+ BEQ %F3 ; the same if the image is running in RAM)
+ B %F2
+1
+ LDMIA r0!, {r2} ; Copy the initialising data over
+ STMIA r1!, {r2}
+2 CMP r1, r3
+ BCC %B1
+3
+ LDR r1, =|Image$$ZI$$Limit| ; Top of area to be zero initialised
+ MOV r2, #0
+ B %F5
+
+4 STMIA r3!, {r2} ; Clear out zero init segment
+5 CMP r3, r1
+ BCC %B4
+
+ MOV r0, #0 ; set argc to 0
+ MOV r1, #0 ; and argv to NUL
+ BL main ; Call main, falling through to
+ ; exit on return.
+
+__rt_exit ; exit
+;
+; void __rt_exit(int code);
+; Terminate execution, optionally setting return code (ignored here).
+; MUST NOT RETURN.
+
+ SWI Exit ; suicide...
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_trap|, CODE, READONLY
+; The code area containing __rt_trap ;
+;----------------------------------------------------------------------------;
+; Support for low-level failures - currently stack overflow and divide by 0. ;
+; If there is a higher level handler, call it otherwise, print a message and ;
+; exit gracefully. ;
+; ;
+; NOTES ;
+; ;
+; typedef struct { unsigned code; char message[252];} __rt_error; ;
+; typedef struct { unsigned r[16];} __rt_registers; ;
+; ;
+;----------------------------------------------------------------------------;
+
+__rt_trap
+;
+; void __rt_trap(__rt_error *e, __rt_registers *r);
+
+ PUSH {r0} ; save e in case handler returns...
+ LDR r3, =__err_handler
+ CMP r3, #0
+ BEQ %F0
+
+ BL call_via_r3 ; Call the routine pointed to by R3
+ ; Note: BL sets bit 0 of LR so return will
+ ; be to Thumb state. This is why we use this
+ ; rather than the sequence
+ ; MOV lr, pc
+ ; BX r3
+ ; which may return to ARM state!
+
+0
+ ADR r0, RTErrorHead ; No handler, or handler returned
+ SWI Write0 ; write preamble...
+ POP {r0}
+ ADD r0, #4
+ SWI Write0 ; write error diagnosis
+ ADR r0, RTErrorTail
+ SWI Write0 ; write postlude
+ MOV a1, #255
+ BL __rt_exit ; and terminate with non-zero exit code
+
+call_via_r3
+ BX r3
+
+; SP has already been decremented by 16 * 4 and R0..R7 saved.
+; IP points to the error description
+; R7 contains the LR register which has been destroyed as a BL was required
+; to get here.
+save_regs_and_trap
+ MOV ip, r0
+ MOV r0, r8
+ MOV r1, r9
+ MOV r2, r10
+ MOV r3, r11
+ MOV r4, r12
+ ADD r5, sp, #16*4 ; Take account of previous SP adjustment
+ ADD r6, sp, #8*4 ; Pointer to hi reg save area
+ STMIA r6!, {r0-r5, r7}
+ STR r7, [sp, #15*4] ; Save my pc as callers lr
+ MOV a2, sp
+ MOV a1, ip
+ B __rt_trap
+
+ ALIGN
+RTErrorHead
+ DCB 10, 13, "run time error: ", 0
+
+ ALIGN
+RTErrorTail
+ DCB 10, 13, "program terminated", 10, 13, 10, 13, 0
+
+ ALIGN
+
+;----------------------------------------------------------------------------;
+; YOU SHOULDN'T NEED TO ALTER ANY OF THE FOLLOWING IN A FIRST RETARGETTING. ;
+;----------------------------------------------------------------------------;
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_alloc|, CODE, READONLY
+; The code area containing __rt_alloc ;
+;----------------------------------------------------------------------------;
+; Primitive support for heap memory management. ;
+; ;
+; NOTES ;
+; ;
+; 1/ The allocator embeds knowledge of the memory layout and interacts with ;
+; the stack limit checking code. Here we assume a single address space ;
+; with the stack at the top growing down and the heap below it growing ;
+; up, with a gap (free memory) in between. ;
+; ;
+; 2/ Failure of the stack-limit check is fatal. However, failure of the low- ;
+; level heap allocator is passed back to its caller. ;
+;----------------------------------------------------------------------------;
+
+
+__rt_alloc ; alloc
+;
+; unsigned __rt_alloc(unsigned minwords, void **block);
+;
+; This tries to allocate a block of sensible size >= minwords. Failing that,
+; it allocates the largest possible block of sensible size. If it can't do
+; that, it returns zero. *block is set to point to the start of the allocated
+; block (NULL if none has been allocated).
+;
+; NOTE: works in units of WORDS, NOT bytes.
+;
+; In this implementation, sl - StackSlop marks the end of allocatable store.
+
+ LDR r2, =MinHeapIncrement
+ CMP r0, r2 ; round up to at least
+ BGE %F0
+ MOV r0, r2 ; MinHeapIncrement words...
+0
+ MOV ip, sl
+ LDR r2, =-StackSlop
+ ADD ip, r2 ; current stack low-water mark
+ LDR r2, =HeapLimit
+ LDR r3, [r2] ; current heap high-water mark
+ CMP r3, ip
+ BLE %F1
+ MOV r3, #0 ; no space, *block = NULL
+ MOV r0, #0 ; no space, return 0
+1
+ STR r3, [r1]
+ LSL r0, #2 ; Convert size request to bytes
+ ADD r3, r0 ; proposed new heap limit
+ CMP r3, ip
+ BLE %F2
+ ADD r0, ip ; Reduce size request by amount
+ SUB r0, r3 ; of overlap
+ MOV r3, ip ; new high-water = stack low-water
+2
+ STR r3, [r2]
+ LSR r0, #2 ; Convert return size to words
+ RET
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__rt_stkovf|, CODE, READONLY
+; The code area containing __rt_stkovf_* ;
+
+ [ :LNOT::DEF:STACK_EXTENSION
+ GBLL STACK_EXTENSION
+STACK_EXTENSION SETL {FALSE}
+ ]
+;----------------------------------------------------------------------------;
+; C stack-limit checking support. ;
+; ;
+; NOTES ;
+; ;
+; 1/ This code is only called if stack checking is enabled with the ;
+; -apcs 3/swst option on the Thumb compiler. Typically you will only do ;
+; this when debugging. ;
+; ;
+; 2/ The code may be configured to either perform automatic stack extension ;
+; or to generate an error on stack overflow. By default it is set up to ;
+; generate an error. To change this to extend the stack uncomment the ;
+; following line. ;
+; ;
+;STACK_EXTENSION SETL {TRUE} ;
+; ;
+; 3/ The stack extension embeds knowledge of the memory layout and interacts ;
+; with the primitive memory management supported by __rt_alloc. Here, we ;
+; assume a single address space with the stack at the top growing down ;
+; and the heap below it growing up, with a gap (free memory) in between. ;
+; ;
+; 4/ Failure of the stack-limit check is fatal. However, failure of the low- ;
+; level heap allocator is passed back to its caller. ;
+; ;
+; 5/ This implementation of stack extension never reduces the size of the ;
+; stack. It simply moves the low-water mark downwards. It is easy to do ;
+; better, but, of course, it takes more code and is more target-specific. ;
+;----------------------------------------------------------------------------;
+
+__16__rt_stkovf_split_small
+;
+; Enter here when a C function with frame size <= 256 bytes underflows
+; the stack low-water mark + StackSlop (sl). The stack space required has
+; already been claimed by decrementing sp, so we set the proposed sp (ip)
+; to the actual sp and fall into the big-frame case.
+
+ [ STACK_EXTENSION
+ MOV ip, sp ; fall into big-frame case with size of 0.
+ ]
+
+__16__rt_stkovf_split_big
+;
+; Enter here when a C function with frame size > 256 bytes would underflow
+; the stack low-water mark + StackSlop (sl). No stack space has been claimed
+; but the proposed new stack pointer is in ip.
+
+ [ STACK_EXTENSION
+ PUSH {r0,r1}
+ ADD r0, sp, #8 ; get original sp
+ MOV r1, ip
+ SUB r0, r1 ; frame size required...
+ LDR r1, =DefaultStackIncrement
+ CMP r0, r1 ; rounded up to at least
+ BGE %F0
+ MOV r0, r1 ; the default increment
+0
+ MOV r1, sl
+ SUB r1, r0
+ LDR r0, =StackSlop
+ SUB r1, r0 ; new stack low-water mark
+ MOV sl, r1
+
+ LDR r1, =HeapLimit
+ LDR r1, [r1] ; check doesn't collide with
+ CMP r1, sl ; the heap.
+ ADD sl, r0 ; restore safety margin
+ ; (preserves CC)
+
+ POP {r0, r1}
+ BGT stackoverflow
+ RET ; and return if OK...
+
+ ]
+stackoverflow
+ SUB sp, sp, #8*4 ; Room for R8..R15
+ PUSH {r0-r7}
+ MOV r7, lr
+ ADR r0, StackOverflowError
+ BL save_regs_and_trap
+
+ ALIGN
+StackOverflowError
+ DCD 3
+ DCB "stack overflow", 0
+ ALIGN
+
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__jmp|, CODE, READONLY
+; The code area containing setjmp, longjmp ;
+;----------------------------------------------------------------------------;
+; Setjmp and longjmp support. ;
+; ;
+; NOTES ;
+; ;
+; 1/ Specific to C and not implementable in C. ;
+; ;
+; 2/ Interacts with stack management and possibly with memory management. ;
+; e.g. on a chunked stack, longjmp must de-allocate jumped-over chunks. ;
+; ;
+;----------------------------------------------------------------------------;
+
+ MAP 0 ; This structure maps the jmp_buf
+sj_v1 # 4 ; data type assumed by the C compiler.
+sj_v2 # 4 ; First, space to save the v-registers...
+sj_v3 # 4
+sj_v4 # 4
+sj_v5 # 4
+sj_v6 # 4
+sj_sl # 4 ; then the frame registers sl, fp, sp (ap),
+sj_fp # 4 ; and pc/lr...
+sj_ap # 4
+sj_pc # 4
+
+
+setjmp
+;
+; int setjmp(jmp_buf env);
+; Saves everything that might count as a register variable in 'env'.
+
+ STMIA a1!, {r4-r7}
+ MOV r0, r8
+ MOV r1, r9
+ MOV r2, sl
+ MOV r3, fp
+ STMIA a1!, {r0-r3}
+ MOV r0, sp
+ MOV r1, lr
+ STMIA a1!, {r0-r1}
+ MOV a1, #0 ; must return 0 from a direct call
+ RET
+
+longjmp
+; int longjmp(jmp_buf env, int val);
+
+ ADD r0, #4*4
+ LDMIA r0!, {r2-r7} ; Restore r8 .. lr
+ MOV r8, r2
+ MOV r9, r3
+ MOV sl, r4
+ MOV fp, r5
+ MOV sp, r6
+ MOV lr, r7
+ SUB r0, #10*4
+ LDMIA r0!, {r4-r7} ; Restore v1..v4
+ MOV r0, r1
+ BNE %F0
+ MOV r0, #1 ; Must not return 0
+0
+ RET
+
+;----------------------------------------------------------------------------;
+ AREA |C$$code$$__divide|, CODE, READONLY
+; The code area containing __rt_sdiv, __rt_udiv, __rt_sdiv_10, __rt_udiv10 ;
+;----------------------------------------------------------------------------;
+; GENERIC ARM FUNCTIONS - divide and remainder. ;
+; ;
+; NOTES ;
+; ;
+; 1/ You may wish to make these functions part of your O/S kernel, replacing ;
+; the implementations here by branches to the relevant entry addresses. ;
+; ;
+; 2/ Each divide function is a div-rem function, returning the quotient in ;
+; r0 and the remainder in r1. Thus (r0, r1) -> (r0/r1, r0%r1). This is ;
+; understood by the C compiler. ;
+; ;
+; 3/ Because of its importance in many applications, divide by 10 is treated ;
+; as a special case. The C compiler recognises divide by 10 and generates ;
+; calls to __rt_{u,s}div10, as appropriate. ;
+; ;
+; 4/ Each of the implementations below has been coded with smallness as a ;
+; higher priority than speed. Unrolling the loops will allow faster ;
+; execution, but will produce much larger code. If the speed of divides ;
+; is critical then unrolled versions can be extracted from the ARM ANSI C ;
+; Library. ;
+; ;
+;----------------------------------------------------------------------------;
+
+; Signed divide of a2 by a1: returns quotient in a1, remainder in a2
+; Quotient is truncated (rounded towards zero).
+; Sign of remainder = sign of dividend.
+; Destroys a3, a4 and ip
+; Negates dividend and divisor, then does an unsigned divide; signs
+; get sorted out again at the end.
+
+__16__rt_sdiv
+ ASR a4, a2, #31
+ EOR a2, a4
+ SUB a2, a4
+
+ ASR a3, a1, #31
+ EOR a1, a3
+ SUB a1, a3
+
+ BEQ dividebyzero
+
+ PUSH {a3, a4} ; Save so we can look at signs later on
+
+ LSR a4, a2, #1
+ MOV a3, a1
+
+s_loop CMP a3, a4
+ BNLS %FT0
+ LSL a3, #1
+0 BLO s_loop
+
+ MOV a4, #0
+ B %FT0
+s_loop2 LSR a3, #1
+0 CMP a2, a3
+ ADC a4, a4
+ CMP a2, a3
+ BCC %FT0
+ SUB a2, a3
+0
+ CMP a3, a1
+ BNE s_loop2
+ MOV a1, a4
+
+ POP {a3, a4}
+
+ EOR a3, a4
+ EOR a1, a3
+ SUB a1, a3
+
+ EOR a2, a4
+ SUB a2, a4
+
+ RET
+
+; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2
+; Destroys a4, ip and r5
+
+__16__rt_udiv
+ LSR a4, a2, #1
+ MOV a3, a1
+ BEQ dividebyzero
+
+u_loop CMP a3, a4
+ BNLS %FT0
+ LSL a3, #1
+0 BLO u_loop
+
+ MOV a4, #0
+ B %FT0
+u_loop2 LSR a3, #1
+0 CMP a2, a3
+ ADC a4, a4
+ CMP a2, a3
+ BCC %FT0
+ SUB a2, a3
+0
+ CMP a3, a1
+ BNE u_loop2
+ MOV a1, a4
+
+ RET
+
+;
+; Fast unsigned divide by 10: dividend in a1, divisor in a2.
+; Returns quotient in a1, remainder in a2.
+; Also destroys a3.
+;
+; Calculate x / 10 as (x * 2**32/10) / 2**32.
+; That is, we calculate the most significant word of the double-length
+; product. In fact, we calculate an approximation which may be 1 off
+; because we've ignored a carry from the least significant word we didn't
+; calculate. We correct for this by insisting that the remainder < 10
+; and by incrementing the quotient if it isn't.
+
+__16__rt_udiv10 ; udiv10 ;
+ MOV a2, a1
+ LSR a1, #1
+ LSR a3, a1, #1
+ ADD a1, a3
+ LSR a3, a1, #4
+ ADD a1, a3
+ LSR a3, a1, #8
+ ADD a1, a3
+ LSR a3, a1, #16
+ ADD a1, a3
+ LSR a1, #3
+ ASL a3, a1, #2
+ ADD a3, a1
+ ASL a3, #1
+ SUB a2, a3
+ CMP a2, #10
+ BLT %FT0
+ ADD a1, #1
+ SUB a2, #10
+0
+ RET
+
+;
+; Fast signed divide by 10: dividend in a1, divisor in a2.
+; Returns quotient in a1, remainder in a2.
+; Also destroys a3 and a4.
+; Quotient is truncated (rounded towards zero).
+; Make use of __rt_udiv10
+
+__16__rt_sdiv10
+ ASR a4, a1, #31
+ EOR a1, a4
+ SUB a1, a4
+
+ MOV a2, a1
+ LSR a1, #1
+ LSR a3, a1, #1
+ ADD a1, a3
+ LSR a3, a1, #4
+ ADD a1, a3
+ LSR a3, a1, #8
+ ADD a1, a3
+ LSR a3, a1, #16
+ ADD a1, a3
+ LSR a1, #3
+ ASL a3, a1, #2
+ ADD a3, a1
+ ASL a3, #1
+ SUB a2, a3
+ CMP a2, #10
+ BLT %FT0
+ ADD a1, #1
+ SUB a2, #10
+0
+ EOR a1, a4
+ SUB a1, a4
+ EOR a2, a4
+ SUB a2, a4
+ RET
+
+;
+; Test for division by zero (used when division is voided).
+
+__16__rt_divtest ; divtest ;
+ CMPS a1, #0
+ BEQ dividebyzero
+ RET
+
+dividebyzero
+ SUB sp, sp, #8*4 ; Room for R8..R15
+ PUSH {r0-r7}
+ MOV r7, lr
+ ADR r0, DivideByZeroError
+ BL save_regs_and_trap
+
+ ALIGN
+DivideByZeroError
+ DCD 1
+ DCB "divide by 0", 0
+ ALIGN
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/ARMSD.MAP b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/ARMSD.MAP
new file mode 100644
index 0000000..c8941ad
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/ARMSD.MAP
@@ -0,0 +1 @@
+00000000 80000000 RAM 4 RW 135/85 135/85
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.APJ
new file mode 100644
index 0000000..442bb95
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.H
new file mode 100644
index 0000000..9d5c9e7
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY.H
@@ -0,0 +1,431 @@
+/*
+ ****************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry.h (part 1 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ * Siemens AG, E STE 35
+ * Postfach 3240
+ * 8520 Erlangen
+ * Germany (West)
+ * Phone: [xxx-49]-9131-7-20330
+ * (8-17 Central European Time)
+ * Usenet: ..!mcvax!unido!estevax!weicker
+ *
+ * Original Version (in Ada) published in
+ * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ * pp. 1013 - 1030, together with the statistics
+ * on which the distribution of statements etc. is based.
+ *
+ * In this C version, the following C library functions are used:
+ * - strcpy, strcmp (inside the measurement loop)
+ * - printf, scanf (outside the measurement loop)
+ * In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ * are used for execution time measurement. For measurements
+ * on other systems, these calls have to be changed.
+ *
+ * Collection of Results:
+ * Reinhold Weicker (address see above) and
+ *
+ * Rick Richardson
+ * PC Research. Inc.
+ * 94 Apple Orchard Drive
+ * Tinton Falls, NJ 07724
+ * Phone: (201) 389-8963 (9-17 EST)
+ * Usenet: ...!uunet!pcrat!rick
+ *
+ * Please send results to Rick Richardson and/or Reinhold Weicker.
+ * Complete information should be given on hardware and software used.
+ * Hardware information includes: Machine type, CPU, type and size
+ * of caches; for microprocessors: clock frequency, memory speed
+ * (number of wait states).
+ * Software information includes: Compiler (and runtime library)
+ * manufacturer and version, compilation switches, OS version.
+ * The Operating System version may give an indication about the
+ * compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ * The complete output generated by the program should be mailed
+ * such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ * History: This version C/2.1 has been made for two reasons:
+ *
+ * 1) There is an obvious need for a common C version of
+ * Dhrystone, since C is at present the most popular system
+ * programming language for the class of processors
+ * (microcomputers, minicomputers) where Dhrystone is used most.
+ * There should be, as far as possible, only one C version of
+ * Dhrystone such that results can be compared without
+ * restrictions. In the past, the C versions distributed
+ * by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ * had small (though not significant) differences.
+ *
+ * 2) As far as it is possible without changes to the Dhrystone
+ * statistics, optimizing compilers should be prevented from
+ * removing significant statements.
+ *
+ * This C version has been developed in cooperation with
+ * Rick Richardson (Tinton Falls, NJ), it incorporates many
+ * ideas from the "Version 1.1" distributed previously by
+ * him over the UNIX network Usenet.
+ * I also thank Chaim Benedelac (National Semiconductor),
+ * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ * for their help with comments on earlier versions of the
+ * benchmark.
+ *
+ * Changes: In the initialization part, this version follows mostly
+ * Rick Richardson's version distributed via Usenet, not the
+ * version distributed earlier via floppy disk by Reinhold Weicker.
+ * As a concession to older compilers, names have been made
+ * unique within the first 8 characters.
+ * Inside the measurement loop, this version follows the
+ * version previously distributed by Reinhold Weicker.
+ *
+ * At several places in the benchmark, code has been added,
+ * but within the measurement loop only in branches that
+ * are not executed. The intention is that optimizing compilers
+ * should be prevented from moving code out of the measurement
+ * loop, or from removing code altogether. Since the statements
+ * that are executed within the measurement loop have NOT been
+ * changed, the numbers defining the "Dhrystone distribution"
+ * (distribution of statements, operand types and locality)
+ * still hold. Except for sophisticated optimizing compilers,
+ * execution times for this version should be the same as
+ * for previous versions.
+ *
+ * Since it has proven difficult to subtract the time for the
+ * measurement loop overhead in a correct way, the loop check
+ * has been made a part of the benchmark. This does have
+ * an impact - though a very minor one - on the distribution
+ * statistics which have been updated for this version.
+ *
+ * All changes within the measurement loop are described
+ * and discussed in the companion paper "Rationale for
+ * Dhrystone version 2".
+ *
+ * Because of the self-imposed limitation that the order and
+ * distribution of the executed statements should not be
+ * changed, there are still cases where optimizing compilers
+ * may not generate code for some statements. To a certain
+ * degree, this is unavoidable for small synthetic benchmarks.
+ * Users of the benchmark are advised to check code listings
+ * whether code is generated for all statements of Dhrystone.
+ *
+ * Version 2.1 is identical to version 2.0 distributed via
+ * the UNIX network Usenet in March 1988 except that it corrects
+ * some minor deficiencies that were found by users of version 2.0.
+ * The only change within the measurement loop is that a
+ * non-executed "else" part was added to the "if" statement in
+ * Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ ***************************************************************************
+ *
+ * Defines: The following "Defines" are possible:
+ * -DREG=register (default: Not defined)
+ * As an approximation to what an average C programmer
+ * might do, the "register" storage class is applied
+ * (if enabled by -DREG=register)
+ * - for local variables, if they are used (dynamically)
+ * five or more times
+ * - for parameters if they are used (dynamically)
+ * six or more times
+ * Note that an optimal "register" strategy is
+ * compiler-dependent, and that "register" declarations
+ * do not necessarily lead to faster execution.
+ * -DNOSTRUCTASSIGN (default: Not defined)
+ * Define if the C compiler does not support
+ * assignment of structures.
+ * -DNOENUMS (default: Not defined)
+ * Define if the C compiler does not support
+ * enumeration types.
+ * -DTIMES (default)
+ * -DTIME
+ * The "times" function of UNIX (returning process times)
+ * or the "time" function (returning wallclock time)
+ * is used for measurement.
+ * For single user machines, "time ()" is adequate. For
+ * multi-user machines where you cannot get single-user
+ * access, use the "times ()" function. If you have
+ * neither, use a stopwatch in the dead of night.
+ * "printf"s are provided marking the points "Start Timer"
+ * and "Stop Timer". DO NOT use the UNIX "time(1)"
+ * command, as this will measure the total time to
+ * run this program, which will (erroneously) include
+ * the time to allocate storage (malloc) and to perform
+ * the initialization.
+ * -DHZ=nnn
+ * In Berkeley UNIX, the function "times" returns process
+ * time in 1/HZ seconds, with HZ = 60 for most systems.
+ * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ * A VALUE.
+ *
+ ***************************************************************************
+ *
+ * Compilation model and measurement (IMPORTANT):
+ *
+ * This C version of Dhrystone consists of three files:
+ * - dhry.h (this file, containing global definitions and comments)
+ * - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ * - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ * The following "ground rules" apply for measurements:
+ * - Separate compilation
+ * - No procedure merging
+ * - Otherwise, compiler optimizations are allowed but should be indicated
+ * - Default results are those without register declarations
+ * See the companion paper "Rationale for Dhrystone Version 2" for a more
+ * detailed discussion of these ground rules.
+ *
+ * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ * models ("small", "medium", "large" etc.) should be given if possible,
+ * together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ * Dhrystone (C version) statistics:
+ *
+ * [Comment from the first distribution, updated for version 2.
+ * Note that because of language differences, the numbers are slightly
+ * different from the Ada version.]
+ *
+ * The following program contains statements of a high level programming
+ * language (here: C) in a distribution considered representative:
+ *
+ * assignments 52 (51.0 %)
+ * control statements 33 (32.4 %)
+ * procedure, function calls 17 (16.7 %)
+ *
+ * 103 statements are dynamically executed. The program is balanced with
+ * respect to the three aspects:
+ *
+ * - statement type
+ * - operand type
+ * - operand locality
+ * operand global, local, parameter, or constant.
+ *
+ * The combination of these three aspects is balanced only approximately.
+ *
+ * 1. Statement Type:
+ * ----------------- number
+ *
+ * V1 = V2 9
+ * (incl. V1 = F(..)
+ * V = Constant 12
+ * Assignment, 7
+ * with array element
+ * Assignment, 6
+ * with record component
+ * --
+ * 34 34
+ *
+ * X = Y +|-|"&&"|"|" Z 5
+ * X = Y +|-|"==" Constant 6
+ * X = X +|- 1 3
+ * X = Y *|/ Z 2
+ * X = Expression, 1
+ * two operators
+ * X = Expression, 1
+ * three operators
+ * --
+ * 18 18
+ *
+ * if .... 14
+ * with "else" 7
+ * without "else" 7
+ * executed 3
+ * not executed 4
+ * for ... 7 | counted every time
+ * while ... 4 | the loop condition
+ * do ... while 1 | is evaluated
+ * switch ... 1
+ * break 1
+ * declaration with 1
+ * initialization
+ * --
+ * 34 34
+ *
+ * P (...) procedure call 11
+ * user procedure 10
+ * library procedure 1
+ * X = F (...)
+ * function call 6
+ * user function 5
+ * library function 1
+ * --
+ * 17 17
+ * ---
+ * 103
+ *
+ * The average number of parameters in procedure or function calls
+ * is 1.82 (not counting the function values aX *
+ *
+ * 2. Operators
+ * ------------
+ * number approximate
+ * percentage
+ *
+ * Arithmetic 32 50.8
+ *
+ * + 21 33.3
+ * - 7 11.1
+ * * 3 4.8
+ * / (int div) 1 1.6
+ *
+ * Comparison 27 42.8
+ *
+ * == 9 14.3
+ * /= 4 6.3
+ * > 1 1.6
+ * < 3 4.8
+ * >= 1 1.6
+ * <= 9 14.3
+ *
+ * Logic 4 6.3
+ *
+ * && (AND-THEN) 1 1.6
+ * | (OR) 1 1.6
+ * ! (NOT) 2 3.2
+ *
+ * -- -----
+ * 63 100.1
+ *
+ *
+ * 3. Operand Type (counted once per operand reference):
+ * ---------------
+ * number approximate
+ * percentage
+ *
+ * Integer 175 72.3 %
+ * Character 45 18.6 %
+ * Pointer 12 5.0 %
+ * String30 6 2.5 %
+ * Array 2 0.8 %
+ * Record 2 0.8 %
+ * --- -------
+ * 242 100.0 %
+ *
+ * When there is an access path leading to the final operand (e.g. a record
+ * component), only the final data type on the access path is counted.
+ *
+ *
+ * 4. Operand Locality:
+ * -------------------
+ * number approximate
+ * percentage
+ *
+ * local variable 114 47.1 %
+ * global variable 22 9.1 %
+ * parameter 45 18.6 %
+ * value 23 9.5 %
+ * reference 22 9.1 %
+ * function result 6 2.5 %
+ * constant 55 22.7 %
+ * --- -------
+ * 242 100.0 %
+ *
+ *
+ * The program does not compute anything meaningful, but it is syntactically
+ * and semantically correct. All variables have a value assigned to them
+ * before they are used as a source operand.
+ *
+ * There has been no explicit effort to account for the effects of a
+ * cache, or to balance the use of long or short displacements for code or
+ * data.
+ *
+ ***************************************************************************
+ */
+
+/* Compiler and system dependent definitions: */
+
+#ifndef TIME
+#undef TIMES
+#define TIMES
+#endif
+ /* Use times(2) time function unless */
+ /* explicitly defined otherwise */
+
+#ifdef MSC_CLOCK
+#undef HZ
+#undef TIMES
+#include <time.h>
+#define HZ CLK_TCK
+#endif
+ /* Use Microsoft C hi-res clock */
+
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+ /* for "times" */
+#endif
+
+#define Mic_secs_Per_Second 1000000.0
+ /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef NOSTRUCTASSIGN
+#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s) d = s
+#endif
+
+#ifdef NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+ typedef int Enumeration;
+#else
+ typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+ Enumeration;
+#endif
+ /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#include <stdio.h>
+ /* for strcpy, strcmp */
+
+#define Null 0
+ /* Value of a Null pointer */
+#define true 1
+#define false 0
+
+typedef int One_Thirty;
+typedef int One_Fifty;
+typedef char Capital_Letter;
+typedef int Boolean;
+typedef char Str_30 [31];
+typedef int Arr_1_Dim [50];
+typedef int Arr_2_Dim [50] [50];
+
+typedef struct record
+ {
+ struct record *Ptr_Comp;
+ Enumeration Discr;
+ union {
+ struct {
+ Enumeration Enum_Comp;
+ int Int_Comp;
+ char Str_Comp [31];
+ } var_1;
+ struct {
+ Enumeration E_Comp_2;
+ char Str_2_Comp [31];
+ } var_2;
+ struct {
+ char Ch_1_Comp;
+ char Ch_2_Comp;
+ } var_3;
+ } variant;
+ } Rec_Type, *Rec_Pointer;
+
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_1.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_1.C
new file mode 100644
index 0000000..f5ba7a7
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_1.C
@@ -0,0 +1,395 @@
+/*
+ ****************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_1.c (part 2 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+
+#include "dhry.h"
+
+/* Global Variables: */
+
+Rec_Pointer Ptr_Glob,
+ Next_Ptr_Glob;
+int Int_Glob;
+Boolean Bool_Glob;
+char Ch_1_Glob,
+ Ch_2_Glob;
+int Arr_1_Glob [50];
+int Arr_2_Glob [50] [50];
+
+extern char *malloc ();
+Enumeration Func_1 ();
+ /* forward declaration necessary since Enumeration may not simply be int */
+
+#ifndef REG
+ Boolean Reg = false;
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#else
+ Boolean Reg = true;
+#endif
+
+/* variables for time measurement: */
+
+#ifdef TIMES
+struct tms time_info;
+extern int times ();
+ /* see library function "times" */
+#define Too_Small_Time (2*HZ)
+ /* Measurements should last at least about 2 seconds */
+#endif
+#ifdef TIME
+extern long time();
+ /* see library function "time" */
+#define Too_Small_Time 2
+ /* Measurements should last at least 2 seconds */
+#endif
+#ifdef MSC_CLOCK
+extern clock_t clock();
+#define Too_Small_Time (2*HZ)
+#endif
+
+long Begin_Time,
+ End_Time,
+ User_Time;
+float Microseconds,
+ Dhrystones_Per_Second;
+
+/* end of variables for time measurement */
+
+
+main ()
+/*****/
+
+ /* main program, corresponds to procedures */
+ /* Main and Proc_0 in the Ada version */
+{
+ One_Fifty Int_1_Loc;
+ REG One_Fifty Int_2_Loc;
+ One_Fifty Int_3_Loc;
+ REG char Ch_Index;
+ Enumeration Enum_Loc;
+ Str_30 Str_1_Loc;
+ Str_30 Str_2_Loc;
+ REG int Run_Index;
+ REG int Number_Of_Runs;
+
+ /* Initializations */
+
+ Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+ Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+ Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
+ Ptr_Glob->Discr = Ident_1;
+ Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
+ Ptr_Glob->variant.var_1.Int_Comp = 40;
+ strcpy (Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING");
+ strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+ Arr_2_Glob [8][7] = 10;
+ /* Was missing in published program. Without this statement, */
+ /* Arr_2_Glob [8][7] would have an undefined value. */
+ /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
+ /* overflow may occur for this array element. */
+
+ printf ("\n");
+ printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+ printf ("\n");
+ if (Reg)
+ {
+ printf ("Program compiled with 'register' attribute\n");
+ printf ("\n");
+ }
+ else
+ {
+ printf ("Program compiled without 'register' attribute\n");
+ printf ("\n");
+ }
+ printf ("Please give the number of runs through the benchmark: ");
+ {
+ int n;
+ scanf ("%d", &n);
+ Number_Of_Runs = n;
+ }
+ printf ("\n");
+
+ printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+
+ /***************/
+ /* Start timer */
+ /***************/
+
+#ifdef TIMES
+ times (&time_info);
+ Begin_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ Begin_Time = time ( (long *) 0);
+#endif
+#ifdef MSC_CLOCK
+ Begin_Time = clock();
+#endif
+
+ for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+ {
+
+ Proc_5();
+ Proc_4();
+ /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+ Int_1_Loc = 2;
+ Int_2_Loc = 3;
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+ Enum_Loc = Ident_2;
+ Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+ /* Bool_Glob == 1 */
+ while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
+ {
+ Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+ /* Int_3_Loc == 7 */
+ Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+ /* Int_3_Loc == 7 */
+ Int_1_Loc += 1;
+ } /* while */
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+ /* Int_Glob == 5 */
+ Proc_1 (Ptr_Glob);
+ for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+ /* loop body executed twice */
+ {
+ if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+ /* then, not executed */
+ {
+ Proc_6 (Ident_1, &Enum_Loc);
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+ Int_2_Loc = Run_Index;
+ Int_Glob = Run_Index;
+ }
+ }
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Int_2_Loc = Int_2_Loc * Int_1_Loc;
+ Int_1_Loc = Int_2_Loc / Int_3_Loc;
+ Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+ /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+ Proc_2 (&Int_1_Loc);
+ /* Int_1_Loc == 5 */
+
+ } /* loop "for Run_Index" */
+
+ /**************/
+ /* Stop timer */
+ /**************/
+
+#ifdef TIMES
+ times (&time_info);
+ End_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ End_Time = time ( (long *) 0);
+#endif
+#ifdef MSC_CLOCK
+ End_Time = clock();
+#endif
+
+ printf ("Execution ends\n");
+ printf ("\n");
+ printf ("Final values of the variables used in the benchmark:\n");
+ printf ("\n");
+ printf ("Int_Glob: %d\n", Int_Glob);
+ printf (" should be: %d\n", 5);
+ printf ("Bool_Glob: %d\n", Bool_Glob);
+ printf (" should be: %d\n", 1);
+ printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
+ printf (" should be: %c\n", 'A');
+ printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
+ printf (" should be: %c\n", 'B');
+ printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
+ printf (" should be: %d\n", 7);
+ printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
+ printf (" should be: Number_Of_Runs + 10\n");
+ printf ("Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent)\n");
+ printf (" Discr: %d\n", Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 2);
+ printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 17);
+ printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Next_Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent), same as above\n");
+ printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 1);
+ printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 18);
+ printf (" Str_Comp: %s\n",
+ Next_Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Int_1_Loc: %d\n", Int_1_Loc);
+ printf (" should be: %d\n", 5);
+ printf ("Int_2_Loc: %d\n", Int_2_Loc);
+ printf (" should be: %d\n", 13);
+ printf ("Int_3_Loc: %d\n", Int_3_Loc);
+ printf (" should be: %d\n", 7);
+ printf ("Enum_Loc: %d\n", Enum_Loc);
+ printf (" should be: %d\n", 1);
+ printf ("Str_1_Loc: %s\n", Str_1_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
+ printf ("Str_2_Loc: %s\n", Str_2_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
+ printf ("\n");
+
+ User_Time = End_Time - Begin_Time;
+
+ if (User_Time < Too_Small_Time)
+ {
+ printf ("Measured time too small to obtain meaningful results\n");
+ printf ("Please increase number of runs\n");
+ printf ("\n");
+ }
+ else
+ {
+#ifdef TIME
+ Microseconds = (float) User_Time * Mic_secs_Per_Second
+ / (float) Number_Of_Runs;
+ Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
+#else
+ Microseconds = (float) User_Time * Mic_secs_Per_Second
+ / ((float) HZ * ((float) Number_Of_Runs));
+ Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+ / (float) User_Time;
+#endif
+ printf ("Microseconds for one run through Dhrystone: ");
+ printf ("%6.1f \n", Microseconds);
+ printf ("Dhrystones per Second: ");
+ printf ("%6.1f \n", Dhrystones_Per_Second);
+ printf ("\n");
+ }
+
+}
+
+
+Proc_1 (Ptr_Val_Par)
+/******************/
+
+REG Rec_Pointer Ptr_Val_Par;
+ /* executed once */
+{
+ REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
+ /* == Ptr_Glob_Next */
+ /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
+ /* corresponds to "rename" in Ada, "with" in Pascal */
+
+ structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
+ Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+ Next_Record->variant.var_1.Int_Comp
+ = Ptr_Val_Par->variant.var_1.Int_Comp;
+ Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+ Proc_3 (&Next_Record->Ptr_Comp);
+ /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
+ == Ptr_Glob->Ptr_Comp */
+ if (Next_Record->Discr == Ident_1)
+ /* then, executed */
+ {
+ Next_Record->variant.var_1.Int_Comp = 6;
+ Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
+ &Next_Record->variant.var_1.Enum_Comp);
+ Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+ Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
+ &Next_Record->variant.var_1.Int_Comp);
+ }
+ else /* not executed */
+ structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+Proc_2 (Int_Par_Ref)
+/******************/
+ /* executed once */
+ /* *Int_Par_Ref == 1, becomes 4 */
+
+One_Fifty *Int_Par_Ref;
+{
+ One_Fifty Int_Loc;
+ Enumeration Enum_Loc;
+
+ Int_Loc = *Int_Par_Ref + 10;
+ do /* executed once */
+ if (Ch_1_Glob == 'A')
+ /* then, executed */
+ {
+ Int_Loc -= 1;
+ *Int_Par_Ref = Int_Loc - Int_Glob;
+ Enum_Loc = Ident_1;
+ } /* if */
+ while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+Proc_3 (Ptr_Ref_Par)
+/******************/
+ /* executed once */
+ /* Ptr_Ref_Par becomes Ptr_Glob */
+
+Rec_Pointer *Ptr_Ref_Par;
+
+{
+ if (Ptr_Glob != Null)
+ /* then, executed */
+ *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+ Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+Proc_4 () /* without parameters */
+/*******/
+ /* executed once */
+{
+ Boolean Bool_Loc;
+
+ Bool_Loc = Ch_1_Glob == 'A';
+ Bool_Glob = Bool_Loc | Bool_Glob;
+ Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+
+Proc_5 () /* without parameters */
+/*******/
+ /* executed once */
+{
+ Ch_1_Glob = 'A';
+ Bool_Glob = false;
+} /* Proc_5 */
+
+
+ /* Procedure for the assignment of structures, */
+ /* if the C compiler doesn't support this feature */
+#ifdef NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char *d;
+register char *s;
+register int l;
+{
+ while (l--) *d++ = *s++;
+}
+#endif
+
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_2.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_2.C
new file mode 100644
index 0000000..ed0e5b7
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/DHRY/DHRY_2.C
@@ -0,0 +1,192 @@
+/*
+ ****************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_2.c (part 3 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#endif
+
+extern int Int_Glob;
+extern char Ch_1_Glob;
+
+
+Proc_6 (Enum_Val_Par, Enum_Ref_Par)
+/*********************************/
+ /* executed once */
+ /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+
+Enumeration Enum_Val_Par;
+Enumeration *Enum_Ref_Par;
+{
+ *Enum_Ref_Par = Enum_Val_Par;
+ if (! Func_3 (Enum_Val_Par))
+ /* then, not executed */
+ *Enum_Ref_Par = Ident_4;
+ switch (Enum_Val_Par)
+ {
+ case Ident_1:
+ *Enum_Ref_Par = Ident_1;
+ break;
+ case Ident_2:
+ if (Int_Glob > 100)
+ /* then */
+ *Enum_Ref_Par = Ident_1;
+ else *Enum_Ref_Par = Ident_4;
+ break;
+ case Ident_3: /* executed */
+ *Enum_Ref_Par = Ident_2;
+ break;
+ case Ident_4: break;
+ case Ident_5:
+ *Enum_Ref_Par = Ident_3;
+ break;
+ } /* switch */
+} /* Proc_6 */
+
+
+Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+/**********************************************/
+ /* executed three times */
+ /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
+ /* Int_Par_Ref becomes 7 */
+ /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+ /* Int_Par_Ref becomes 17 */
+ /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+ /* Int_Par_Ref becomes 18 */
+One_Fifty Int_1_Par_Val;
+One_Fifty Int_2_Par_Val;
+One_Fifty *Int_Par_Ref;
+{
+ One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 2;
+ *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+ /* executed once */
+ /* Int_Par_Val_1 == 3 */
+ /* Int_Par_Val_2 == 7 */
+Arr_1_Dim Arr_1_Par_Ref;
+Arr_2_Dim Arr_2_Par_Ref;
+int Int_1_Par_Val;
+int Int_2_Par_Val;
+{
+ REG One_Fifty Int_Index;
+ REG One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 5;
+ Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+ Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+ Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+ for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+ Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+ Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+ Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+ Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
+/*************************************************/
+ /* executed three times */
+ /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
+ /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
+ /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
+
+Capital_Letter Ch_1_Par_Val;
+Capital_Letter Ch_2_Par_Val;
+{
+ Capital_Letter Ch_1_Loc;
+ Capital_Letter Ch_2_Loc;
+
+ Ch_1_Loc = Ch_1_Par_Val;
+ Ch_2_Loc = Ch_1_Loc;
+ if (Ch_2_Loc != Ch_2_Par_Val)
+ /* then, executed */
+ return (Ident_1);
+ else /* not executed */
+ {
+ Ch_1_Glob = Ch_1_Loc;
+ return (Ident_2);
+ }
+} /* Func_1 */
+
+
+Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+ /* executed once */
+ /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+ /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+Str_30 Str_1_Par_Ref;
+Str_30 Str_2_Par_Ref;
+{
+ REG One_Thirty Int_Loc;
+ Capital_Letter Ch_Loc;
+
+ Int_Loc = 2;
+ while (Int_Loc <= 2) /* loop body executed once */
+ if (Func_1 (Str_1_Par_Ref[Int_Loc],
+ Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+ /* then, executed */
+ {
+ Ch_Loc = 'A';
+ Int_Loc += 1;
+ } /* if, while */
+ if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+ /* then, not executed */
+ Int_Loc = 7;
+ if (Ch_Loc == 'R')
+ /* then, not executed */
+ return (true);
+ else /* executed */
+ {
+ if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+ /* then, not executed */
+ {
+ Int_Loc += 7;
+ Int_Glob = Int_Loc;
+ return (true);
+ }
+ else /* executed */
+ return (false);
+ } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enum_Par_Val)
+/***************************/
+ /* executed once */
+ /* Enum_Par_Val == Ident_3 */
+Enumeration Enum_Par_Val;
+{
+ Enumeration Enum_Loc;
+
+ Enum_Loc = Enum_Par_Val;
+ if (Enum_Loc == Ident_3)
+ /* then, executed */
+ return (true);
+ else /* not executed */
+ return (false);
+} /* Func_3 */
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/BYTEDEMO.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/BYTEDEMO.C
new file mode 100644
index 0000000..209b4f0
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/BYTEDEMO.C
@@ -0,0 +1,148 @@
+/* Explanation of byte-reversing in ARM assembler
+
+ for PC only (uses cursor control codes)
+*/
+
+#include <stdio.h>
+
+static void cls()
+{
+ printf("\033[2J");
+}
+
+static void up(int n)
+{
+ while (n > 0)
+ { printf("\033[1A"); --n;
+ }
+}
+
+static void pause()
+{
+ fprintf(stderr, "Please press <Return> to proceeed ");
+ while( fgetc(stdin) != '\n' );
+}
+
+static void prologue()
+{
+ printf("\
+ AMAZING FACTS ABOUT THE ARM - Reversing the bytes in a word\n\
+\n\
+This function reverses the bytes in a word. The method was discovered in\n\
+1986 following a competition between ARM programmers; it requires just 4\n\
+instructions and 1 work register. A method using only 3 instructions per\n\
+word reversed was also found, but it has some set-up overhead and uses a\n\
+2nd register. Can you re-discover this method?\n\
+\n\
+Later, the C compiler was 'taught' to generate exactly the instructions\n\
+needed, from C source. Check this claim using armcc -S -DREV byterev.c\n\
+and examining the assembly code file produced.\n\
+\n\
+unsigned long reverse(unsigned long v)\n\
+{ unsigned long t;\n\
+ t = v ^ ((v << 16) | (v >> 16)); /* EOR r1,r0,r0,ROR #16 */\n\
+ t &= ~0xff0000; /* BIC r1,r1,#&ff0000 */\n\
+ v = (v << 24) | (v >> 8); /* MOV r0,r0,ROR #8 */\n\
+ return v ^ (t >> 8); /* EOR r0,r0,r1,LSR #8 */\n\
+}\n\
+\n\
+To see the method in action, press <Return>. Each time you press <Return>\n\
+one step of the reversal process will be executed. The values displayed\n\
+are symbolic, starting with the input word D C B A.\n\
+\n");
+}
+
+static void prelude()
+{
+ printf("\
+ AMAZING FACTS ABOUT THE ARM - Reversing the bytes in a word\n\
+\n\
+unsigned long reverse(unsigned long v)\n\
+{ unsigned long t;\n\
+ t = v ^ ((v << 16) | (v >> 16)); /* EOR r1,r0,r0,ROR #16 */\n\
+ t &= ~0xff0000; /* BIC r1,r1,#&ff0000 */\n\
+ v = (v << 24) | (v >> 8); /* MOV r0,r0,ROR #8 */\n\
+ return v ^ (t >> 8); /* EOR r0,r0,r1,LSR #8 */\n\
+}\n\
+\n");
+}
+
+static void show_state_1()
+{
+ printf("\
+ v / r0 t / r1 original input in v/r0\n\
+\n\
+ +---+---+---+---+ +---+---+---+---+\n\
+ | D | C | B | A | | x | x | x | x |\n\
+ +---+---+---+---+ +---+---+---+---+\n\
+\n\n\n\n\n\n\n");
+}
+
+static void show_state_2()
+{
+ printf("\
+ v / r0 t / r1 state after executing \n\
+\n\
+ +---+---+---+---+ +---+---+---+---+ t = v ^ ((v<<16) | (v>>16));\n\
+ | D | C | B | A | |D^B|C^A|B^D|A^C|\n\
+ +---+---+---+---+ +---+---+---+---+ EOR r1,r0,r0,ROR #16\n\
+\n\n\n\n\n\n\n");
+}
+
+static void show_state_3()
+{
+ printf("\
+ +---+---+---+---+ +---+---+---+---+ t &= ~0xff0000; \n\
+ | D | C | B | A | |D^B| 0 |B^D|A^C|\n\
+ +---+---+---+---+ +---+---+---+---+ BIC r1,r1,#&ff0000 \n\
+\n\n\n\n\n\n\n");
+}
+
+static void show_state_4()
+{
+ printf("\
+ +---+---+---+---+ +---+---+---+---+ v = (v << 24) | (v >> 8);\n\
+ | A | D | C | B | |D^B| 0 |B^D|A^C|\n\
+ +---+---+---+---+ +---+---+---+---+ MOV r0,r0,ROR #8 \n\
+\n\n\n\n\n\n\n");
+}
+
+static void show_state_5()
+{
+ printf("\
+ +---+---+---+---+ +---+---+---+---+ v = v ^ (t >> 8); \n\
+\n\
+ +---+-^-+-^-+-^-+---+ +---+---+---+---+ EOR r0,r0,r1,LSR #8\n\
+ |D^B| 0 |B^D|A^C|\n\
+ +---+---+---+---+\n\
+\n\
+ +---+---+---+---+\n\
+ | A | B | C | D | (original input was: D C B A)\n\
+ +---+---+---+---+\n\
+\n");
+}
+
+int main()
+{
+ cls();
+ prologue();
+ pause();
+ cls();
+ prelude();
+ show_state_1();
+ pause();
+ up(13);
+ show_state_2();
+ pause();
+ up(11);
+ show_state_3();
+ pause();
+ up(11);
+ show_state_4();
+ pause();
+ up(11);
+ show_state_5();
+ pause();
+ fputc('\n', stdout);
+ return( 0 );
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/DIVC.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/DIVC.C
new file mode 100644
index 0000000..3a5d85c
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/DIVC.C
@@ -0,0 +1,213 @@
+/* Optimal divide-by-contstant code generator
+ Advanced RISC Machines
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BANNER "generated by divc 1.02 (Advanced RISC Machines)"
+#define DATE "27 Jan 94"
+
+#define DIVIDE_BY_2_MINUS_1 0
+#define DIVIDE_BY_2_PLUS_1 1
+
+
+typedef unsigned int uint;
+
+
+uint log2( uint n )
+{
+ uint bit, pow, logn;
+
+ for( bit = 0, pow = 1; bit < 31; bit++, pow <<= 1 )
+ {
+ if( n == pow ) logn = bit;
+ }
+
+ return( logn );
+}
+
+
+int powerof2( int n )
+{
+ return( n == ( n & (-n) ) );
+}
+
+
+void dodiv2m1( uint logd, uint logmsb )
+{
+ /* Output instructions to do division by 2^n - 1 */
+ printf( "\tMOV a1, a1, lsr #1\n" );
+
+ while( logd < 32 )
+ {
+ printf( "\tADD a1, a1, a1, lsr #%d\n", logd );
+ logd <<= 1;
+ }
+ printf( "\tMOV a1, a1, lsr #%d\n", logmsb - 1 );
+}
+
+
+void dodiv2p1( uint logd, uint logmsb )
+{
+ /* Output instructions to do division by 2^n + 1 */
+ printf( "\tSUB a1, a1, a1, lsr #%d\n", logd );
+
+ while( logd < 16 )
+ {
+ logd <<= 1;
+ printf( "\tADD a1, a1, a1, lsr #%d\n", logd );
+ }
+
+ printf( "\tMOV a1, a1, lsr #%d\n", logmsb );
+}
+
+
+void loada4( uint type, uint lsb, uint msb )
+{
+ /* Constant is too big to be used as an immediate constant, */
+ /* so load it into register a4. */
+ printf( "\tMOV a4, #0x%x\n", msb );
+
+ switch( type )
+ {
+ case DIVIDE_BY_2_MINUS_1:
+ printf( "\tSUB a4, a4, #0x%x\n", lsb );
+ break;
+
+ case DIVIDE_BY_2_PLUS_1:
+ printf( "\tADD a4, a4, #0x%x\n", lsb );
+ break;
+
+ default:
+ fputs( "Internal error", stderr );
+ }
+}
+
+
+void divideby2( uint type, uint n, uint lsb, uint msb )
+{
+ uint loglsb;
+ uint logmsb;
+ uint usinga4;
+
+ loglsb = log2( lsb );
+ logmsb = log2( msb );
+
+ printf( "; %s [%s]\n\n", BANNER, DATE );
+ printf( "\tAREA |div%d$code|, CODE, READONLY\n\n", n );
+ printf( "\tEXPORT udiv%d\n\n", n );
+ printf( "udiv%d\n", n );
+ printf( "; takes argument in a1\n" );
+ printf( "; returns quotient in a1, remainder in a2\n" );
+ printf( "; cycles could be saved if only divide or remainder is required\n" );
+
+ usinga4 = ( n >> loglsb ) > 255;
+ if( usinga4 )
+ {
+ loada4( type, lsb, msb );
+ printf( "\tSUB a2, a1, a4\n" );
+ }
+ else
+ {
+ printf( "\tSUB a2, a1, #%d\n", n );
+ }
+
+ /* 1/n as a binary number consists of a simple repeating pattern */
+ /* The multiply by 1/n is expanded as a sequence of ARM instructions */
+ /* (there is a rounding error which must be corrected later) */
+ switch( type )
+ {
+ case DIVIDE_BY_2_MINUS_1:
+ dodiv2m1( logmsb - loglsb, logmsb );
+ /* Now do multiply-by-n */
+ printf( "\tRSB a3, a1, a1, asl #%d\n", logmsb - loglsb );
+ break;
+
+ case DIVIDE_BY_2_PLUS_1:
+ dodiv2p1( logmsb - loglsb, logmsb );
+ /* Now do multiply-by-n */
+ printf( "\tADD a3, a1, a1, asl #%d\n", logmsb - loglsb );
+ break;
+
+ default:
+ fputs( "Internal error", stderr );
+ }
+
+ /* Subtract from adjusted original to obtain remainder */
+ printf( "\tSUBS a2, a2, a3, asl #%d\n", loglsb );
+
+ /* Apply corrections */
+ printf( "\tADDPL a1, a1, #1\n" );
+ if( usinga4 )
+ {
+ printf( "\tADDMI a2, a2, a4\n" );
+ }
+ else
+ {
+ printf( "\tADDMI a2, a2, #%d\n", n );
+ }
+
+ /* Additional test required for divide-by-3, as result could be */
+ /* off by 2 lsb due to accumulated rounding errors. */
+ if( n == 3 )
+ {
+ printf( "\tCMP a2, #3\n" );
+ printf( "\tADDGE a1, a1, #1\n" );
+ printf( "\tSUBGE a2, a2, #3\n" );
+ }
+
+ printf( "\tMOV pc, lr\n\n" );
+ printf( "\tEND\n" );
+}
+
+
+int main( int argc, char *argv[] )
+{
+ if( argc != 2 )
+ {
+ printf( "Usage: divc <n>\n" );
+ printf( "Generates optimal ARM code for divide-by-constant\n" );
+ printf( "where <n> is one of (2^n-2^m) or (2^n+2^m) eg. 10\n" );
+ printf( "Advanced RISC Machines [%s]\n", DATE );
+ }
+ else
+ {
+ int num;
+
+ num = atoi( argv[ 1 ] );
+ if( num <= 1 )
+ {
+ fprintf( stderr, "%d is not sensible\n", num );
+ }
+ else
+ {
+ uint lsb = 1;
+
+ /* find least-significant bit */
+ while( ( num & lsb ) == 0 )
+ {
+ lsb <<= 1;
+ }
+
+ if( powerof2( num ) )
+ {
+ fprintf( stderr, "%d is an easy case\n", num );
+ }
+ else if( powerof2( num + lsb ) )
+ {
+ divideby2( DIVIDE_BY_2_MINUS_1, num, lsb, num + lsb );
+ }
+ else if( powerof2( num - lsb ) )
+ {
+ divideby2( DIVIDE_BY_2_PLUS_1, num, lsb, num - lsb );
+ }
+ else
+ {
+ fprintf( stderr, "%d is not one of (2^n-2^m) or (2^n+2^m)\n", num );
+ }
+ }
+ }
+ return( 0 );
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDOM.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDOM.S
new file mode 100644
index 0000000..67aacdf
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDOM.S
@@ -0,0 +1,42 @@
+; Random number generator
+;
+; This uses a 33-bit feedback shift register to generate a pseudo-randomly
+; ordered sequence of numbers which repeats in a cycle of length 2^33 - 1
+; NOTE: randomseed should not be set to 0, otherwise a zero will be generated
+; continuously (not particularly random!).
+;
+; This is a good application of direct ARM assembler, because the 33-bit
+; shift register can be implemented using RRX (which uses reg + carry).
+; An ANSI C version would be less efficient as the compiler would not use RRX.
+
+ AREA |Random$$code|, CODE, READONLY
+
+ EXPORT randomnumber
+
+randomnumber
+; on exit:
+; a1 = low 32-bits of pseudo-random number
+; a2 = high bit (if you want to know it)
+ LDR ip, |seedpointer|
+ LDMIA ip, {a1, a2}
+ TST a2, a2, LSR#1 ; to bit into carry
+ MOVS a3, a1, RRX ; 33-bit rotate right
+ ADC a2, a2, a2 ; carry into LSB of a2
+ EOR a3, a3, a1, LSL#12 ; (involved!)
+ EOR a1, a3, a3, LSR#20 ; (similarly involved!)
+ STMIA ip, {a1, a2}
+
+ MOV pc, lr
+
+|seedpointer|
+ DCD seed
+
+
+ AREA |Random$$data|, DATA
+
+ EXPORT seed
+seed
+ DCD &55555555
+ DCD &55555555
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDTEST.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDTEST.C
new file mode 100644
index 0000000..092ffb4
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANDTEST.C
@@ -0,0 +1,20 @@
+/* Random number generator demo program
+
+ Calls assembler function 'randomnumber' defined in random.s
+*/
+
+#include <stdio.h>
+
+/* this function prototype is needed because 'randomnumber' is external */
+extern unsigned int randomnumber( void );
+
+int main()
+{
+ int loop;
+
+ for( loop = 0; loop < 10; loop++ )
+ { printf( "randomnumber() returned %08x\n", randomnumber() );
+ }
+
+ return( 0 );
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANTEST.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANTEST.APJ
new file mode 100644
index 0000000..e8bde34
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/RANTEST.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UDIV10.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UDIV10.S
new file mode 100644
index 0000000..787bb0b
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UDIV10.S
@@ -0,0 +1,23 @@
+; generated by divc 1.01 (Advanced RISC Machines) [01 Jul 92]
+
+ AREA |div10$code|, CODE, READONLY
+
+ EXPORT udiv10
+
+udiv10
+; takes argument in a1
+; returns quotient in a1, remainder in a2
+; cycles could be saved if only divide or remainder is required
+ SUB a2, a1, #10
+ SUB a1, a1, a1, lsr #2
+ ADD a1, a1, a1, lsr #4
+ ADD a1, a1, a1, lsr #8
+ ADD a1, a1, a1, lsr #16
+ MOV a1, a1, lsr #3
+ ADD a3, a1, a1, asl #2
+ SUBS a2, a2, a3, asl #1
+ ADDPL a1, a1, #1
+ ADDMI a2, a2, #10
+ MOV pc, lr
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA.APJ
new file mode 100644
index 0000000..b4ea8b8
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA1.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA1.S
new file mode 100644
index 0000000..369773a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOA1.S
@@ -0,0 +1,60 @@
+; This demonstrates recursion in ARM assembler.
+; this version does not perform stack checking.
+;
+; Converting a number to a string can be expressed using a divide-and-
+; conquer algorithm:
+; <string> = "<number/10><number%10>"
+
+ AREA |utoa$$code|, CODE, READONLY
+
+ EXPORT dtoa
+ EXPORT utoa
+
+ IMPORT udiv10
+
+dtoa
+; converts signed word to string
+; a1 = char *buffer
+; a2 = signed int number
+; on exit:
+; a1 = char *end_of_string
+
+ CMP a2, #0
+ RSBMI a2, a2, #0; make a2 positive
+ MOVMI ip, #'-'
+ STRMIB ip, [ a1 ], #1 ; add minus sign to buffer
+
+; *** intentional drop-through to utoa ***
+
+utoa
+; recursive routine to convert unsigned word to string
+; on entry:
+; a1 = char *buffer
+; a2 = unsigned int number
+; on exit:
+; a1 = char *end_of_string ; character after last digit
+; all other registers preserved
+
+ STMFD sp!, {v1, v2, lr} ; save 2 variable registers and
+ ; the return address
+
+ MOV v1, a1 ; keep char *buffer for later
+ MOV v2, a2 ; and keep the number for later
+ MOV a1, a2
+ BL udiv10 ; on return, the quotient is in a1
+
+ SUB v2, v2, a1, LSL #3 ; number - 8*quoitient
+ SUB v2, v2, a1, LSL #1 ; - 2*quotient = remainder
+
+ CMP a1, #0 ; quotient non-zero?
+ MOVNE a2, a1 ; quotient to a2...
+ MOV a1, v1 ; buffer pointer unconditionally to a1
+ BLNE utoa ; conditional recursive call to utoa
+
+ ADD v2, v2, #'0' ; final digit
+ STRB v2, [a1], #1 ; store digit at end of buffer
+
+ LDMFD sp!, {v1, v2, pc} ; restore and return
+
+ END
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOATEST.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOATEST.C
new file mode 100644
index 0000000..5e411b5
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/EXPLASM/UTOATEST.C
@@ -0,0 +1,22 @@
+/* test utoa or utoa */
+
+#include <stdio.h>
+
+extern char *utoa( char *string, signed int num );
+
+int main()
+{
+ signed int num;
+ char buffer[ 12 ];
+
+ puts( "Enter number:" );
+
+ if( scanf( "%d", &num ) == 1 )
+ {
+ *utoa( buffer, num ) = 0; /* add string terminator */
+ puts( "utoa yields:" );
+ puts( buffer );
+ }
+
+ return( 0 );
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/GETDATA.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/GETDATA.C
new file mode 100644
index 0000000..b0e5a36
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/GETDATA.C
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int getData(char *buffer,int length)
+{
+ int charsIn;
+ int charRead;
+ charsIn=0;
+ for (charsIn=0;charsIn<length;) {
+ charRead=getchar();
+ if (charRead == EOF) break;
+ buffer[charsIn++]=charRead;
+ if (charRead == '\n' ) break;
+ }
+ for (;(charsIn%3)!=0; ) buffer[charsIn++]='\0';
+ return charsIn;
+}
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAIN.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAIN.C
new file mode 100644
index 0000000..02fb4d6
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAIN.C
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <string.h>
+#define INBUFFSIZE 192
+#define OUTBUFFSIZE 257
+
+static char inBuff[INBUFFSIZE];
+static char outBuff[OUTBUFFSIZE];
+static int charCount=0;
+
+extern int getData(char *,int);
+extern int uuencode(char *, char *, int);
+extern int _sys_flen(int );
+extern int _sys_open(char *,int );
+extern int _sys_read(int, void *, int, int );
+extern int _sys_close(int);
+
+int main(int argc,char **argv)
+{
+ int uuCount;
+ charCount = getData(inBuff,sizeof(inBuff));
+ if (charCount<0) {
+ fprintf(stderr,"Error reading data.\n");
+ }
+ else {
+ uuCount=uuencode(inBuff,outBuff,charCount);
+ outBuff[uuCount]='\0';
+ puts(outBuff);
+ }
+ return 0;
+}
+
+void MemCopy(void *d,void *s,int c)
+{
+ memmove(d,s,c);
+}
+
+int LoadOverlaySegment(int nameLen,char *name,void *baseAdr)
+{
+ char name0[16];
+ int length;
+ int fh;
+
+ memmove(name0,name,nameLen);
+ name0[nameLen]='\0';
+#define OPEN_B 1
+#define OPEN_R 0
+
+ fh = _sys_open(name0,OPEN_B|OPEN_R);
+ if (fh==0) return 0;
+ length = _sys_flen(fh);
+ (void)_sys_read(fh,baseAdr,length,0);
+ (void)_sys_close(fh);
+ return length;
+}
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAININIT.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAININIT.S
new file mode 100644
index 0000000..41220ea
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAININIT.S
@@ -0,0 +1,9 @@
+ AREA MainWithOverlayInit, CODE, READONLY
+ IMPORT |Image$$overlay_init|
+ IMPORT __main
+
+ ENTRY
+ BL |Image$$overlay_init|
+ BL __main
+ END
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAKEFILE b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAKEFILE
new file mode 100644
index 0000000..fcf6760
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/MAKEFILE
@@ -0,0 +1,27 @@
+LIB=
+
+.c.o:
+ armcc -bi -c -APCS 3/32/noswst $<
+
+.s.o:
+ armasm -bi -APCS 3/32/noswst $<
+
+all: ov/root
+ov/root: main.o uue.o getdata.o overmgrs.o maininit.o startup.o
+ armlink -bin -base 0x40000 -data 0x10000 -ov ovlist \
+ -o ov maininit.o startup.o main.o overmgrs.o uue.o getdata.o \
+ -FIRST maininit.o ${LIB}/armlib.32b -map -symbols - -list tS.map \
+ -v
+
+startup.o: startup.s
+
+overmgrs.o: overmgrs.s
+
+maininit.o: maininit.s
+
+main.o: main.c
+
+uue.o: uue.c
+
+getdata.o: getdata.c
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVERMGRS.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVERMGRS.S
new file mode 100644
index 0000000..4aeb6e4
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVERMGRS.S
@@ -0,0 +1,391 @@
+; AUTHORS: L.Smith, J. Sutton
+;
+; DATE: Last edit 16-Mar-90 (ECN)
+;
+; VERSION: 0.07
+;
+; DESCRIPTION: Overlay Manager
+;
+; CHANGES: 28-Feb-90 LDS
+; Fixed a bug in check_for_invalidated_returns whereby a return
+; handler was allocated on return rather than just on call.
+;
+; 16-Mar-90 ECN
+; Use OS_GetEnv to read the overlay directory instead of Obey$Dir
+; which doesn't work if the image is not executed from an obey file.
+;
+; Tidied up the behaviour of "Disk not present errors". The previous
+; version just splatted a message all over the desktop. The new
+; version only prompt for disk insertion if executing outside the
+; desktop (inside the desktop the wimp will prompt the user).
+;
+; Tidied up the generation of errors and exit from application.
+; Previously either gave a trap or stiffed the machine.
+;
+;;; Copyright (C) Advanced RISC Machines Ltd., 1991
+
+ EXPORT |Image$$overlay_init|
+ EXPORT |Image$$load_seg|
+
+; pointers to start and end of workspace area supplied by the linker
+ IMPORT |Overlay$$Data$$Base|
+ IMPORT |Overlay$$Data$$Limit|
+ IMPORT |Image$$RO$$Limit|
+ IMPORT |Image$$RW$$Base|
+ IMPORT |Image$$ZI$$Base|
+ IMPORT MemCopy
+ IMPORT LoadOverlaySegment
+ IMPORT SevereErrorHandler, WEAK
+
+ZeroInitCodeOffset EQU 64
+
+; Why does the linker need to generate this zero init area, why can't the
+; Overlay Manager define it itself??? ECN.
+;
+; Layout of workspace allocated by the linker pointed to by Overlay$$Data
+; This area is automatically zero-initialised AFTER overlay_init is called
+; offsets are prefixed with Work_
+ ^ 0
+Work_HStack # 4 ; top of stack of allocated handlers
+Work_HFree # 4 ; head of free-list
+Work_RSave # 9*4 ; for R0-R8
+Work_LRSave # 4 ; saved lr
+Work_PCSave # 4 ; saved PC
+Work_PSRSave # 4 ; saved CPSR
+Work_ReturnHandlersArea EQU @ ; rest of this memory is treated as heap
+ ; space for the return handlers
+Work_MinSize EQU @ + 32 * RHandl_Size
+
+; Return handler. 1 is allocated per inter-segment procedure call
+; allocated and free lists of handlers are pointed to from HStack and HFree
+; offsets are prefixed with RHandl_
+ ^ 0
+RHandl_Branch # 4 ; BL load_seg_and_ret
+RHandl_RealLR # 4 ; space for the real return address
+RHandl_Segment # 4 ; -> PCIT section of segment to load
+RHandl_Link # 4 ; -> next in stack order
+RHandl_Size EQU @
+
+; set up by check_for_invalidated_returns.
+
+; PCITSection. 1 per segment stored in root segment, allocated by linker
+; offsets are prefixed with PCITSect_
+ ^ 0
+PCITSect_Vecsize # 4 ; .-4-EntryV ; size of entry vector
+PCITSect_Base # 4 ; used by load_segment; not initialised
+PCITSect_Limit # 4 ; used by load_segment; not initialised
+PCITSect_Name # 11 ; <11 bytes> ; 10-char segment name + NUL in 11 bytes
+PCITSect_Flags # 1 ; ...and a flag byte
+PCITSect_ClashSz # 4 ; PCITEnd-.-4 ; size of table following
+PCITSect_Clashes # 4 ; >table of pointers to clashing segments
+
+; Stack structure (all offsets are negative)
+; defined in procedure call standard
+; offsets are prefixed with Stack_
+ ^ 0
+Stack_SaveMask # -4
+Stack_LRReturn # -4
+Stack_SPReturn # -4
+Stack_FPReturn # -4
+
+; the code and private workspace area
+ AREA OverLayMgrArea, PIC, CODE , READONLY
+
+STRLR STR lr, [pc, #-8] ; a word that is to be matched in PCITs
+
+; Store 2 words which are the addresses of the start and end of the workspace
+WorkSpace DCD |Overlay$$Data$$Base|
+WorkSpaceEnd DCD |Overlay$$Data$$Limit|
+InitFlag DCD InitDoneFlag
+
+|Image$$overlay_init| ROUT
+; Initialise overlay manager.
+; In the AIF format this is is called from offset 8 in header. This routine has
+; to pass control to the zero initialisation code.
+; In Non AIF formats this routine has to be called explicitly e.g. from
+; a customised rtstand.s .
+;
+; In the AIF example the entire root segment is copied to the load address.
+;
+; In the non AIF example only the RW part of the root is copied.
+;
+ LDR ip,WorkSpace
+ IF :DEF:AIF_EXAMPLE
+ STR lr,[ip,#Work_LRSave]
+
+ ADD ip,ip,#Work_RSave
+ STMIA ip,{r0-r3}
+
+;
+; Look at the AIF header and add compute the total size of the AIF header
+;
+ SUB r1,lr,#0xC
+
+ LDR r0,[r1,#0x28]
+
+ LDR r2,[r1,#0x14]
+ LDR r3,[r1,#0x18]
+ ADD r2,r2,r3
+ LDR r3,[r1,#0x1C]
+ ADD r2,r2,r3
+
+;
+; A system specific Memory Copy call. r0 is the destination area.
+; r1 is the source area.
+; r2 is the block size in bytes.
+;
+ BL MemCopy
+ LDR ip,WorkSpace
+ LDR lr,[ip,#Work_LRSave]
+ ADD ip,ip,#Work_RSave
+ SUB lr,lr,#12
+ LDR lr,[lr,#0x28]
+ ADD lr,lr,#12
+ LDMIA ip,{r0-r3}
+;
+; Return to the Zero Initialisation Code in the AIF header.
+;
+ ADD pc,lr,#ZeroInitCodeOffset-12
+ ELSE
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+ STMIA ip,{r0-r2,lr}
+
+ LDR r0,=|Image$$RW$$Base|
+ LDR r1,=|Image$$RO$$Limit|
+ LDR r2,=|Image$$ZI$$Base|
+ SUB r2,r2,r0
+ BL MemCopy
+
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+ LDMIA ip,{r0-r2,PC}
+ ENDIF
+
+ DCD 0 ; Not needed for a real system but needed when using ARMSD
+ ; is used to simulate a ROMN based system.
+; entry point
+|Image$$load_seg| ROUT
+; called when segment has been called but is not loaded
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+ MRS r4, CPSR ; Save status register -it'll get stored in the
+ ; workspace later.
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r0, InitFlag
+ LDRB r1, [r0]
+ CMP r1, #0
+ BNE InitDone
+
+;Initialise Return Handlers on first call to this routine
+ MOV r1, #1
+ STRB r1, [r0] ; set InitDone flag
+ LDR r0, WorkSpace
+; r0 points to workspace
+; corrupts r0-r3,lr
+; create and initialise return handler linked list
+ MOV r2, #0
+ STR r2, [r0, #Work_HStack] ; initialise start of handler list with NULL
+ ADD r1, r0, #Work_ReturnHandlersArea ; Start of heap space
+ STR r1, [r0, #Work_HFree] ; Start of list of free handlers point to heap space
+ LDR r0, WorkSpaceEnd ; for test in loop to make sure..
+ SUBS r0, r0, #RHandl_Size ; ..I dont overrun in init
+01 ADD r3, r1, #RHandl_Size ; next handler
+; set up link to point to next handler (in fact consecutive locations)
+ STR r3, [r1, #RHandl_Link]
+ MOV r1, r3 ; next handler
+ CMP r1, r0 ; test for end of workspace
+ BLT %BT01
+ SUB r1, r1, #RHandl_Size ; previous handler
+ STR r2, [r1, #RHandl_Link] ; NULL-terminate list
+
+InitDone
+ LDR r3, WorkSpace
+ STR r4, [r3, #Work_PSRSave] ; CPSR read into R4 before the InitDone
+ ; test.
+ MOV r8,lr ;
+ LDR r0, [r8, #-8] ; saved r14... (is end of PCIT)
+ STR r0, [r3, #Work_LRSave] ; ...save it here ready for retry
+ LDR r0, STRLR ; look for this...
+ SUB r1, r8, #8 ; ... starting at last overwrite
+01 LDR r2, [r1, #-4]!
+ CMP r2, r0 ; must stop on guard word...
+ BNE %B01
+ ADD r1, r1, #4 ; gone one too far...
+ STR r1, [r3, #Work_PCSave] ; where to resume at
+
+load_segment
+
+; ip -> the register save area; r8 -> the PCIT section of the segment to load.
+; First re-initialise the PCIT section (if any) which clashes with this one...
+
+ ADD r1, r8, #PCITSect_Clashes
+ LDR r0, [r8, #PCITSect_ClashSz]
+01 SUBS r0, r0, #4
+ BLT Done_Reinit ; nothing left to do
+ LDR r7, [r1], #4 ; a clashing segment...
+ LDRB r2, [r7, #PCITSect_Flags] ; its flags (0 if unloaded)
+ CMPS r2, #0 ; is it loaded?
+ BEQ %B01 ; no, so look again
+
+; clashing segment is loaded (clearly, there can only be 1 such segment)
+; mark it as unloaded and reinitialise its PCIT
+; r7 -> PCITSection of clashing loaded segment
+
+ MOV r0, #0
+ STRB r0, [r7, #PCITSect_Flags] ; mark as unloaded
+ LDR r0, [r7, #PCITSect_Vecsize]
+ SUB r1, r7, #4 ; end of vector
+ LDR r2, STRLR ; init value to store in the vector...
+02 STR r2, [r1, #-4]! ;>
+ SUBS r0, r0, #4 ;> loop to initialise the PCIT segment
+ BGT %B02 ;>
+; Now we check the chain of call frames on the stack for return addresses
+
+; which have been invalidated by loading this segment and install handlers
+; for each invalidated return.
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+
+ BL check_for_invalidated_returns
+Done_Reinit
+
+; All segment clashes have now been dealt with, as have the re-setting
+; of the segment-loaded flags and the intercepting of invalidated returns.
+; So, now load the required segment.
+
+Retry
+;
+; Call a routine to load the overlay segment.
+; First parameter is the length of the segment name.
+; The second parameter is the address of the segment name
+; The third parameter is the base address of the segement.
+; The routine returns the segment length in r0.
+;
+ MOV r0,#12
+ ADD r1, r8, #PCITSect_Name
+ LDR r2, [ r8, #PCITSect_Base]
+ BL LoadOverlaySegment
+
+ TEQ r0,#0
+ MOVEQ r0,#2
+ BEQ SevereErrorHandler
+
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+;
+; Mark the segment as loaded.
+;
+ MOV r1,#1
+ STRB r1, [r8, #PCITSect_Flags]
+
+ LDR r2, [r8, #PCITSect_Base]
+ ADD r0, r2, r0 ; start + length = end of file
+
+; The segment's entry vector is at the end of the segment...
+; ...copy it to the PCIT section identified by r8.
+
+ LDR r1, [r8, #PCITSect_Vecsize]
+ SUB r3, r8, #8 ; end of entry vector...
+ MOV r4, #0 ; for data initialisation
+01 LDR r2, [r0, #-4]! ;>loop to copy
+ STR r4, [r0] ; (zero-init possible data section)
+ STR r2, [r3], #-4 ;>the segment's PCIT
+ SUBS r1, r1, #4 ;>section into the
+ BGT %B01 ;>global PCIT
+
+; Finally, continue, unabashed...
+
+ LDR r3, WorkSpace
+ LDR r3, [r3,#Work_PSRSave]
+ MSR CPSR,r3
+
+ LDMIA ip, {r0-r8, lr, pc}
+
+load_seg_and_ret
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r3, WorkSpace
+ MRS r8, CPSR
+ STR r8, [r3, #Work_PSRSave]
+
+; lr points to the return handler
+ MOV r8, lr
+ ; load return handler fields RealLR, Segment, Link
+ LDMIA r8, {r0, r1, r2}
+ SUB r8, r8, #4 ; point to true start of return handler before BL
+ STR r0, [r3, #Work_LRSave]
+ STR r0, [r3, #Work_PCSave]
+; Now unchain the handler and return it to the free pool
+; HStack points to this handler
+ LDR r0, [r3, #Work_HStack]
+ CMPS r0, r8
+ MOVNE r0, #1
+ BNE SevereErrorHandler
+ STR r2, [r3, #Work_HStack] ; new top of handler stack
+ LDR r2, [r3, #Work_HFree]
+ STR r2, [r8, #RHandl_Link] ; Link -> old HFree
+ STR r8, [r3, #Work_HFree] ; new free list
+ MOV r8, r1 ; segment to load
+ B load_segment
+
+check_for_invalidated_returns
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+; Note: check for returns invalidated by a call NOT for returns invalidated by
+; a return! In the 2nd case, the saved LR and saved PC are identical.
+ LDR r5, WorkSpace
+ ADD r6, r5, #Work_LRSave ; 1st location to check
+ LDMIA r6, {r0, r1} ; saved LR & PC
+ CMPS r0, r1
+ MOVEQ pc, lr ; identical => returning...
+ MOV r0, fp ; temporary FP...
+01 LDR r1, [r6] ; the saved return address...
+ LDR r2, [r5, #Work_HStack] ; top of handler stack
+ CMPS r1, r2 ; found the most recent handler, so
+ MOVEQ pc, lr ; abort the search
+ LDR r2, [r7, #PCITSect_Base]
+ CMPS r1, r2 ; see if >= base...
+ BLT %F02
+ LDR r2, [r7, #PCITSect_Limit]
+ CMPS r1, r2 ; ...and < limit ?
+ BLT FoundClash
+02 CMPS r0, #0 ; bottom of stack?
+ MOVEQ pc, lr ; yes => return
+ ADD r6, r0, #Stack_LRReturn
+ LDR r0, [r0, #Stack_FPReturn] ; previous FP
+ B %B01
+FoundClash
+ LDR r0, [r5, #Work_HFree] ; head of chain of free handlers
+ CMPS r0, #0
+ MOVEQ r0, #2
+ BEQ SevereErrorHandler
+; Transfer the next free handler to head of the handler stack.
+ LDR r1, [r0, #RHandl_Link] ; next free handler
+ STR r1, [r5, #Work_HFree]
+ LDR r1, [r5, #Work_HStack] ; the active handler stack
+ STR r1, [r0, #RHandl_Link]
+ STR r0, [r5, #Work_HStack] ; now with the latest handler linked in
+; Initialise the handler with a BL load_seg_and_ret, RealLR and Segment.
+ ADR r1, load_seg_and_ret
+ SUB r1, r1, r0 ; byte offset for BL in handler
+ SUB r1, r1, #8 ; correct for PC off by 8
+ MOV r1, r1, ASR #2 ; word offset
+ BIC r1, r1, #&FF000000
+ ORR r1, r1, #&EB000000 ; code for BL
+ STR r1, [r0, #RHandl_Branch]
+
+ LDR r1, [r6] ; LRReturn on stack
+ STR r1, [r0, #RHandl_RealLR] ; RealLR
+ STR r0, [r6] ; patch stack to return to handler
+
+ STR r7, [r0, #RHandl_Segment] ; segment to re-load on return
+ MOV pc, lr ; and return
+
+ AREA OverlayInit, DATA
+InitDoneFlag DCD 0
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVLIST b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVLIST
new file mode 100644
index 0000000..c04b8b5
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/OVLIST
@@ -0,0 +1,2 @@
+bert(0x9000) uue.o
+fred(0x9000) getdata.o
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/STARTUP.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/STARTUP.S
new file mode 100644
index 0000000..b61472a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/STARTUP.S
@@ -0,0 +1,52 @@
+ AREA |!!!|, CODE, READONLY
+
+ IMPORT __entry ; The C library entry point
+
+ EXPORT __main
+
+ IMPORT |Image$$RO$$Base|
+ IMPORT |Image$$RO$$Limit|
+ IMPORT |Image$$RW$$Base|
+ IMPORT |Image$$RW$$Limit|
+ IMPORT |Image$$ZI$$Base|
+ IMPORT |Image$$ZI$$Limit|
+
+;----------------------------------------------------------------------------;
+; The above symbols are created by the linker to define various sections in ;
+; the ROM/RAM image. ;
+; ;
+; Image$$RO$$Base defines the code (ROM) base address ;
+; Image$$RO$$Limit defines the code limit and the start of a section of ;
+; data initialisation values which are copied to RAM ;
+; in __main below before main is called. ;
+; Image$$RW$$Base defines the data (RAM) base address ;
+; Image$$RW$$Limit defines the data end address ;
+; Image$$ZI$$Base defines the base of a section to be initialised with 0s ;
+; Image$$ZI$$Limit defines the end of the region to be initialised with 0s ;
+; (must be the same as Image$$RW$$Limit in this model) ;
+;----------------------------------------------------------------------------;
+
+; Code is enter in ARM mode
+ [ {CONFIG} = 16
+ CODE32
+ ]
+
+__main
+ LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
+ LDR r1, =|Image$$RW$$Base| ; and RAM copy
+ LDR r3, =|Image$$ZI$$Base| ; Zero init base => top of initialised data
+ CMP r0, r1 ; Check that they are different
+ BEQ %FT1
+0 CMP r1, r3 ; Copy init data
+ LDRCC r2, [r0], #4
+ STRCC r2, [r1], #4
+ BCC %BT0
+1 LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment
+ MOV r2, #0
+2 CMP r3, r1 ; Zero init
+ STRCC r2, [r3], #4
+ BCC %BT2
+
+ B __entry
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/TEXT.TXT b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/TEXT.TXT
new file mode 100644
index 0000000..f304e9a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/TEXT.TXT
@@ -0,0 +1,742 @@
+Application Note: Use Of Overlays in A ROM Based System
+
+Version 0.4 May 1995 Laurence Bond
+
+Introduction
+------------
+
+This application note describes an example which uses overlays in a ROM based
+system. The linker section in the Software Development Toolkit manual should
+read in conjunction with this note.
+
+Please note that this example will only work with Tools 200 alpha-1 or later.
+
+Example Application Structure
+-----------------------------
+The overlay root segment code is to be ROM resident. The read-write data will
+be RAM resident when the application is running. The two areas are assumed to
+be mapped into ROM memory in the same manner as a BIN file produced by the
+linker. That is the ROM image of the root segment is:
+ read-only code
+ read-only data
+ read-write code
+ read-write data
+ initialised data
+ zero initialised data
+
+The areas are assumed to be contiguous.
+
+When the overlay manager is initialised the read-write areas should be copied
+from the ROM to the RAM.
+
+Example Memory Structure
+------------------------
+In this example the memory is assumed to have the following structure
+ SRAM at addresses 0x8000 up to 0x18000.
+ ROM starting at the address 0x40000.
+
+Overlay Manager
+---------------
+The linker does not provide the overlay manager. The overlay manager is user
+supplied code which controls the overlay mechanism. The linker produces the
+appropriate binary files and constructs the PCITs (Procedure Call Indirection
+Tables).
+The overlay manager must define two publicly visible symbols
+Image$$overlay_init and Image$$load_seg.
+
+Image$$overlay_init is used to initialise the overlay manager. In an AIF based
+environment, this routine is called from the Debug/Zero Initialisation slot in
+the AIF header. When the overlay manager has been initialised, control should
+be passed to the Zero Initialisation code. In non AIF systems,
+Image$$overlay_init does not get called automatically. However it should be
+called just after the application has been entered. This is the case used in the
+example.
+
+Image$$load_seg is the procedure that performs the functions of the overlay
+manager described in the Software Development toolkit manual.
+
+The overlay manager listed in Appendix A is a modified version of that supplied
+with the toolkit. It has been modified to be more operating system independent
+and to run in 32 bit mode. The code area has also been made read-only. The flag
+used to indicate whether the overlay manager has initialised its workspace has
+been moved to a read-write area of its own.
+
+To aid operating system independence, three routines may be called by the
+overlay manager. These could have replaced by inline code. However to aid
+clarity, this has not been done. The routines are:
+
+ MemCopy
+ r0 - Destination address
+ r1 - Source Address
+ r2 - Block length in bytes
+
+ This routine does not return anything.
+
+ LoadOverlaySegment
+ r0 - Length of overlay segment name.
+ r1 - Overlay segment name address
+ r2 - Address at which the overlay segment is to be written.
+
+ Returns the number of bytes copied. If this is zero it is treated
+ as an error.
+
+ SevereErrorHandler
+ r0 - A value indicating which error condition has occurred.
+
+ This symbol is a weak reference and need not be resolved. In the example
+ no such routine is provided. However in a real application one should be
+ provided.
+
+Linker Symbols
+--------------
+The overlay manager relies on the following linker generated symbols:
+ Image$$RW$$Base Base address of the read-write area
+ Image$$RO$$Limit Address one byte beyond read-only area
+ Image$$ZI$$Limit Address one byte beyond the Zero Initialised
+ data area.
+
+A Pitfall In Using The C library
+--------------------------------
+In this example, a the C library was found to interfere with loaded segments.
+The reason is that in the default C library, the C heap is initialised to start
+at the address Image$$RW$$Limit.
+
+For example, the segments could get corrupted by use of the standard C memory
+allocation package if they are located to an address greater that this. A malloc
+could grab some memory from the heap which just happened to be part of an
+overlayed segments code. Similarly loading an overlay segment could result in
+the segment data being loaded into an area used by the heap, thereby corrupting
+the heap.
+
+
+The Example Application
+-----------------------
+The example application reads a sequence of characters, terminated either by
+end of file or a newline, from stdin. These characters are then UU encoded and
+output to stdout.
+
+The application consists of three C source files and two assembler files
+excluding the overlay manager. The C files are as follows:
+
+ getdata.c
+ This defines a function, getData, which reads the characters into a
+ buffer passed to it by the main program.
+
+ uue.c
+ This defines a function, uue, which takes an input buffer passed
+ in by the main program and writes the UU encoded equivalent into
+ another buffer supplied by the main program.
+
+ main.c
+ This contains the C main program and example implementations of
+ the functions LoadOverlaySegment and MemCopy needed by the overlay
+ manager. Two statically allocated data buffers are also defined.
+
+ The main program calls getData to read data into a buffer. This buffer
+ is then passed to uue as the input buffer. The output buffer is zero
+ terminated after uue returns and the results written to stdout.
+
+ MemCopy is just a call to memmove - a standard C library function.
+
+ LoadOverlaySegment does not use stdio because of the pitfall
+ mentioned above. Low level calls are used to read the
+ file contents. The files are assumed to be in the current directory.
+
+ It is straight forward to modify the example to have the overlays
+ in memory and to copy them to the appropriate locations. This was
+ not done in this application note because it was felt that little
+ information would be added by doing so.
+
+Together with the overlay manager these C files could define the whole
+application. Using a BIN file means that further work is necessary. In
+particular the overlay manager initialisation routine has to be called somehow.
+This requires that the program entry point has to be changed. In this example,
+the C library source file startup.s has been modified to eliminate the ENTRY
+directive. In a customised environment, the ENTRY directive should be removed
+from rtstand.s.
+
+Now a new entry point is required. This supplied by the file maininit.s .
+The file consists of an ENTRY directive and a call to Image$$overlay_init.
+Then the code branches to __main the standard C startup routine.
+
+The source code except for the overlay manager and the modified C __main
+function can be found in Appendix B.
+
+The buffers defined in main.c will be read-write data in the root segment. The
+assembler entry point code, the functions defined in main.c and any C library
+functions extracted from the library will be in the root segment.
+
+The function uue will be in an overlay segment named seg1. The function getData
+will be in an overlay segment named seg2.
+
+Testing The Application
+-----------------------
+The application was built big endian and linked with the following linker
+options:
+ armlink -bin -base 0x40000 -data 0x10000 -ov ovlist \
+ -o ov maininit.o startup.o main.o overmgr.o uue.o \
+ getdata.o -first maininit.o $(LIB) -map -symbols - \
+ -list tS.map -v
+
+This command produces a plain binary file for the root segment. The overlay
+segments are always plain binary files. Both the overlay segments and the
+root segment will be be placed in the ov subdirectory whoch should exist before
+the command is executed.
+
+The full Makefile can be found in Appendix B.
+
+These base the read-only areas at address 0x40000 and the read-write areas at
+0x10000. The file ov specifies where the overlay segments are to be placed.
+The overlay segments in this example were placed at 0x9000. So the file used
+was:
+
+ seg1(0x9000) uue.o
+ seg2(0x9000) getdata.o
+
+This uses the modified overlay file format introduced in Tools 200 Alpha-1.
+
+The application was the loaded into ARMSD. As it was not an AIF file, the
+loading process was done manually.
+Change the current directory to be the ov directory.
+
+ armsd -bi
+ armsd: get root 0x40000
+ armsd: let pc=0x40000
+
+The entry point is at 0x40000 by virtue of the -FIRST option on the linker and
+the code structure in startup.s
+
+After typing 'go' at armsd, the program will wait for the user to type a
+newline terminated string.
+
+ armsd: go
+ Hello World
+ 2&5L;&\@5V]R;&0*
+
+This is correct when compared against UUENCODE on SunOS 4.1.3. Note that
+initial encoded count byte is not output.
+
+ Program terminated normally at PC = 0x00040248
+ 0x00040248: 0xef000011 .... : swi 0x11
+ armsd: q
+ Quitting
+
+Appendix A
+----------
+Overlay Manager Code - overmgr.s
+--------------------------------
+
+;;; Copyright (C) Advanced RISC Machines Ltd., 1991
+
+ EXPORT |Image$$overlay_init|
+ EXPORT |Image$$load_seg|
+
+; pointers to start and end of workspace area supplied by the linker
+ IMPORT |Overlay$$Data$$Base|
+ IMPORT |Overlay$$Data$$Limit|
+ IMPORT |Image$$RO$$Limit|
+ IMPORT |Image$$RW$$Base|
+ IMPORT |Image$$ZI$$Limit|
+ IMPORT MemCopy
+ IMPORT LoadOverlaySegment
+ IMPORT SevereErrorHandler, WEAK
+
+ZeroInitCodeOffset EQU 64
+
+; Layout of workspace allocated by the linker pointed to by Overlay$$Data
+; This area is automatically zero-initialised AFTER overlay_init is called
+; offsets are prefixed with Work_
+ ^ 0
+Work_HStack # 4 ; top of stack of allocated handlers
+Work_HFree # 4 ; head of free-list
+Work_RSave # 9*4 ; for R0-R8
+Work_LRSave # 4 ; saved lr
+Work_PCSave # 4 ; saved PC
+Work_PSRSave # 4 ; saved CPSR
+Work_ReturnHandlersArea EQU @ ; rest of this memory is treated as heap
+ ; space for the return handlers
+Work_MinSize EQU @ + 32 * RHandl_Size
+
+; Return handler. 1 is allocated per inter-segment procedure call
+; allocated and free lists of handlers are pointed to from HStack and HFree
+; offsets are prefixed with RHandl_
+ ^ 0
+RHandl_Branch # 4 ; BL load_seg_and_ret
+RHandl_RealLR # 4 ; space for the real return address
+RHandl_Segment # 4 ; -> PCIT section of segment to load
+RHandl_Link # 4 ; -> next in stack order
+RHandl_Size EQU @
+
+; set up by check_for_invalidated_returns.
+
+; PCITSection. 1 per segment stored in root segment, allocated by linker
+; offsets are prefixed with PCITSect_
+ ^ 0
+PCITSect_Vecsize # 4 ; .-4-EntryV ; size of entry vector
+PCITSect_Base # 4 ; used by load_segment; not initialised
+PCITSect_Limit # 4 ; used by load_segment; not initialised
+PCITSect_Name # 11 ; <11 bytes> ; 10-char segment name + NUL in 11 bytes
+PCITSect_Flags # 1 ; ...and a flag byte
+PCITSect_ClashSz # 4 ; PCITEnd-.-4 ; size of table following
+PCITSect_Clashes # 4 ; >table of pointers to clashing segments
+
+; Stack structure (all offsets are negative)
+; defined in procedure call standard
+; offsets are prefixed with Stack_
+ ^ 0
+Stack_SaveMask # -4
+Stack_LRReturn # -4
+Stack_SPReturn # -4
+Stack_FPReturn # -4
+
+; the code and private workspace area
+ AREA OverLayMgrArea, PIC, CODE , READONLY
+
+STRLR STR lr, [pc, #-8] ; a word that is to be matched in PCITs
+
+; Store 2 words which are the addresses of the start and end of the workspace
+WorkSpace DCD |Overlay$$Data$$Base|
+WorkSpaceEnd DCD |Overlay$$Data$$Limit|
+InitFlag DCD InitDoneFlag
+
+|Image$$overlay_init| ROUT
+; Initialise overlay manager.
+; In the AIF format this is is called from offset 8 in header. This routine has
+; to pass control to the zero initialisation code.
+; In Non AIF formats this routine has to be called explicitly e.g. from
+; a customised rtstand.s .
+;
+; In the AIF example the entire root segment is copied to the load address.
+;
+; In the non AIF example only the RW part of the root is copied.
+;
+ LDR ip,WorkSpace
+ IF :DEF:AIF_EXAMPLE
+ STR lr,[ip,#Work_LRSave]
+
+ ADD ip,ip,#Work_RSave
+ STMIA ip,{r0-r3}
+
+;
+; Look at the AIF header and add compute the total size of the AIF header
+;
+ SUB r1,lr,#0xC
+
+ LDR r0,[r1,#0x28]
+
+ LDR r2,[r1,#0x14]
+ LDR r3,[r1,#0x18]
+ ADD r2,r2,r3
+ LDR r3,[r1,#0x1C]
+ ADD r2,r2,r3
+
+;
+; A system specific Memory Copy call. r0 is the destination area.
+; r1 is the source area.
+; r2 is the block size in bytes.
+;
+ BL MemCopy
+ LDR ip,WorkSpace
+ LDR lr,[ip,#Work_LRSave]
+ ADD ip,ip,#Work_RSave
+ SUB lr,lr,#12
+ LDR lr,[lr,#0x28]
+ ADD lr,lr,#12
+ LDMIA ip,{r0-r3}
+;
+; Return to the Zero Initialisation Code in the AIF header.
+;
+ ADD pc,lr,#ZeroInitCodeOffset-12
+ ELSE
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+ STMIA ip,{r0-r2,lr}
+
+ LDR r0,=|Image$$RW$$Base|
+ LDR r1,=|Image$$RO$$Limit|
+ LDR r2,=|Image$$ZI$$Limit|
+ SUB r2,r2,r1
+ BL MemCopy
+
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+ LDMIA ip,{r0-r2,PC}
+ ENDIF
+
+ DCD 0 ; Not needed for a real system but needed when using ARMSD
+ ; is used to simulate a ROM based system.
+; entry point
+
+|Image$$load_seg| ROUT
+;
+; called when segment has been called but is not loaded
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+ MRS r4, CPSR ; Save status register -it'll get stored in the
+ ; workspace later.
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r0, InitFlag
+ LDRB r1, [r0]
+ CMP r1, #0
+ BNE InitDone
+
+;Initialise Return Handlers on first call to this routine
+ MOV r1, #1
+ STRB r1, [r0] ; set InitDone flag
+ LDR r0, WorkSpace
+; r0 points to workspace
+; corrupts r0-r3,lr
+; create and initialise return handler linked list
+ MOV r2, #0
+ STR r2, [r0, #Work_HStack] ; initialise start of handler list with NULL
+ ADD r1, r0, #Work_ReturnHandlersArea ; Start of heap space
+ STR r1, [r0, #Work_HFree] ; Start of list of free handlers point to heap space
+ LDR r0, WorkSpaceEnd ; for test in loop to make sure..
+ SUBS r0, r0, #RHandl_Size ; ..I dont overrun in init
+01 ADD r3, r1, #RHandl_Size ; next handler
+; set up link to point to next handler (in fact consecutive locations)
+ STR r3, [r1, #RHandl_Link]
+ MOV r1, r3 ; next handler
+ CMP r1, r0 ; test for end of workspace
+ BLT %BT01
+ SUB r1, r1, #RHandl_Size ; previous handler
+ STR r2, [r1, #RHandl_Link] ; NULL-terminate list
+
+InitDone
+ LDR r3, WorkSpace
+ STR r4, [r3, #Work_PSRSave] ; CPSR read into R4 before the InitDone
+ ; test.
+ MOV r8,lr ;
+ LDR r0, [r8, #-8] ; saved r14... (is end of PCIT)
+ STR r0, [r3, #Work_LRSave] ; ...save it here ready for retry
+ LDR r0, STRLR ; look for this...
+ SUB r1, r8, #8 ; ... starting at last overwrite
+01 LDR r2, [r1, #-4]!
+ CMP r2, r0 ; must stop on guard word...
+ BNE %B01
+ ADD r1, r1, #4 ; gone one too far...
+ STR r1, [r3, #Work_PCSave] ; where to resume at
+
+load_segment
+
+; ip -> the register save area; r8 -> the PCIT section of the segment to load.
+; First re-initialise the PCIT section (if any) which clashes with this one...
+
+ ADD r1, r8, #PCITSect_Clashes
+ LDR r0, [r8, #PCITSect_ClashSz]
+01 SUBS r0, r0, #4
+ BLT Done_Reinit ; nothing left to do
+ LDR r7, [r1], #4 ; a clashing segment...
+ LDRB r2, [r7, #PCITSect_Flags] ; its flags (0 if unloaded)
+ CMPS r2, #0 ; is it loaded?
+ BEQ %B01 ; no, so look again
+
+; clashing segment is loaded (clearly, there can only be 1 such segment)
+; mark it as unloaded and reinitialise its PCIT
+; r7 -> PCITSection of clashing loaded segment
+
+ MOV r0, #0
+ STRB r0, [r7, #PCITSect_Flags] ; mark as unloaded
+ LDR r0, [r7, #PCITSect_Vecsize]
+ SUB r1, r7, #4 ; end of vector
+ LDR r2, STRLR ; init value to store in the vector...
+02 STR r2, [r1, #-4]! ;>
+ SUBS r0, r0, #4 ;> loop to initialise the PCIT segment
+ BGT %B02 ;>
+; Now we check the chain of call frames on the stack for return addresses
+
+; which have been invalidated by loading this segment and install handlers
+; for each invalidated return.
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+
+ BL check_for_invalidated_returns
+Done_Reinit
+
+; All segment clashes have now been dealt with, as have the re-setting
+; of the segment-loaded flags and the intercepting of invalidated returns.
+; So, now load the required segment.
+
+Retry
+;
+; Call a routine to load the overlay segment.
+; First parameter is the length of the segment name.
+; The second parameter is the address of the segment name
+; The third parameter is the base address of the segement.
+; The routine returns the segment length in r0.
+;
+ MOV r0,#12
+ ADD r1, r8, #PCITSect_Name
+ LDR r2, [ r8, #PCITSect_Base]
+ BL LoadOverlaySegment
+
+ TEQ r0,#0
+ MOVEQ r0,#2
+ BEQ SevereErrorHandler
+
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+;
+; Mark the segment as loaded.
+;
+ MOV r1,#1
+ STRB r1, [r8, #PCITSect_Flags]
+
+ LDR r2, [r8, #PCITSect_Base]
+ ADD r0, r2, r0 ; start + length = end of file
+
+; The segment's entry vector is at the end of the segment...
+; ...copy it to the PCIT section identified by r8.
+
+ LDR r1, [r8, #PCITSect_Vecsize]
+ SUB r3, r8, #8 ; end of entry vector...
+ MOV r4, #0 ; for data initialisation
+01 LDR r2, [r0, #-4]! ;>loop to copy
+ STR r4, [r0] ; (zero-init possible data section)
+ STR r2, [r3], #-4 ;>the segment's PCIT
+ SUBS r1, r1, #4 ;>section into the
+ BGT %B01 ;>global PCIT
+
+; Finally, continue, unabashed...
+
+ LDR r3, WorkSpace
+ LDR r3, [r3,#Work_PSRSave]
+ MSR CPSR,r3
+
+ LDMIA ip, {r0-r8, lr, pc}
+
+load_seg_and_ret
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r3, WorkSpace
+ MRS r8, CPSR
+ STR r8, [r3, #Work_PSRSave]
+
+; lr points to the return handler
+ MOV r8, lr
+ ; load return handler fields RealLR, Segment, Link
+ LDMIA r8, {r0, r1, r2}
+ SUB r8, r8, #4 ; point to true start of return handler before BL
+ STR r0, [r3, #Work_LRSave]
+ STR r0, [r3, #Work_PCSave]
+; Now unchain the handler and return it to the free pool
+; HStack points to this handler
+ LDR r0, [r3, #Work_HStack]
+ CMPS r0, r8
+ MOVNE r0, #1
+ BNE SevereErrorHandler
+ STR r2, [r3, #Work_HStack] ; new top of handler stack
+ LDR r2, [r3, #Work_HFree]
+ STR r2, [r8, #RHandl_Link] ; Link -> old HFree
+ STR r8, [r3, #Work_HFree] ; new free list
+ MOV r8, r1 ; segment to load
+ B load_segment
+
+check_for_invalidated_returns
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+; Note: check for returns invalidated by a call NOT for returns invalidated by
+; a return! In the 2nd case, the saved LR and saved PC are identical.
+ LDR r5, WorkSpace
+ ADD r6, r5, #Work_LRSave ; 1st location to check
+ LDMIA r6, {r0, r1} ; saved LR & PC
+ CMPS r0, r1
+ MOVEQ pc, lr ; identical => returning...
+ MOV r0, fp ; temporary FP...
+01 LDR r1, [r6] ; the saved return address...
+ LDR r2, [r5, #Work_HStack] ; top of handler stack
+ CMPS r1, r2 ; found the most recent handler, so
+ MOVEQ pc, lr ; abort the search
+ LDR r2, [r7, #PCITSect_Base]
+ CMPS r1, r2 ; see if >= base...
+ BLT %F02
+ LDR r2, [r7, #PCITSect_Limit]
+ CMPS r1, r2 ; ...and < limit ?
+ BLT FoundClash
+02 CMPS r0, #0 ; bottom of stack?
+ MOVEQ pc, lr ; yes => return
+ ADD r6, r0, #Stack_LRReturn
+ LDR r0, [r0, #Stack_FPReturn] ; previous FP
+ B %B01
+FoundClash
+ LDR r0, [r5, #Work_HFree] ; head of chain of free handlers
+ CMPS r0, #0
+ MOVEQ r0, #2
+ BEQ SevereErrorHandler
+; Transfer the next free handler to head of the handler stack.
+ LDR r1, [r0, #RHandl_Link] ; next free handler
+ STR r1, [r5, #Work_HFree]
+ LDR r1, [r5, #Work_HStack] ; the active handler stack
+ STR r1, [r0, #RHandl_Link]
+ STR r0, [r5, #Work_HStack] ; now with the latest handler linked in
+; Initialise the handler with a BL load_seg_and_ret, RealLR and Segment.
+ ADR r1, load_seg_and_ret
+ SUB r1, r1, r0 ; byte offset for BL in handler
+ SUB r1, r1, #8 ; correct for PC off by 8
+ MOV r1, r1, ASR #2 ; word offset
+ BIC r1, r1, #&FF000000
+ ORR r1, r1, #&EB000000 ; code for BL
+ STR r1, [r0, #RHandl_Branch]
+
+ LDR r1, [r6] ; LRReturn on stack
+ STR r1, [r0, #RHandl_RealLR] ; RealLR
+ STR r0, [r6] ; patch stack to return to handler
+
+ STR r7, [r0, #RHandl_Segment] ; segment to re-load on return
+ MOVS pc, lr ; and return
+
+ AREA OverlayInit, DATA
+InitDoneFlag DCD 0
+
+ END
+Appendix B
+----------
+main.c
+------
+
+#include <stdio.h>
+#include <string.h>
+#define INBUFFSIZE 192
+#define OUTBUFFSIZE 257
+
+static char inBuff[INBUFFSIZE];
+static char outBuff[OUTBUFFSIZE];
+static int charCount=0;
+
+extern int getData(char *,int);
+extern int uuencode(char *, char *, int);
+extern int _sys_flen(int );
+extern int _sys_open(char *,int );
+extern int _sys_read(int, void *, int, int );
+extern int _sys_close(int);
+
+int main(int argc,char **argv)
+{
+ int uuCount;
+ charCount = getData(inBuff,sizeof(inBuff));
+ if (charCount<0) {
+ fprintf(stderr,"Error reading data.\n");
+ }
+ else {
+ uuCount=uuencode(inBuff,outBuff,charCount);
+ outBuff[uuCount]='\0';
+ puts(outBuff);
+ }
+ return 0;
+}
+
+void MemCopy(void *d,void *s,int c)
+{
+ memmove(d,s,c);
+}
+
+int LoadOverlaySegment(int nameLen,char *name,void *baseAdr)
+{
+ char name0[16];
+ int length;
+ int fh;
+
+ memmove(name0,name,nameLen);
+ name0[nameLen]='\0';
+#define OPEN_B 1
+#define OPEN_R 0
+
+ fh = _sys_open(name0,OPEN_B|OPEN_R);
+ if (fh==0) return 0;
+ length = _sys_flen(fh);
+ (void)_sys_read(fh,baseAdr,length,0);
+ (void)_sys_close(fh);
+ return length;
+}
+
+getdata.c
+---------
+#include <stdio.h>
+
+int getData(char *buffer,int length)
+{
+ int charsIn;
+ int charRead;
+ charsIn=0;
+ for (charsIn=0;charsIn<length;) {
+ charRead=getchar();
+ if (charRead == EOF) break;
+ buffer[charsIn++]=charRead;
+ if (charRead == '\n' ) break;
+ }
+ for (;(charsIn%3)!=0; ) buffer[charsIn++]='\0';
+ return charsIn;
+}
+
+uue.c
+-----
+/*
+ A simple routine to UUENCODE a buffer. It does not split up the
+ uuencoded data into lines and append encode count bytes though.
+ It assumes that the input buffer is an integer multiple of 3 bytes long.
+ The number of bytes written to the output buffer is returned.
+*/
+unsigned int uuencode(unsigned char *in,unsigned char *out,unsigned int count)
+{
+ unsigned char t0;
+ unsigned char t1;
+ unsigned char t2;
+ unsigned int result=0;
+ for (;count;count-=3,in+=3,out+=4,result+=4) {
+ t0=in[0];
+ *out=' '+(t0>>2);
+ t1=in[1];
+ out[1]=' '+((t0<<4)&0x30)+(t1>>4);
+ t2=in[2];
+ out[2]=' '+((t1<<2)&0x3C)+ (t2>>6);
+ out[3]=' '+(t2&0x3F);
+ }
+ return result;
+}
+
+maininit.s
+----------
+ AREA MainWithOverlayInit, CODE, READONLY
+ IMPORT |Image$$overlay_init|
+ IMPORT __main
+
+ ENTRY
+ BL |Image$$overlay_init|
+ BL __main
+ END
+
+
+Makefile
+--------
+
+LIB=
+
+.c.o:
+ armcc -bi -c -APCS 3/32/noswst $<
+
+.s.o:
+ armasm -bi -APCS 3/32/noswst $<
+
+all: ov/root
+
+ov/root: main.o uue.o getdata.o overmgr.o maininit.o startup.o
+ armlink -bin -base 0x40000 -data 0x10000 -ov ovlist \
+ -o ov maininit.o startup.o main.o overmgr.o uue.o getdata.o \
+ -FIRST maininit.o ${LIB}/armlib.32b -map -symbols - -list tS.map \
+ -v
+
+startup.o: startup.s
+
+overmgr.o: overmgr.s
+
+maininit.o: maininit.s
+
+main.o: main.c
+
+uue.o: uue.c
+
+getdata.o: getdata.c
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/UUE.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/UUE.C
new file mode 100644
index 0000000..fa06e2e
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/OVERLAY/UUE.C
@@ -0,0 +1,23 @@
+/*
+ A simple routine to UUENCODE a buffer. It does not split up the
+ uuencoded data into lines and append encode count bytes though.
+ It assumes that the input buffer is an integer multiple of 3 bytes long.
+ The number of bytes written to the output buffer is returned.
+*/
+unsigned int uuencode(unsigned char *in,unsigned char *out,unsigned int count)
+{
+ unsigned char t0;
+ unsigned char t1;
+ unsigned char t2;
+ unsigned int result=0;
+ for (;count;count-=3,in+=3,out+=4,result+=4) {
+ t0=in[0];
+ *out=' '+(t0>>2);
+ t1=in[1];
+ out[1]=' '+((t0<<4)&0x30)+(t1>>4);
+ t2=in[2];
+ out[2]=' '+((t1<<2)&0x3C)+ (t2>>6);
+ out[3]=' '+(t2&0x3F);
+ }
+ return result;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/PROGC/DSPDIV.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/PROGC/DSPDIV.C
new file mode 100644
index 0000000..c805d33
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/PROGC/DSPDIV.C
@@ -0,0 +1,18 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ if (argc != 3)
+ puts("needs 2 numeric args");
+ else
+ {
+ __sdiv32by16 result;
+
+ result = __rt_sdiv32by16(atoi(argv[1]), atoi(argv[2]));
+
+ printf("quotient %d\n", result.quot);
+ printf("remainder %d\n", result.rem);
+ }
+ return 0;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/CONFIG.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/CONFIG.H
new file mode 100644
index 0000000..18f6fbf
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/CONFIG.H
@@ -0,0 +1,74 @@
+/*
+ * config.h - modified specially for reentrant strlib.
+ * Copyright (C) Advanced RISC Machines Limited 1994. All rights reserved.
+ */
+
+#define BYTESEX_EVEN 1 /* little-endian */
+/*#define BYTESEX_ODD 1 -- BIG-endian */
+
+/*
+ * Define this to get a shared library with an initialised data image in the
+ * library. Undefine it to get the data image in the library stub. Remember
+ * To modify strshl in step (the line containing + {}).
+ */
+#define DATA_IN_LIBRARY 1 /* needs +{} in strshl */
+
+#include "interns.h"
+
+#define memcpy_c
+#define memmove_c
+#define memchr_c
+#define memcmp_c
+#define memset_c
+#define strcat_c
+#define strchr_c
+#define strcmp_c
+#define strcoll_c
+#define strcpy_c
+#define strcspn_c
+#define strerror_c
+#define strlen_c
+#define strncat_c
+#define strncmp_c
+#define strncpy_c
+#define strpbrk_c
+#define strrchr_c
+#define strspn_c
+#define strstr_c
+#ifndef DATA_IN_LIBRARY
+#define strtok_c
+#endif
+#define strxfrm_c
+#define _strerror_c
+
+#include <string.h>
+
+static char *_hostos_error_string(unsigned int n, char *v)
+{ char *s = v;
+ int j;
+ strcpy(s, "unknown shared string-library error 0x");
+ s += strlen(s);
+ for (j = 0; j < 8; ++ j)
+ { *s++ = "0123456789ABCDEF"[n >> 28];
+ n <<= 4;
+ }
+ *s = 0;
+ return v;
+}
+
+
+#ifdef DATA_IN_LIBRARY
+
+static char *saves1 = NULL;
+
+char *strtok(char *s1, const char *s2)
+{ char *s0;
+ if (s1 == 0) s1 = (saves1 == NULL) ? "" : saves1; /* use saved pointer */
+ if (*(s1 += strspn(s1,s2)) == 0) s0 = 0; /* no tokens */
+ else { s0 = s1;
+ if (*(s1 += strcspn(s1,s2)) != 0) *s1++ = 0; /* insert 0 if nec */
+ }
+ return (saves1 = s1, s0);
+}
+
+#endif
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/DYNLINK.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/DYNLINK.S
new file mode 100644
index 0000000..571740a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/DYNLINK.S
@@ -0,0 +1,72 @@
+ AREA |DynamicLinker|, CODE, READONLY, REENTRANT
+
+ EXPORT |__rt_dynlink|
+
+|__rt_dynlink|
+; Enter from a call through the stub vector with r0-r6, lr saved on sp...
+; ip (the 'new sb' value) is the index of the proxy function in the stub
+; vector which caused this entry to the dynamic linker and identifies
+; which call to resume after linking.
+; On entry r0 points to the 4-word dynamic linker entry veneer at the
+; end of the stub vector.
+
+ MOV r6, r0
+ LDR r5, [r6, #-8] ; # entries - 1
+ ADD r5, r5, #1 ; # entries
+ MOV r4, ip ; resume index
+
+; r6+24 points to the EFT parameter block; call the library location function
+; to return a pointer to the matching library... Here we assume it's loaded
+; at 0x40000...
+
+; In the following line, the Makefile relies on a space after '#' and on the
+; contents of the comment. DO NOT CHANGE THESE OR Makefile WILL FAIL.
+
+ MOV r0, # 0x40000 ; EFT Address (DO NOT ALTER THIS COMMENT)
+
+; r0 now points to the EFT
+ LDR ip, [r0] ; #entries
+ CMPS ip, r5
+ BLT Botched ; not enough entries to init the stub
+
+ LDR ip, [r6, #16] ; stub data len
+ BIC ip, ip, #3 ; word aligned, I insist...
+ ADD r3, r0, #4
+ LDR r3, [r3, r5, LSL #2] ; library data len...
+ CMPS r3, ip
+ BNE Botched
+
+ LDR r3, [r6, #20] ; stub data dest
+ SUB r2, r0, ip ; library data src - precedes EFT
+01 SUBS ip, ip, #4 ; word by word copy loop
+ LDRGE r1, [r2], #4
+ STRGE r1, [r3], #4
+ BGE %B01
+
+ LDR ip, [r6, #12] ; length of the inter-LU data area
+ ADD r3, r6, #24 ; end of the inter-LU data area...
+ SUB r3, r3, ip ; sb = start of inter-LU data area
+
+ LDR r2, [r6, #-8]! ; index of stub entry
+00 SUB ip, r5, #1 ; index of the lib entry
+ CMPS ip, r2 ; is this lib entry in the stub?
+ SUBGT r5, r5, #1 ; no, skip it
+ BGT %B00
+ CMPS r2, r4 ; found the retry index?
+ MOVEQ lr, r6 ; yes: remember it
+ LDR ip, [r0, r5, lsl #2] ; entry point offset
+ ADD ip, ip, r0 ; entry point address
+ STMIA r6, {r3, ip} ; save {sb, pc}
+ LDR r2, [r6, #-8]! ; load index and decrement r6...
+ TST r2, #&ff000000 ; ... or if loaded instruction?
+ LDRNE r2, [r6, #-8]! ; load index and decrement r6 if instr
+ SUBS r5, r5, #1
+ BGT %B00
+
+ MOV ip, lr ; retry address
+ LDMFD sp!, {r0-r6, lr} ; restore saved regs
+ LDMIA ip, {ip, pc} ; and retry the call
+
+Botched B Botched
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/INTERNS.H b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/INTERNS.H
new file mode 100644
index 0000000..3a3fd1a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/INTERNS.H
@@ -0,0 +1,12 @@
+/*
+ * Dummy interns.h sufficient to compile strlib.
+ * Copyright (C) Advanced RISC Machines Limited 1994. All rights reserved.
+ */
+
+#ifndef __internals_h
+#define __internals_h
+
+extern char *_strerror(int n, char *v);
+extern void __set_strcoll_table(const unsigned char *table);
+
+#endif
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAIN.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAIN.S
new file mode 100644
index 0000000..552f24d
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAIN.S
@@ -0,0 +1,26 @@
+ EXPORT __main
+ IMPORT main
+ IMPORT |sb$$interLUdata$$Base|
+
+SWI_GetEnv * &10
+SWI_Exit * &11
+
+ AREA |StartupCode|, CODE, READONLY, REENTRANT
+
+;
+; This is the initial entry point to the image.
+; (The compiler ensures it is linked in to the image by generating a reference
+; to __main from the object module generated from compiling a file containing
+; an extern main()).
+ ENTRY
+
+; We have to establish a stack for C, initialise the library, then call _main
+; (which will set up the arguments for main, then call it).
+|__main|
+ LDR r9, =|sb$$interLUdata$$Base|
+ SWI SWI_GetEnv ; to decide heap limit
+ MOV r13, r1 ; top of program workspace
+ BL |main|
+ SWI SWI_Exit
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAKEFILE b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAKEFILE
new file mode 100644
index 0000000..e51ed42
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/MAKEFILE
@@ -0,0 +1,101 @@
+# Copyright (C) Advanced RISC Machines Limited 1994. All rights reserved.
+# Makefile for shared string library (reentrant APCS) example.
+
+CLIBSRC=../../cl
+CC=armcc
+LD=armlink
+AS=armasm
+SD=armsd
+
+# If you change -li below and in the $(SD) command later, you MUST change
+# config.h to #define BYTESEX_ODD, not BYTESEX_EVEN. This Makefile and all
+# the sources it uses assume little-endian operation.
+
+RCFLAGS=-li -apcs 3/32bit/reent -zps1
+RAFLAGS=-li -apcs 3/32bit/reent
+
+.SILENT:
+
+all:
+ echo "Use 'make run' to run the test"
+ echo "Use 'make build' to build the test"
+ echo "Use 'make clean' to tidy up afterwards"
+
+# A armsd.ini file is used to load the shared string library so that its
+# EFT starts at 0x4000 (built in to dynlink.s - see below). You can alter
+# this provided you do so carefully...
+
+build: rstub.o strtest armsd.ini
+ echo "Now use 'make run' to run the test"
+
+run: strlib strtest armsd.ini
+ $(SD) -li strtest
+ echo "Now use 'make clean' to tidy up"
+
+clean:
+ rm -f armsd.ini map maplib strtest strlib *.o
+
+# Here we make a sharable library out of the ANSI C Library's string functions.
+# We make a reentrant stub for use with a reentrant client.
+
+rstub.o: string.o
+ echo Making strlib and rstub.o
+ echo "Please ignore (Warning) Attribute conflict"
+ echo ""
+ $(LD) -o rstub.o -reent -s - -shl strshl -map string.o > maplib
+ @echo Made strlib and a matching reentrant stub
+
+# The armsd.ini file instructs armsd to load the shared string library so its
+# EFT is located at the address assumed by dynlink.s. Here, we grep the
+# assumed address from dynlink.s and the EFT's offset from the library's
+# map file (maplib). We load the library at <address>-<EFT offset>.
+# eg.
+# armsd: getfile strlib 0x40000-0x0009c8
+# ^^^^^^^^ value of EFT$$Offset from maplib
+# armsd: go
+
+armsd.ini: dynlink.s maplib
+ echo Making $@
+ fgrep 'EFT Address' dynlink.s | \
+ awk '{printf "getfile strlib %s",$$4}' - > armsd.ini
+ fgrep 'EFT$$$$Offset' maplib | awk '{printf "-0x%s\n",$$2}' - >> armsd.ini
+
+# We use a local dummy copy of interns.h and a local copy of config.h which
+# patches around some deficiencies in the library sources prior to r1.6.2.
+
+string.o: $(CLIBSRC)/string.c interns.h config.h
+ echo Making $@
+ $(CC) $(RCFLAGS) -c -I. $(CLIBSRC)/string.c
+
+# Here we link the test program with:
+# - the dynamic linker (dynlink.o)
+# - the reentrant stub of the library
+# - a small piece of startup code which provides the same run-line
+# environment as a fully reentrant, shared C library kernel would provide.
+
+strtest: strtest.o dynlink.o main.o
+ echo Making $@
+ echo "Please ignore (Waring) Attribute conflict"
+ echo ""
+ $(LD) -d -o strtest strtest.o dynlink.o rstub.o main.o -map > map
+
+strtest.o: strtest.c
+ echo Making $@
+ $(CC) $(RCFLAGS) -c strtest.c
+
+dynlink.o: dynlink.s
+ echo Making $@
+ $(AS) $(RAFLAGS) dynlink.s dynlink.o
+
+main.o: main.s
+ echo Making $@
+ $(AS) $(RAFLAGS) main.s main.o
+
+# Null dependencies
+
+maplib: rstub.o
+
+strlib: rstub.o
+
+dynlink.s:
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSHL b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSHL
new file mode 100644
index 0000000..3eee490
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSHL
@@ -0,0 +1,34 @@
+> strlib \
+ 0x40000
+
+; Include an image of the initialised data in the library itself.
+; Dynlink will copy this at run time to a zero-initialised area
+; reserved by the stub.
+
++()
+
+; Functions exported from the sharable string library
+
+memcpy
+memmove
+memchr
+memcmp
+strcat
+strchr
+strcmp
+strcoll
+__set_strcoll_table
+strcpy
+strcspn
+strerror
+_strerror
+strlen
+strncat
+strncmp
+strncpy
+strpbrk
+strrchr
+strspn
+strstr
+strtok
+strxfrm
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSTUB.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSTUB.APJ
new file mode 100644
index 0000000..95d64b1
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRSTUB.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.APJ
new file mode 100644
index 0000000..93109e2
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.C
new file mode 100644
index 0000000..a2ee0a3
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/REENT/STRTEST.C
@@ -0,0 +1,18 @@
+extern char *strerror(int);
+
+__swi(0) void writec(int);
+
+
+static void puts(char *s)
+{ int ch;
+ for (ch = *s; ch != 0; ch = *++s) writec(ch);
+}
+
+int main()
+{
+ puts("\nstrerror(42) returns \"");
+ puts(strerror(42));
+ puts("\"\n\r\n");
+
+ return 0;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C
new file mode 100644
index 0000000..4430177
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/EX.C
@@ -0,0 +1,52 @@
+/* We use the following Debug Monitor SWIs to write things out
+ * in this example
+ */
+extern __swi(0) WriteC(char c); /* Write a character */
+extern __swi(2) Write0(char *s); /* Write a string */
+
+/* The following symbols are defined by the linker and define
+ * various memory regions which may need to be copied or initialised
+ */
+extern char Image$$RO$$Limit[];
+extern char Image$$RW$$Base[];
+
+
+/* We define some more meaningfull names here */
+#define rom_data_base Image$$RO$$Limit
+#define ram_data_base Image$$RW$$Base
+
+/* This is an example of a pre-initialised variable. */
+static unsigned factory_id = 0xAA55AA55; /* Factory set ID */
+
+/* This is an example of an uninitialised (or 0 initialised) variable */
+static char display[8][40]; /* Screen buffer */
+
+static const char hex[16] = "0123456789ABCDEF";
+
+static void pr_hex(unsigned n)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ WriteC(hex[n >> 28]);
+ n <<= 4;
+ }
+}
+
+void C_Entry(void)
+{
+ if (rom_data_base == ram_data_base) {
+ Write0("Warning: Image has been linked as an application. To link as a ROM image\r\n");
+ Write0(" link with the options -RO <rom-base> -RW <ram-base>\r\n");
+ }
+
+ Write0("'factory_id' is at address ");
+ pr_hex((unsigned)&factory_id);
+ Write0(", contents = ");
+ pr_hex((unsigned)factory_id);
+ Write0("\r\n");
+
+ Write0("'display' is at address ");
+ pr_hex((unsigned)display);
+ Write0("\r\n");
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S
new file mode 100644
index 0000000..3786ac7
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S
@@ -0,0 +1,164 @@
+;
+; The AREA must have the attribute READONLY, otherwise the linker will not
+; place it in ROM.
+;
+; The AREA must have the attribute CODE, otherwise the assembler will not
+; let us put any code in this AREA
+;
+; Note the '|' character is used to surround any symbols which contain
+; non standard characters like '!'.
+
+ AREA Init, CODE, READONLY
+
+; Now some standard definitions...
+
+Mode_IRQ EQU 0x12
+Mode_SVC EQU 0x13
+
+I_Bit EQU 0x80
+F_Bit EQU 0x40
+
+SWI_Exit EQU 0x11
+
+; Locations of various things in our memory system
+
+RAM_Base EQU 0x10000000 ; 64k RAM at this base
+RAM_Limit EQU 0x10010000
+
+IRQ_Stack EQU RAM_Limit ; 1K IRQ stack at top of memory
+SVC_Stack EQU RAM_Limit-1024 ; followed by SVC stack
+
+; --- Define __main & set entry point
+ ENTRY
+
+; --- Setup interrupt / exception vectors
+ IF :DEF: ROM_AT_ADDRESS_ZERO
+; If the ROM is at address 0 this is just a sequence of branches
+ B Reset_Handler
+ B Undefined_Handler
+ B SWI_Handler
+ B Prefetch_Handler
+ B Abort_Handler
+ NOP ; Reserved vector
+ B IRQ_Handler
+ B FIQ_Handler
+ ELSE
+; Otherwise we copy a sequence of LDR PC instructions over the vectors
+; (Note: We copy LDR PC instructions because branch instructions
+; could not simply be copied, the offset in the branch instruction
+; would have to be modified so that it branched into ROM. Also, a
+; branch instructions might not reach if the ROM is at an address
+; > 32M).
+ MOV R8, #0
+ ADR R9, Vector_Init_Block
+ LDMIA R9!, {R0-R7}
+ STMIA R8!, {R0-R7}
+ LDMIA R9!, {R0-R7}
+ STMIA R8!, {R0-R7}
+
+; Now fall into the LDR PC, Reset_Addr instruction which will continue
+; execution at 'Reset_Handler'
+
+Vector_Init_Block
+ LDR PC, Reset_Addr
+ LDR PC, Undefined_Addr
+ LDR PC, SWI_Addr
+ LDR PC, Prefetch_Addr
+ LDR PC, Abort_Addr
+ NOP
+ LDR PC, IRQ_Addr
+ LDR PC, FIQ_Addr
+
+Reset_Addr DCD Reset_Handler
+Undefined_Addr DCD Undefined_Handler
+SWI_Addr DCD SWI_Handler
+Prefetch_Addr DCD Prefetch_Handler
+Abort_Addr DCD Abort_Handler
+ DCD 0 ; Reserved vector
+IRQ_Addr DCD IRQ_Handler
+FIQ_Addr DCD FIQ_Handler
+ ENDIF
+
+; The following handlers do not do anything useful in this example.
+;
+Undefined_Handler
+ B Undefined_Handler
+SWI_Handler
+ B SWI_Handler
+Prefetch_Handler
+ B Prefetch_Handler
+Abort_Handler
+ B Abort_Handler
+IRQ_Handler
+ B IRQ_Handler
+FIQ_Handler
+ B FIQ_Handler
+
+; The RESET entry point
+Reset_Handler
+
+; --- Initialise stack pointer registers
+; Enter IRQ mode and set up the IRQ stack pointer
+ MOV R0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
+ MSR CPSR, R0
+ LDR R13, =IRQ_Stack
+
+; Set up other stack pointers if necessary
+ ; ...
+
+; Set up the SVC stack pointer last and return to SVC mode
+ MOV R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
+ MSR CPSR, R0
+ LDR R13, =SVC_Stack
+
+; --- Initialise memory system
+ ; ...
+
+; --- Initialise critical IO devices
+ ; ...
+
+; --- Initialise interrupt system variables here
+ ; ...
+
+; --- Enable interrupts
+; Now safe to enable interrupts, so do this and remain in SVC mode
+ MOV R0, #Mode_SVC:OR:F_Bit ; Only IRQ enabled
+ MSR CPSR, R0
+
+; --- Initialise memory required by C code
+
+ IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
+ IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
+ IMPORT |Image$$ZI$$Base| ; Base and limit of area
+ IMPORT |Image$$ZI$$Limit| ; to zero initialise
+
+ LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
+ LDR r1, =|Image$$RW$$Base| ; and RAM copy
+ LDR r3, =|Image$$ZI$$Base| ; Zero init base => top of initialised data
+ CMP r0, r1 ; Check that they are different
+ BEQ %1
+0 CMP r1, r3 ; Copy init data
+ LDRCC r2, [r0], #4
+ STRCC r2, [r1], #4
+ BCC %0
+1 LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment
+ MOV r2, #0
+2 CMP r3, r1 ; Zero init
+ STRCC r2, [r3], #4
+ BCC %2
+
+; --- Now we enter the C code
+
+ IMPORT C_Entry
+ [ :DEF:THUMB
+ ORR lr, pc, #1
+ BX lr
+ CODE16 ; Next instruction will be Thumb
+ ]
+ BL C_Entry
+; In a real application we wouldn't normally expect to return, however
+; this example does so the debug monitor swi SWI_Exit is used to halt the
+; application.
+ SWI SWI_Exit
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C
new file mode 100644
index 0000000..6a5d4c9
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/SPRINTF.C
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+/* We use the following Debug Monitor SWIs to write things out
+ * in this example
+ */
+extern __swi(2) Write0(char *s); /* Write a string */
+
+/* The following symbols are defined by the linker and define
+ * various memory regions which may need to be copied or initialised
+ */
+extern char Image$$RO$$Base[];
+extern char Image$$RO$$Limit[];
+extern char Image$$RW$$Base[];
+
+/* We define some more meaningful names here */
+#define rom_code_base Image$$RO$$Base
+#define rom_data_base Image$$RO$$Limit
+#define ram_data_base Image$$RW$$Base
+
+void C_Entry(void)
+{
+ char s[80];
+
+ if (rom_data_base == ram_data_base) {
+ Write0("Warning: Image has been linked as an application. To link as a ROM image\r\n");
+ Write0(" link with the options -RO <rom-base> -RW <ram-base>\r\n");
+ }
+
+ sprintf(s, "ROM is at address %p, RAM is at address %p\n", rom_code_base, ram_data_base);
+ Write0(s);
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/ARMSD.OB b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/ARMSD.OB
new file mode 100644
index 0000000..c15049e
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/ARMSD.OB
@@ -0,0 +1,3 @@
+get app/root 0x80000
+get app/copydata 0x84800
+let pc=0x80000
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/GETDATA.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/GETDATA.C
new file mode 100644
index 0000000..20f3c90
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/GETDATA.C
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int getData(char *buffer,int length)
+{
+ int charsIn;
+ int charRead;
+ charsIn=0;
+ for (charsIn=0;charsIn<length;) {
+ charRead=getchar();
+ if (charRead == EOF) break;
+ buffer[charsIn++]=charRead;
+ if (charRead == '\n' ) break;
+ }
+ for (;(charsIn%3)!=0; ) buffer[charsIn++]='\0';
+ return charsIn;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/INITAPP.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/INITAPP.S
new file mode 100644
index 0000000..1bdbaea
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/INITAPP.S
@@ -0,0 +1,81 @@
+ AREA InitApp, CODE , READONLY
+ EXPORT InitialiseApp
+InitialiseApp
+ ADR r0,ziTable
+ MOV R3,#0
+ziLoop
+ LDR r1,[r0],#4
+ CMP r1,#0
+ BEQ initLoop
+ LDR r2,[r0],#4
+ziFillLoop
+ STR r3,[r2],#4
+ SUBS r1,r1,#4
+ BNE ziFillLoop
+ B ziLoop
+
+initLoop
+ LDR r1,[r0],#4
+ CMP r1,#0
+ MOVEQ pc,lr
+ LDMIA r0!,{r2,r3}
+ CMP r1,#16
+ BLT copyWords
+copy4Words
+ LDMIA r3!,{r4,r5,r6,r7}
+ STMIA r2!,{r4,r5,r6,r7}
+ SUBS r1,r1,#16
+ BGT copy4Words
+ BEQ initLoop
+copyWords
+ SUBS r1,r1,#8
+ LDMIAGE r3!,{r4,r5}
+ STMIAGE r2!,{r4,r5}
+ BEQ initLoop
+
+ LDR r4,[r3]
+ STR r4,[r2]
+
+ B initLoop
+
+ MACRO
+ ZIEntry $execname
+ LCLS lensym
+ LCLS basesym
+ LCLS namecp
+namecp SETS "$execname"
+lensym SETS "|Image$$":CC:namecp:CC:"$$ZI$$Length|"
+basesym SETS "|Image$$":CC:namecp:CC:"$$ZI$$Base|"
+ IMPORT $lensym
+ IMPORT $basesym
+ DCD $lensym
+ DCD $basesym
+ MEND
+
+ MACRO
+ InitEntry $execname
+ LCLS lensym
+ LCLS basesym
+ LCLS loadsym
+ LCLS namecp
+namecp SETS "$execname"
+lensym SETS "|Image$$":CC:namecp:CC:"$$Length|"
+basesym SETS "|Image$$":CC:namecp:CC:"$$Base|"
+loadsym SETS "|Load$$":CC:namecp:CC:"$$Base|"
+ IMPORT $lensym
+ IMPORT $basesym
+ IMPORT $loadsym
+ DCD $lensym
+ DCD $basesym
+ DCD $loadsym
+ MEND
+
+ziTable
+ ZIEntry root
+ DCD 0
+
+InitTable
+ InitEntry root
+ InitEntry overmgr
+ DCD 0
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAIN.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAIN.C
new file mode 100644
index 0000000..7b90bc0
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAIN.C
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <string.h>
+#define INBUFFSIZE 192
+#define OUTBUFFSIZE 257
+
+static char IDstring[]="This is initailised data.";
+static char inBuff[INBUFFSIZE];
+static char outBuff[OUTBUFFSIZE];
+static int charCount=0;
+
+extern int getData(char *,int);
+extern int uuencode(char *, char *, int);
+
+int main(int argc,char **argv)
+{
+ int uuCount;
+ charCount = getData(inBuff,sizeof(inBuff));
+ if (charCount<0) {
+ fprintf(stderr,"Error reading data.\n");
+ }
+ else {
+ uuCount=uuencode(inBuff,outBuff,charCount);
+ outBuff[uuCount]='\0';
+ puts(outBuff);
+ }
+ return 0;
+}
+
+void MemCopy(void *d,void *s,int c)
+{
+ memmove(d,s,c);
+}
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAININIT.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAININIT.S
new file mode 100644
index 0000000..3fed52a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAININIT.S
@@ -0,0 +1,12 @@
+ AREA MainWithOverlayInit, CODE, READONLY
+ IMPORT |Image$$overlay_init|
+ IMPORT InitialiseApp
+ IMPORT __entry
+ EXPORT __main
+
+ ENTRY
+__main
+ BL InitialiseApp
+ BL |Image$$overlay_init|
+ BL __entry
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAKEFILE b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAKEFILE
new file mode 100644
index 0000000..6dadf7a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/MAKEFILE
@@ -0,0 +1,29 @@
+CC=/xdevt/rel200/gccsunos/armcc -bi -c
+LD= /xdevt/rel200/gccsunos/armlink
+LIB=/xdevt/rel200/lib/armlib.32b
+
+.c.o:
+ $(CC) -APCS 3/32/noswst $<
+
+all: app/root
+
+app/root: main.o uue.o getdata.o overmgrs.o initapp.o maininit.o
+ $(LD) -bin -scatter scatdes -o app maininit.o main.o overmgrs.o uue.o \
+ getdata.o initapp.o $(LIB) -map -symbols - -first maininit.o \
+ -list tS.map -v
+
+maininit.o: maininit.s
+ armasm -bi -APCS 3/32/noswst maininit.s
+
+initapp.o: initapp.s
+ armasm -bi -APCS 3/32/noswst initapp.s
+
+overmgrs.o: overmgrs.s
+ armasm -bi -APCS 3/32/noswst overmgrs.s
+
+main.o: main.c
+
+uue.o: uue.c
+
+getdata.o: getdata.c
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/OVERMGRS.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/OVERMGRS.S
new file mode 100644
index 0000000..c9504a0
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/OVERMGRS.S
@@ -0,0 +1,326 @@
+
+;;; Copyright (C) Advanced RISC Machines Ltd., 1991
+;;
+;; For use with a scatter loaded application with embedded overlays.
+
+ EXPORT |Image$$overlay_init|
+ EXPORT |Image$$load_seg|
+
+; pointers to start and end of workspace area supplied by the linker
+ IMPORT |Overlay$$Data$$Base|
+ IMPORT |Overlay$$Data$$Limit|
+ IMPORT |Root$$OverlayTable|
+ IMPORT MemCopy
+ IMPORT SevereErrorHandler, WEAK
+
+ZeroInitCodeOffset EQU 64
+
+; Layout of workspace allocated by the linker pointed to by Overlay$$Data
+; This area is automatically zero-initialised AFTER overlay_init is called
+; offsets are prefixed with Work_
+ ^ 0
+Work_HStack # 4 ; top of stack of allocated handlers
+Work_HFree # 4 ; head of free-list
+Work_RSave # 9*4 ; for R0-R8
+Work_LRSave # 4 ; saved lr
+Work_PCSave # 4 ; saved PC
+Work_PSRSave # 4 ; saved CPSR
+Work_ReturnHandlersArea EQU @ ; rest of this memory is treated as heap
+ ; space for the return handlers
+Work_MinSize EQU @ + 32 * RHandl_Size
+
+; Return handler. 1 is allocated per inter-segment procedure call
+; allocated and free lists of handlers are pointed to from HStack and HFree
+; offsets are prefixed with RHandl_
+ ^ 0
+RHandl_Branch # 4 ; BL load_seg_and_ret
+RHandl_RealLR # 4 ; space for the real return address
+RHandl_Segment # 4 ; -> PCIT section of segment to load
+RHandl_Link # 4 ; -> next in stack order
+RHandl_Size EQU @
+
+; set up by check_for_invalidated_returns.
+
+; PCITSection. 1 per segment stored in root segment, allocated by linker
+; offsets are prefixed with PCITSect_
+ ^ 0
+PCITSect_Vecsize # 4 ; .-4-EntryV ; size of entry vector
+PCITSect_Base # 4 ; used by load_segment; not initialised
+PCITSect_Limit # 4 ; used by load_segment; not initialised
+PCITSect_Name # 11 ; <11 bytes> ; 10-char segment name + NUL in 11 bytes
+PCITSect_Flags # 1 ; ...and a flag byte
+PCITSect_ClashSz # 4 ; PCITEnd-.-4 ; size of table following
+PCITSect_Clashes # 4 ; >table of pointers to clashing segments
+
+; Stack structure (all offsets are negative)
+; defined in procedure call standard
+; offsets are prefixed with Stack_
+ ^ 0
+Stack_SaveMask # -4
+Stack_LRReturn # -4
+Stack_SPReturn # -4
+Stack_FPReturn # -4
+
+; the code and private workspace area
+ AREA OverLayMgrArea, PIC, CODE , READONLY
+
+STRLR STR lr, [pc, #-8] ; a word that is to be matched in PCITs
+
+; Store 2 words which are the addresses of the start and end of the workspace
+WorkSpace DCD |Overlay$$Data$$Base|
+WorkSpaceEnd DCD |Overlay$$Data$$Limit|
+InitFlag DCD InitDoneFlag
+
+|Image$$overlay_init| ROUT
+; Initialise overlay manager.
+; In the AIF format this is is called from offset 8 in header. This routine has
+; to pass control to the zero initialisation code.
+; In Non AIF formats this routine has to be called explicitly e.g. from
+; a customised rtstand.s .
+;
+; In the AIF example the entire root segment is copied to the load address.
+;
+; In the non AIF example only the RW part of the root is copied.
+;
+ MOV pc,lr
+
+ DCD 0 ; Not needed for a real system but needed when using ARMSD
+ ; is used to simulate a ROM based system.
+; entry point
+
+|Image$$load_seg| ROUT
+;
+; called when segment has been called but is not loaded
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+ MRS r4, CPSR ; Save status register -it'll get stored in the
+ ; workspace later.
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r0, InitFlag
+ LDRB r1, [r0]
+ CMP r1, #0
+ BNE InitDone
+
+;Initialise Return Handlers on first call to this routine
+ MOV r1, #1
+ STRB r1, [r0] ; set InitDone flag
+ LDR r0, WorkSpace
+; r0 points to workspace
+; corrupts r0-r3,lr
+; create and initialise return handler linked list
+ MOV r2, #0
+ STR r2, [r0, #Work_HStack] ; initialise start of handler list with NULL
+ ADD r1, r0, #Work_ReturnHandlersArea ; Start of heap space
+ STR r1, [r0, #Work_HFree] ; Start of list of free handlers point to heap space
+ LDR r0, WorkSpaceEnd ; for test in loop to make sure..
+ SUBS r0, r0, #RHandl_Size ; ..I dont overrun in init
+01 ADD r3, r1, #RHandl_Size ; next handler
+; set up link to point to next handler (in fact consecutive locations)
+ STR r3, [r1, #RHandl_Link]
+ MOV r1, r3 ; next handler
+ CMP r1, r0 ; test for end of workspace
+ BLT %BT01
+ SUB r1, r1, #RHandl_Size ; previous handler
+ STR r2, [r1, #RHandl_Link] ; NULL-terminate list
+
+InitDone
+ LDR r3, WorkSpace
+ STR r4, [r3, #Work_PSRSave] ; CPSR read into R4 before the InitDone
+ ; test.
+ MOV r8,lr ;
+ LDR r0, [r8, #-8] ; saved r14... (is end of PCIT)
+ STR r0, [r3, #Work_LRSave] ; ...save it here ready for retry
+ LDR r0, STRLR ; look for this...
+ SUB r1, r8, #8 ; ... starting at last overwrite
+01 LDR r2, [r1, #-4]!
+ CMP r2, r0 ; must stop on guard word...
+ BNE %B01
+ ADD r1, r1, #4 ; gone one too far...
+ STR r1, [r3, #Work_PCSave] ; where to resume at
+
+load_segment
+
+; ip -> the register save area; r8 -> the PCIT section of the segment to load.
+; First re-initialise the PCIT section (if any) which clashes with this one...
+
+ ADD r1, r8, #PCITSect_Clashes
+ LDR r0, [r8, #PCITSect_ClashSz]
+01 SUBS r0, r0, #4
+ BLT Done_Reinit ; nothing left to do
+ LDR r7, [r1], #4 ; a clashing segment...
+ LDRB r2, [r7, #PCITSect_Flags] ; its flags (0 if unloaded)
+ CMPS r2, #0 ; is it loaded?
+ BEQ %B01 ; no, so look again
+
+; clashing segment is loaded (clearly, there can only be 1 such segment)
+; mark it as unloaded and reinitialise its PCIT
+; r7 -> PCITSection of clashing loaded segment
+
+ MOV r0, #0
+ STRB r0, [r7, #PCITSect_Flags] ; mark as unloaded
+ LDR r0, [r7, #PCITSect_Vecsize]
+ SUB r1, r7, #4 ; end of vector
+ LDR r2, STRLR ; init value to store in the vector...
+02 STR r2, [r1, #-4]! ;>
+ SUBS r0, r0, #4 ;> loop to initialise the PCIT segment
+ BGT %B02 ;>
+; Now we check the chain of call frames on the stack for return addresses
+
+; which have been invalidated by loading this segment and install handlers
+; for each invalidated return.
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+
+ BL check_for_invalidated_returns
+Done_Reinit
+
+; All segment clashes have now been dealt with, as have the re-setting
+; of the segment-loaded flags and the intercepting of invalidated returns.
+; So, now load the required segment.
+
+Retry
+;
+; Use the overlay table generated by the linker. The table format is as follows:
+; The first word in the table is contains the number of entries in the table.
+; The follows that number of table entries. Each entry is 3 words long:
+; Word 1 Length of the segment in bytes.
+; Word 2 Execution address of the PCIT section address. This is compared
+; against the value in R8. If the values are equal we have found
+; the entry for the called overlay.
+; Word 3 Load address of the segment.
+; Segment names are not used.
+;
+ LDR r0,=|Root$$OverlayTable|
+ LDR r1,[r0],#4
+search_loop
+ CMP r1,#0
+ MOVEQ r0,#2 ; The end the table has been reached and the
+ BEQ SevereErrorHandler ; segemnt has not been found.
+ LDMIA r0!,{r2,r3,r4}
+ CMP r8,r3
+ SUBNE r1,r1,#1
+ BNE search_loop
+
+ LDR r0,[ r8, #PCITSect_Base ]
+ MOV r1,r4
+ MOV r4,r2
+ BL MemCopy
+
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+;
+; Mark the segment as loaded.
+;
+ MOV r1,#1
+ STRB r1, [r8, #PCITSect_Flags]
+
+ LDR r0,[ r8, #PCITSect_Base ]
+ ADD r0,r0,r4
+
+; The segment's entry vector is at the end of the segment...
+; ...copy it to the PCIT section identified by r8.
+
+ LDR r1, [r8, #PCITSect_Vecsize]
+ SUB r3, r8, #8 ; end of entry vector...
+ MOV r4, #0 ; for data initialisation
+01 LDR r2, [r0, #-4]! ;>loop to copy
+ STR r4, [r0] ; (zero-init possible data section)
+ STR r2, [r3], #-4 ;>the segment's PCIT
+ SUBS r1, r1, #4 ;>section into the
+ BGT %B01 ;>global PCIT
+
+; Finally, continue, unabashed...
+
+ LDR r3, WorkSpace
+ LDR r3, [r3,#Work_PSRSave]
+ MSR CPSR,r3
+
+ LDMIA ip, {r0-r8, lr, pc}
+
+load_seg_and_ret
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r3, WorkSpace
+ MRS r8, CPSR
+ STR r8, [r3, #Work_PSRSave]
+
+; lr points to the return handler
+ MOV r8, lr
+ ; load return handler fields RealLR, Segment, Link
+ LDMIA r8, {r0, r1, r2}
+ SUB r8, r8, #4 ; point to true start of return handler before BL
+ STR r0, [r3, #Work_LRSave]
+ STR r0, [r3, #Work_PCSave]
+; Now unchain the handler and return it to the free pool
+; HStack points to this handler
+ LDR r0, [r3, #Work_HStack]
+ CMPS r0, r8
+ MOVNE r0, #1
+ BNE SevereErrorHandler
+ STR r2, [r3, #Work_HStack] ; new top of handler stack
+ LDR r2, [r3, #Work_HFree]
+ STR r2, [r8, #RHandl_Link] ; Link -> old HFree
+ STR r8, [r3, #Work_HFree] ; new free list
+ MOV r8, r1 ; segment to load
+ B load_segment
+
+check_for_invalidated_returns
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+; Note: check for returns invalidated by a call NOT for returns invalidated by
+; a return! In the 2nd case, the saved LR and saved PC are identical.
+ LDR r5, WorkSpace
+ ADD r6, r5, #Work_LRSave ; 1st location to check
+ LDMIA r6, {r0, r1} ; saved LR & PC
+ CMPS r0, r1
+ MOVEQ pc, lr ; identical => returning...
+ MOV r0, fp ; temporary FP...
+01 LDR r1, [r6] ; the saved return address...
+ LDR r2, [r5, #Work_HStack] ; top of handler stack
+ CMPS r1, r2 ; found the most recent handler, so
+ MOVEQ pc, lr ; abort the search
+ LDR r2, [r7, #PCITSect_Base]
+ CMPS r1, r2 ; see if >= base...
+ BLT %F02
+ LDR r2, [r7, #PCITSect_Limit]
+ CMPS r1, r2 ; ...and < limit ?
+ BLT FoundClash
+02 CMPS r0, #0 ; bottom of stack?
+ MOVEQ pc, lr ; yes => return
+ ADD r6, r0, #Stack_LRReturn
+ LDR r0, [r0, #Stack_FPReturn] ; previous FP
+ B %B01
+FoundClash
+ LDR r0, [r5, #Work_HFree] ; head of chain of free handlers
+ CMPS r0, #0
+ MOVEQ r0, #2
+ BEQ SevereErrorHandler
+; Transfer the next free handler to head of the handler stack.
+ LDR r1, [r0, #RHandl_Link] ; next free handler
+ STR r1, [r5, #Work_HFree]
+ LDR r1, [r5, #Work_HStack] ; the active handler stack
+ STR r1, [r0, #RHandl_Link]
+ STR r0, [r5, #Work_HStack] ; now with the latest handler linked in
+; Initialise the handler with a BL load_seg_and_ret, RealLR and Segment.
+ ADR r1, load_seg_and_ret
+ SUB r1, r1, r0 ; byte offset for BL in handler
+ SUB r1, r1, #8 ; correct for PC off by 8
+ MOV r1, r1, ASR #2 ; word offset
+ BIC r1, r1, #&FF000000
+ ORR r1, r1, #&EB000000 ; code for BL
+ STR r1, [r0, #RHandl_Branch]
+
+ LDR r1, [r6] ; LRReturn on stack
+ STR r1, [r0, #RHandl_RealLR] ; RealLR
+ STR r0, [r6] ; patch stack to return to handler
+
+ STR r7, [r0, #RHandl_Segment] ; segment to re-load on return
+ MOV pc, lr ; and return
+
+ AREA OverlayInit, DATA
+InitDoneFlag DCD 0
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/README.TXT b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/README.TXT
new file mode 100644
index 0000000..5748912
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/README.TXT
@@ -0,0 +1,745 @@
+ Use Of The Linker For Scatter Loading
+ -------------------------------------
+
+Version 0.1 Apr 1995 Laurence Bond
+Version 1.0 May 1995 Laurence Bond
+
+Introduction
+------------
+
+This application note describes an example which uses uses the linker to produce
+a scatter loaded application with overlays. The linker section in the Software
+Development Toolkit manual should read in conjunction with this note. Other
+information can be found in the Programming Techinques manual.
+
+The example will work only with Tools 200 Beta or later.
+
+Example Memory Structure
+------------------------
+In this example the memory is assumed to have the following structure
+
+ 0x00000 - 0x3FFFF - Unused
+ 0x40000 - 0x43FFF - SRAM
+ 0x44000 - 0x7FFFF - Unused
+ 0x80000 - 0x9FFFF - ROM
+
+Overlays will be placed in ROM and copied into the SRAM when needed. Also the
+overlay manager and all read/write initialised data will be copied into the
+SRAM.
+
+Overlay Manager
+---------------
+The linker does not provide the overlay manager. The overlay manager is user
+supplied code which controls the overlay mechanism. The linker produces the
+appropriate binary files and constructs the PCITs (Procedure Call Indirection
+Tables).
+The overlay manager must define two publicly visible symbols
+Image$$overlay_init and Image$$load_seg.
+
+Image$$overlay_init is used to initialise the overlay manager.
+Image$$overlay_init does not get called automatically. However it should be
+called just after the application has been entered. This is the case in this
+example although the routine just returns to the caller. The initialisation
+of the overlay manager workspace would done as part of the initialisation
+of the scatter loaded image.
+
+Image$$load_seg is the procedure that performs the functions of the overlay
+manager described in the Software Development toolkit manual.
+
+The overlay manager listed in Appendix A works with 32 bit processor modes only.
+It is operating system independent. The code area is read-only. The flag
+used to indicate whether the overlay manager has initialised its workspace is
+in a read-write area of its own. The code to load a segment uses the linker
+generated table that relates PCIT section addresses to the location of the
+overlay segments in their load regions. The address of this table is bound to
+the linker generated symbol Root$$OverlayTable.
+
+To aid operating system independence, two routines are be called by the
+overlay manager. These should could have replaced by inline code. However to aid
+clarity, this has not been done. The routines are:
+
+ MemCopy
+ r0 - Destination address
+ r1 - Source Address
+ r2 - Block length in bytes
+
+ This routine does not return anything.
+
+ SevereErrorHandler
+ r0 - A value indicating which error condition has occurred.
+
+ This symbol is a weak reference and need not be resolved. In the example
+ no such routine is provided. However in a real application one should be
+ provided.
+
+
+A Pitfall In Using The C library
+--------------------------------
+In this example, a the C library was found to interfere with loaded segments.
+The reason is that in the default C library, the heap is initialised to start
+at the address Image$$RW$$Limit.
+
+For example, the segments could get corrupted by use of the memory
+allocation package if they are located to an address greater that this. A malloc
+could grab some memory from the heap which just happened to be part of an
+overlayed segments code. Similarly loading an overlay segment could result in
+the segment data being loaded into an area used by the heap, thereby corrupting
+the heap. In this application the default libraray is used. The data allcoated
+on the heap is sufficently smaller that it fits between the end of the root
+read/write execution region and the start of the root read only execution
+region. If one were to examine the memory immediately above the address
+Image$$RW$$Limit one will find the data buffers used by the standard input and
+output channels.
+
+
+The Example Application
+-----------------------
+The example application reads a sequence of characters, terminated either by
+end of file or a newline, from stdin. These characters are then UU encoded and
+output to stdout.
+
+The application consists of 3 C source files and two assembler files excluding
+the overlay manager. The C files are as follows:
+
+ getdata.c
+ This defines a function, getData, which reads the characters into a
+ buffer passed to it by the main program.
+
+ uue.c
+ This defines a function, uue, which takes an input buffer passed
+ in by the main program and writes the UU encoded equivalent into
+ another buffer supplied by the main program.
+
+ main.c
+ This contains the C main program and example implementations of
+ the functions LoadOverlaySegment and MemCopy needed by the overlay
+ manager. Two statically allocated data buffers are also defined.
+
+ The main program calls getData to read data into a buffer. This buffer
+ is then passed to uue as the input buffer. The output buffer is zero
+ terminated after uue returns and the results written to stdout.
+
+ MemCopy is just a call to memmove - a standard C library function.
+
+Together with the overlay manager these C files could define the whole
+application. However the initialisation of the image is not done by any code in
+these source modules.
+
+A new entry point is required which initialises the application and the overlay manager. This supplied by the file maininit.s .
+The source code except for the overlay manager can be found in Appendix B.
+
+The buffers defined in main.c will be read-write data in the root read/write
+execution region.The assembler entry point code, the functions defined in
+main.c and any C library functions extracted from the library will be in the
+root read only execution region. The overlay manager and its initialised data
+will be moved to address 0x40000.
+
+The function uue will be in an overlay segment named seg_1. The function getData
+will be in an overlay segment named seg_2.
+
+Testing The Application
+-----------------------
+The application was built big endian and linked with the following linker
+options:
+ armlink -bin -scatter scatdes -o app maininit.o main.o overmgrs.o \
+ uue.o getdata.o initapp.o armlib.32b -map -symbols - \
+ -first maininit.o -list tS.map -v
+
+This command produces the subdirectory app which will contain 2 pure binary
+files - one per load region.
+
+The full Makefile and the scatter load description file (scatdes) can be found
+in Appendix B.
+
+The application is then loaded into ARMSD. As it is not an AIF file, the
+loading process is done manually.
+
+ armsd -bi
+ armsd: get app/root 0x80000
+ armsd: get app/copydata 0x84800
+ armsd: let pc=0x80000
+
+The entry point is at 0x80000 by virtue of the -FIRST option on the linker and
+the code structure in maininit.s
+
+ armsd: go
+ Hello World (The user types Hello World)
+ 2&5L;&\@5V]R;&0* (The program prints this.)
+
+This is correct when compared against UUENCODE on SunOS 4.1.3. Note that
+initial encoded count byte is not output.
+
+ Program terminated normally at PC = 0x00040248
+ 0x00040248: 0xef000011 .... : swi 0x11
+ armsd: q
+ Quitting
+
+Appendix A
+----------
+
+
+;;; Copyright (C) Advanced RISC Machines Ltd., 1991
+;;
+;; For use with a scatter loaded application with embedded overlays.
+
+ EXPORT |Image$$overlay_init|
+ EXPORT |Image$$load_seg|
+
+; pointers to start and end of workspace area supplied by the linker
+ IMPORT |Overlay$$Data$$Base|
+ IMPORT |Overlay$$Data$$Limit|
+ IMPORT |Root$$OverlayTable|
+ IMPORT MemCopy
+ IMPORT SevereErrorHandler, WEAK
+
+ZeroInitCodeOffset EQU 64
+
+; Layout of workspace allocated by the linker pointed to by Overlay$$Data
+; This area is automatically zero-initialised AFTER overlay_init is called
+; offsets are prefixed with Work_
+ ^ 0
+Work_HStack # 4 ; top of stack of allocated handlers
+Work_HFree # 4 ; head of free-list
+Work_RSave # 9*4 ; for R0-R8
+Work_LRSave # 4 ; saved lr
+Work_PCSave # 4 ; saved PC
+Work_PSRSave # 4 ; saved CPSR
+Work_ReturnHandlersArea EQU @ ; rest of this memory is treated as heap
+ ; space for the return handlers
+Work_MinSize EQU @ + 32 * RHandl_Size
+
+; Return handler. 1 is allocated per inter-segment procedure call
+; allocated and free lists of handlers are pointed to from HStack and HFree
+; offsets are prefixed with RHandl_
+ ^ 0
+RHandl_Branch # 4 ; BL load_seg_and_ret
+RHandl_RealLR # 4 ; space for the real return address
+RHandl_Segment # 4 ; -> PCIT section of segment to load
+RHandl_Link # 4 ; -> next in stack order
+RHandl_Size EQU @
+
+; set up by check_for_invalidated_returns.
+
+; PCITSection. 1 per segment stored in root segment, allocated by linker
+; offsets are prefixed with PCITSect_
+ ^ 0
+PCITSect_Vecsize # 4 ; .-4-EntryV ; size of entry vector
+PCITSect_Base # 4 ; used by load_segment; not initialised
+PCITSect_Limit # 4 ; used by load_segment; not initialised
+PCITSect_Name # 11 ; <11 bytes> ; 10-char segment name + NUL in 11 bytes
+PCITSect_Flags # 1 ; ...and a flag byte
+PCITSect_ClashSz # 4 ; PCITEnd-.-4 ; size of table following
+PCITSect_Clashes # 4 ; >table of pointers to clashing segments
+
+; Stack structure (all offsets are negative)
+; defined in procedure call standard
+; offsets are prefixed with Stack_
+ ^ 0
+Stack_SaveMask # -4
+Stack_LRReturn # -4
+Stack_SPReturn # -4
+Stack_FPReturn # -4
+
+; the code and private workspace area
+ AREA OverLayMgrArea, PIC, CODE , READONLY
+
+STRLR STR lr, [pc, #-8] ; a word that is to be matched in PCITs
+
+; Store 2 words which are the addresses of the start and end of the workspace
+WorkSpace DCD |Overlay$$Data$$Base|
+WorkSpaceEnd DCD |Overlay$$Data$$Limit|
+InitFlag DCD InitDoneFlag
+
+|Image$$overlay_init| ROUT
+; Initialise overlay manager.
+; In the AIF format this is is called from offset 8 in header. This routine has
+; to pass control to the zero initialisation code.
+; In Non AIF formats this routine has to be called explicitly e.g. from
+; a customised rtstand.s .
+;
+; In the AIF example the entire root segment is copied to the load address.
+;
+; In the non AIF example only the RW part of the root is copied.
+;
+ MOV pc,lr
+
+ DCD 0 ; Not needed for a real system but needed when using ARMSD
+ ; is used to simulate a ROM based system.
+; entry point
+
+|Image$$load_seg| ROUT
+;
+; called when segment has been called but is not loaded
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+ MRS r4, CPSR ; Save status register -it'll get stored in the
+ ; workspace later.
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r0, InitFlag
+ LDRB r1, [r0]
+ CMP r1, #0
+ BNE InitDone
+
+;Initialise Return Handlers on first call to this routine
+ MOV r1, #1
+ STRB r1, [r0] ; set InitDone flag
+ LDR r0, WorkSpace
+; r0 points to workspace
+; corrupts r0-r3,lr
+; create and initialise return handler linked list
+ MOV r2, #0
+ STR r2, [r0, #Work_HStack] ; initialise start of handler list with NULL
+ ADD r1, r0, #Work_ReturnHandlersArea ; Start of heap space
+ STR r1, [r0, #Work_HFree] ; Start of list of free handlers point to heap space
+ LDR r0, WorkSpaceEnd ; for test in loop to make sure..
+ SUBS r0, r0, #RHandl_Size ; ..I dont overrun in init
+01 ADD r3, r1, #RHandl_Size ; next handler
+; set up link to point to next handler (in fact consecutive locations)
+ STR r3, [r1, #RHandl_Link]
+ MOV r1, r3 ; next handler
+ CMP r1, r0 ; test for end of workspace
+ BLT %BT01
+ SUB r1, r1, #RHandl_Size ; previous handler
+ STR r2, [r1, #RHandl_Link] ; NULL-terminate list
+
+InitDone
+ LDR r3, WorkSpace
+ STR r4, [r3, #Work_PSRSave] ; CPSR read into R4 before the InitDone
+ ; test.
+ MOV r8,lr ;
+ LDR r0, [r8, #-8] ; saved r14... (is end of PCIT)
+ STR r0, [r3, #Work_LRSave] ; ...save it here ready for retry
+ LDR r0, STRLR ; look for this...
+ SUB r1, r8, #8 ; ... starting at last overwrite
+01 LDR r2, [r1, #-4]!
+ CMP r2, r0 ; must stop on guard word...
+ BNE %B01
+ ADD r1, r1, #4 ; gone one too far...
+ STR r1, [r3, #Work_PCSave] ; where to resume at
+
+load_segment
+
+; ip -> the register save area; r8 -> the PCIT section of the segment to load.
+; First re-initialise the PCIT section (if any) which clashes with this one...
+
+ ADD r1, r8, #PCITSect_Clashes
+ LDR r0, [r8, #PCITSect_ClashSz]
+01 SUBS r0, r0, #4
+ BLT Done_Reinit ; nothing left to do
+ LDR r7, [r1], #4 ; a clashing segment...
+ LDRB r2, [r7, #PCITSect_Flags] ; its flags (0 if unloaded)
+ CMPS r2, #0 ; is it loaded?
+ BEQ %B01 ; no, so look again
+
+; clashing segment is loaded (clearly, there can only be 1 such segment)
+; mark it as unloaded and reinitialise its PCIT
+; r7 -> PCITSection of clashing loaded segment
+
+ MOV r0, #0
+ STRB r0, [r7, #PCITSect_Flags] ; mark as unloaded
+ LDR r0, [r7, #PCITSect_Vecsize]
+ SUB r1, r7, #4 ; end of vector
+ LDR r2, STRLR ; init value to store in the vector...
+02 STR r2, [r1, #-4]! ;>
+ SUBS r0, r0, #4 ;> loop to initialise the PCIT segment
+ BGT %B02 ;>
+; Now we check the chain of call frames on the stack for return addresses
+
+; which have been invalidated by loading this segment and install handlers
+; for each invalidated return.
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+
+ BL check_for_invalidated_returns
+Done_Reinit
+
+; All segment clashes have now been dealt with, as have the re-setting
+; of the segment-loaded flags and the intercepting of invalidated returns.
+; So, now load the required segment.
+
+Retry
+;
+; Use the overlay table generated by the linker. The table format is as follows:
+; The first word in the table is contains the number of entries in the table.
+; The follows that number of table entries. Each entry is 3 words long:
+; Word 1 Length of the segment in bytes.
+; Word 2 Execution address of the PCIT section address. This is compared
+; against the value in R8. If the values are equal we have found
+; the entry for the called overlay.
+; Word 3 Load address of the segment.
+; Segment names are not used.
+;
+ LDR r0,=|Root$$OverlayTable|
+ LDR r1,[r0],#4
+search_loop
+ CMP r1,#0
+ MOVEQ r0,#2 ; The end the table has been reached and the
+ BEQ SevereErrorHandler ; segemnt has not been found.
+ LDMIA r0!,{r2,r3,r4}
+ CMP r8,r3
+ SUBNE r1,r1,#1
+ BNE search_loop
+
+ LDR r0,[ r8, #PCITSect_Base ]
+ MOV r1,r4
+ MOV r4,r2
+ BL MemCopy
+
+ LDR ip,WorkSpace
+ ADD ip,ip,#Work_RSave
+;
+; Mark the segment as loaded.
+;
+ MOV r1,#1
+ STRB r1, [r8, #PCITSect_Flags]
+
+ LDR r0,[ r8, #PCITSect_Base ]
+ ADD r0,r0,r4
+
+; The segment's entry vector is at the end of the segment...
+; ...copy it to the PCIT section identified by r8.
+
+ LDR r1, [r8, #PCITSect_Vecsize]
+ SUB r3, r8, #8 ; end of entry vector...
+ MOV r4, #0 ; for data initialisation
+01 LDR r2, [r0, #-4]! ;>loop to copy
+ STR r4, [r0] ; (zero-init possible data section)
+ STR r2, [r3], #-4 ;>the segment's PCIT
+ SUBS r1, r1, #4 ;>section into the
+ BGT %B01 ;>global PCIT
+
+; Finally, continue, unabashed...
+
+ LDR r3, WorkSpace
+ LDR r3, [r3,#Work_PSRSave]
+ MSR CPSR,r3
+
+ LDMIA ip, {r0-r8, lr, pc}
+
+load_seg_and_ret
+; presume ip is corruptible by this
+ LDR ip, WorkSpace
+ ADD ip, ip, #Work_RSave
+ STMIA ip, {r0-r8} ; save working registers
+; (save in my workspace because stack is untouchable during procedure call)
+ LDR r3, WorkSpace
+ MRS r8, CPSR
+ STR r8, [r3, #Work_PSRSave]
+
+; lr points to the return handler
+ MOV r8, lr
+ ; load return handler fields RealLR, Segment, Link
+ LDMIA r8, {r0, r1, r2}
+ SUB r8, r8, #4 ; point to true start of return handler before BL
+ STR r0, [r3, #Work_LRSave]
+ STR r0, [r3, #Work_PCSave]
+; Now unchain the handler and return it to the free pool
+; HStack points to this handler
+ LDR r0, [r3, #Work_HStack]
+ CMPS r0, r8
+ MOVNE r0, #1
+ BNE SevereErrorHandler
+ STR r2, [r3, #Work_HStack] ; new top of handler stack
+ LDR r2, [r3, #Work_HFree]
+ STR r2, [r8, #RHandl_Link] ; Link -> old HFree
+ STR r8, [r3, #Work_HFree] ; new free list
+ MOV r8, r1 ; segment to load
+ B load_segment
+
+check_for_invalidated_returns
+; Note: r8 identifies the segment being loaded; r7 the segment being unloaded.
+; Note: check for returns invalidated by a call NOT for returns invalidated by
+; a return! In the 2nd case, the saved LR and saved PC are identical.
+ LDR r5, WorkSpace
+ ADD r6, r5, #Work_LRSave ; 1st location to check
+ LDMIA r6, {r0, r1} ; saved LR & PC
+ CMPS r0, r1
+ MOVEQ pc, lr ; identical => returning...
+ MOV r0, fp ; temporary FP...
+01 LDR r1, [r6] ; the saved return address...
+ LDR r2, [r5, #Work_HStack] ; top of handler stack
+ CMPS r1, r2 ; found the most recent handler, so
+ MOVEQ pc, lr ; abort the search
+ LDR r2, [r7, #PCITSect_Base]
+ CMPS r1, r2 ; see if >= base...
+ BLT %F02
+ LDR r2, [r7, #PCITSect_Limit]
+ CMPS r1, r2 ; ...and < limit ?
+ BLT FoundClash
+02 CMPS r0, #0 ; bottom of stack?
+ MOVEQ pc, lr ; yes => return
+ ADD r6, r0, #Stack_LRReturn
+ LDR r0, [r0, #Stack_FPReturn] ; previous FP
+ B %B01
+FoundClash
+ LDR r0, [r5, #Work_HFree] ; head of chain of free handlers
+ CMPS r0, #0
+ MOVEQ r0, #2
+ BEQ SevereErrorHandler
+; Transfer the next free handler to head of the handler stack.
+ LDR r1, [r0, #RHandl_Link] ; next free handler
+ STR r1, [r5, #Work_HFree]
+ LDR r1, [r5, #Work_HStack] ; the active handler stack
+ STR r1, [r0, #RHandl_Link]
+ STR r0, [r5, #Work_HStack] ; now with the latest handler linked in
+; Initialise the handler with a BL load_seg_and_ret, RealLR and Segment.
+ ADR r1, load_seg_and_ret
+ SUB r1, r1, r0 ; byte offset for BL in handler
+ SUB r1, r1, #8 ; correct for PC off by 8
+ MOV r1, r1, ASR #2 ; word offset
+ BIC r1, r1, #&FF000000
+ ORR r1, r1, #&EB000000 ; code for BL
+ STR r1, [r0, #RHandl_Branch]
+
+ LDR r1, [r6] ; LRReturn on stack
+ STR r1, [r0, #RHandl_RealLR] ; RealLR
+ STR r0, [r6] ; patch stack to return to handler
+
+ STR r7, [r0, #RHandl_Segment] ; segment to re-load on return
+ MOV pc, lr ; and return
+
+ AREA OverlayInit, DATA
+InitDoneFlag DCD 0
+
+ END
+Appendix B
+----------
+main.c
+------
+
+#include <stdio.h>
+#include <string.h>
+#define INBUFFSIZE 192
+#define OUTBUFFSIZE 257
+
+/*
+ This is used to check whether the initialised data has been copied
+ correctly.
+*/
+static char IDstring[]="This is initialised data.";
+static char inBuff[INBUFFSIZE];
+static char outBuff[OUTBUFFSIZE];
+static int charCount=0;
+
+extern int getData(char *,int);
+extern int uuencode(char *, char *, int);
+
+int main(int argc,char **argv)
+{
+ int uuCount;
+ charCount = getData(inBuff,sizeof(inBuff));
+ if (charCount<0) {
+ fprintf(stderr,"Error reading data.\n");
+ }
+ else {
+ uuCount=uuencode(inBuff,outBuff,charCount);
+ outBuff[uuCount]='\0';
+ puts(outBuff);
+ }
+ return 0;
+}
+
+void MemCopy(void *d,void *s,int c)
+{
+ memmove(d,s,c);
+}
+
+getdata.c
+---------
+
+int getData(char *buffer,int length)
+{
+ int charsIn;
+ int charRead;
+ charsIn=0;
+ for (charsIn=0;charsIn<length;) {
+ charRead=getchar();
+ if (charRead == EOF) break;
+ buffer[charsIn++]=charRead;
+ if (charRead == '\n' ) break;
+ }
+ for (;(charsIn%3)!=0; ) buffer[charsIn++]='\0';
+ return charsIn;
+}
+
+uue.c
+-----
+
+/*
+ A simple reoutine to UUENCODE a buffer. It does not split up the
+ uuencoded data into lines and append encode count bytes though.
+ It assumes that the input buffer is an integer multiple of 3 bytes long.
+ The number of bytes written to the output buffer is returned.
+*/
+unsigned int encodedCount=0;
+unsigned int uuencode(unsigned char *in,unsigned char *out,unsigned int count)
+{
+ unsigned char t0;
+ unsigned char t1;
+ unsigned char t2;
+ unsigned int result=0;
+
+ for (;count;count-=3,in+=3,out+=4,result+=4) {
+ t0=in[0];
+ *out=' '+(t0>>2);
+ t1=in[1];
+ out[1]=' '+((t0<<4)&0x30)+(t1>>4);
+ t2=in[2];
+ out[2]=' '+((t1<<2)&0x3C)+ (t2>>6);
+ out[3]=' '+(t2&0x3F);
+ }
+ encodedCount += count;
+ return result;
+}
+
+maininit.s
+----------
+
+ AREA MainWithOverlayInit, CODE, READONLY
+ IMPORT |Image$$overlay_init|
+ IMPORT InitialiseApp
+ IMPORT __entry
+ EXPORT __main
+
+ ENTRY
+__main
+ BL InitialiseApp
+ BL |Image$$overlay_init|
+ BL __entry
+ END
+
+Makefile
+--------
+
+LIB=
+
+.c.o:
+ armcc -c -bi -APCS 3/32/noswst $<
+
+.s.o:
+ armasm -bi -APCS 3/32/noswst $<
+
+all: app/root
+
+app/root: main.o uue.o getdata.o overmgrs.o initapp.o maininit.o
+ armlink -bin -scatter scatdes -o app maininit.o main.o overmgrs.o \
+ uue.o getdata.o initapp.o $(LIB)/armlib.32b -map -symbols - \
+ -first maininit.o -list tS.map -NOUNUSED -v > tS.log
+
+maininit.o: maininit.s
+
+initapp.o: initapp.s
+
+overmgrs.o: overmgrs.s
+
+main.o: main.c
+
+uue.o: uue.c
+
+getdata.o: getdata.c
+
+scatdes
+-------
+
+;
+; Position the root load region at 0x80000. Limit the size so it does not
+; overlap the overlay segments in the ROM load region.
+;
+ROOT 0x80000 0x4800
+;
+; Position the root read/write execution region .
+;
+ROOT-DATA 0x43000
+
+copydata 0x84800 {
+ seg_1 0x42000 OVERLAY { uue.o }
+ seg_2 0x42000 OVERLAY { getdata.o }
+ overmgr 0x40000 { overmgrs.o(+RO, +RW) } ; Position the overlay manager
+ ; code and data in the SRAM
+}
+
+initapp.s
+---------
+
+ AREA InitApp, CODE , READONLY
+ EXPORT InitialiseApp
+InitialiseApp
+ ADR r0,ziTable
+ MOV R3,#0
+ziLoop
+ LDR r1,[r0],#4
+ CMP r1,#0
+ BEQ initLoop
+ LDR r2,[r0],#4
+ziFillLoop
+ STR r3,[r2],#4
+ SUBS r1,r1,#4
+ BNE ziFillLoop
+ B ziLoop
+
+initLoop
+ LDR r1,[r0],#4
+ CMP r1,#0
+ MOVEQ pc,lr
+ LDMIA r0!,{r2,r3}
+ CMP r1,#16
+ BLT copyWords
+copy4Words
+ LDMIA r3!,{r4,r5,r6,r7}
+ STMIA r2!,{r4,r5,r6,r7}
+ SUBS r1,r1,#16
+ BGT copy4Words
+ BEQ initLoop
+copyWords
+ SUBS r1,r1,#8
+ LDMIAGE r3!,{r4,r5}
+ STMIAGE r2!,{r4,r5}
+ BEQ initLoop
+
+ LDR r4,[r3]
+ STR r4,[r2]
+
+ B initLoop
+
+ MACRO
+ ZIEntry $execname
+ LCLS lensym
+ LCLS basesym
+ LCLS namecp
+namecp SETS "$execname"
+lensym SETS "|Image$$":CC:namecp:CC:"$$ZI$$Length|"
+basesym SETS "|Image$$":CC:namecp:CC:"$$ZI$$Base|"
+ IMPORT $lensym
+ IMPORT $basesym
+ DCD $lensym
+ DCD $basesym
+ MEND
+
+ MACRO
+ InitEntry $execname
+ LCLS lensym
+ LCLS basesym
+ LCLS loadsym
+ LCLS namecp
+namecp SETS "$execname"
+lensym SETS "|Image$$":CC:namecp:CC:"$$Length|"
+basesym SETS "|Image$$":CC:namecp:CC:"$$Base|"
+loadsym SETS "|Load$$":CC:namecp:CC:"$$Base|"
+ IMPORT $lensym
+ IMPORT $basesym
+ IMPORT $loadsym
+ DCD $lensym
+ DCD $basesym
+ DCD $loadsym
+ MEND
+
+ziTable
+ ZIEntry root
+ DCD 0
+
+InitTable
+ InitEntry root
+ InitEntry overmgr
+ DCD 0
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATDES b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATDES
new file mode 100644
index 0000000..6ec377f
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATDES
@@ -0,0 +1,26 @@
+;
+;
+; The memory map or the system is
+;
+; 0x00000 - 0x3FFFF - DRAM
+; 0x40000 - 0x43FFF - SRAM
+; 0x44000 - 0x7FFFF - Unused
+; 0x80000 - 0x9FFFF - ROM
+;
+; Position the root load region at 0x40000. Limit the size so it does not
+; overlap the overlay segments in the ROM load region.
+;
+ROOT 0x80000 0x8000
+;
+; Position the root read/write execution region .
+;
+ROOT-DATA 0x43000
+
+copydata 0x88000 {
+ seg_1 0x42000 OVERLAY { uue.o }
+ seg_2 0x42000 OVERLAY { getdata.o }
+ overmgr 0x40000 { overmgrs.o(+RO, +RW) } ; Position the overlay manager
+ ; code and data in the fast SRAM
+}
+
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATTER.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATTER.APJ
new file mode 100644
index 0000000..1d8d656
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/SCATTER.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/STARTUP.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/STARTUP.S
new file mode 100644
index 0000000..b61472a
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/STARTUP.S
@@ -0,0 +1,52 @@
+ AREA |!!!|, CODE, READONLY
+
+ IMPORT __entry ; The C library entry point
+
+ EXPORT __main
+
+ IMPORT |Image$$RO$$Base|
+ IMPORT |Image$$RO$$Limit|
+ IMPORT |Image$$RW$$Base|
+ IMPORT |Image$$RW$$Limit|
+ IMPORT |Image$$ZI$$Base|
+ IMPORT |Image$$ZI$$Limit|
+
+;----------------------------------------------------------------------------;
+; The above symbols are created by the linker to define various sections in ;
+; the ROM/RAM image. ;
+; ;
+; Image$$RO$$Base defines the code (ROM) base address ;
+; Image$$RO$$Limit defines the code limit and the start of a section of ;
+; data initialisation values which are copied to RAM ;
+; in __main below before main is called. ;
+; Image$$RW$$Base defines the data (RAM) base address ;
+; Image$$RW$$Limit defines the data end address ;
+; Image$$ZI$$Base defines the base of a section to be initialised with 0s ;
+; Image$$ZI$$Limit defines the end of the region to be initialised with 0s ;
+; (must be the same as Image$$RW$$Limit in this model) ;
+;----------------------------------------------------------------------------;
+
+; Code is enter in ARM mode
+ [ {CONFIG} = 16
+ CODE32
+ ]
+
+__main
+ LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
+ LDR r1, =|Image$$RW$$Base| ; and RAM copy
+ LDR r3, =|Image$$ZI$$Base| ; Zero init base => top of initialised data
+ CMP r0, r1 ; Check that they are different
+ BEQ %FT1
+0 CMP r1, r3 ; Copy init data
+ LDRCC r2, [r0], #4
+ STRCC r2, [r1], #4
+ BCC %BT0
+1 LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment
+ MOV r2, #0
+2 CMP r3, r1 ; Zero init
+ STRCC r2, [r3], #4
+ BCC %BT2
+
+ B __entry
+
+ END
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/UUE.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/UUE.C
new file mode 100644
index 0000000..76d60c3
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SCATTER/UUE.C
@@ -0,0 +1,26 @@
+/*
+ A simple reoutine to UUENCODE a buffer. It does not split up the
+ uuencoded data into lines and append encode count bytes though.
+ It assumes that the input buffer is an integer multiple of 3 bytes long.
+ The number of bytes written to the output buffer is returned.
+*/
+unsigned int encodedCount=0;
+unsigned int uuencode(unsigned char *in,unsigned char *out,unsigned int count)
+{
+ unsigned char t0;
+ unsigned char t1;
+ unsigned char t2;
+ unsigned int result=0;
+
+ for (;count;count-=3,in+=3,out+=4,result+=4) {
+ t0=in[0];
+ *out=' '+(t0>>2);
+ t1=in[1];
+ out[1]=' '+((t0<<4)&0x30)+(t1>>4);
+ t2=in[2];
+ out[2]=' '+((t1<<2)&0x3C)+ (t2>>6);
+ out[3]=' '+(t2&0x3F);
+ }
+ encodedCount += count;
+ return result;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/ARMSD.MAP b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/ARMSD.MAP
new file mode 100644
index 0000000..ba65198
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/ARMSD.MAP
@@ -0,0 +1 @@
+0 80000000 RAM 4 rw 135/80 135/80
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/SORTS.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/SORTS.C
new file mode 100644
index 0000000..5a2afa2
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SORTS/SORTS.C
@@ -0,0 +1,135 @@
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define N 1000
+
+#if N > 1000000
+#error "Value of N too big, must be <= 1000000"
+#endif
+
+#define LOG10_N 6
+#define N_FORMAT "%06d"
+
+#if N <= 1000
+static void insert_sort(char *strings[], int n)
+{
+ char *v, *t;
+ char **strp, **endp;
+ int i;
+
+ endp = &strings[N-1];
+ i = N-2;
+ do {
+ strp = &strings[i];
+ v = strp[0];
+ do {
+ t = strp[1];
+ if (strcmp(v, t) <= 0) break;
+ *strp++ = t;
+ } while (strp < endp);
+ strp[0] = v;
+ } while (--i >= 0);
+}
+#endif
+
+static void shell_sort(char *strings[], int n)
+{
+ int h, i, j;
+ char *v;
+
+ strings--; /* Make array 1 origin */
+ h = 1;
+ do {h = h * 3 + 1;} while (h <= n);
+ do {
+ h = h / 3;
+ for (i = h + 1; i <= n; i++) {
+ v = strings[i];
+ j = i;
+ while (j > h && strcmp(strings[j-h], v) > 0) {
+ strings[j] = strings[j-h];
+ j = j-h;
+ }
+ strings[j] = v;
+ }
+ }
+ while (h > 1);
+}
+
+static void randomise(char *strings[], int n)
+{
+ int i;
+ int v;
+ char *t;
+
+ /* srand(clock()); /* comment out for reproducible results */
+ for (i = 0; i < N; i++) {
+ v = rand() % N;
+ t = strings[v];
+ strings[v] = strings[i];
+ strings[i] = t;
+ }
+}
+
+static void check_order(char *sort_type, char *strings[], int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (atoi(strings[i]) != i) {
+ fprintf(stderr, "%s sort failed - exiting\n", sort_type);
+ exit(1);
+ }
+ }
+}
+
+int qs_string_compare(const void *a, const void *b)
+{
+ return strcmp(*(char **)a, *(char **)b);
+}
+
+int main(void)
+{
+ char *strings[N], *strings_copy[N];
+ char buffer[N*(LOG10_N+1)];
+ char *p;
+ clock_t starttime, endtime;
+ int i;
+
+ p = buffer;
+ for (i = 0; i < N; i++) {
+ sprintf(p, N_FORMAT, i);
+ strings[i] = p;
+ p += LOG10_N+1;
+ }
+ randomise(strings, N);
+
+#if N <= 1000
+ /* Do insertion sort */
+ memcpy(strings_copy, strings, sizeof(strings));
+ starttime = clock();
+ insert_sort(strings_copy, N);
+ endtime = clock();
+ check_order("Insertion", strings_copy, N);
+ printf("Insertion sort took %d clock ticks\n", endtime - starttime);
+#else
+ printf("Value of N too big to use insertion sort, must be <= 1000\n");
+#endif
+
+ /* Do shell sort */
+ memcpy(strings_copy, strings, sizeof(strings));
+ starttime = clock();
+ shell_sort(strings_copy, N);
+ endtime = clock();
+ check_order("Shell", strings_copy, N);
+ printf("Shell sort took %d clock ticks\n", endtime - starttime);
+
+ /* Do quick sort - use built-in C library sort */
+ memcpy(strings_copy, strings, sizeof(strings));
+ starttime = clock();
+ qsort(strings_copy, N, sizeof(char *), qs_string_compare);
+ endtime = clock();
+ check_order("Quick", strings_copy, N);
+ printf("Quick sort took %d clock ticks\n", endtime - starttime);
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/HANDLE.S b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/HANDLE.S
new file mode 100644
index 0000000..6056035
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/HANDLE.S
@@ -0,0 +1,42 @@
+ AREA TopSwiHandler, CODE ; name this block of code
+
+ EXPORT SWIHandler
+ EXPORT MakeChain
+ IMPORT C_SWI_Handler
+ IMPORT Dswivec
+SWIHandler
+ SUB r13, r13, #4 ; leave space to store spsr
+ STMFD r13!, {r0-r12,r14} ; store registers
+ MOV r1, r13 ; second parameter to C routine
+ ; is register values.
+ LDR r0,[r14,#-4] ; Calculate address of SWI instruction
+ ; and load it into r0
+ BIC r0,r0,#0xff000000 ; mask off top 8 bits of instruction
+ MRS r2, spsr
+ STR r2,[r13,#14*4] ; store spsr on stack at original r13
+ BL C_SWI_Handler ; Call C routine to handle SWI
+ CMP r0, #0 ; Has C routine handled SWI ?
+ ; 0 = no, 1 = yes
+ LDR r2, [r13,#14*4] ; extract spsr from stack
+ MSR spsr,r2 ; and restore it
+ LDMFD r13!, {r0-r12,lr} ; Restore original registers
+ ADD r13,r13,#4
+ ; Now need to decide whether to return from handler or to call
+ ; the next handler in the chain (the debugger's).
+ MOVNES pc,lr ; return from handler if SWI handled
+ LDR pc, swichain ; else jump to address containing
+ ; instruction to branch to address of
+ ; debugger's SWI handler.
+
+swichain
+ DCD 0
+
+MakeChain
+ LDR r0, =swichain
+ LDR r1, =Dswivec
+ LDR r2, [r1]
+ STR r2, [r0]
+ MOV pc,lr
+
+ END ; mark end of this file
+
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALL.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALL.C
new file mode 100644
index 0000000..9c0fadf
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALL.C
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void SWIHandler (void);
+extern void MakeChain (void);
+
+unsigned *Dswivec = (unsigned *) 0x20; /* ie place to store old one */
+
+struct four_results
+{ unsigned a;
+ unsigned b;
+ unsigned c;
+ unsigned d;
+};
+
+__swi (256) void my_swi_256 (void);
+__swi (257) void my_swi_257 (unsigned);
+__swi (258) unsigned my_swi_258 (unsigned,unsigned,unsigned,unsigned);
+__swi (259) __value_in_regs struct four_results
+ my_swi_259 (unsigned, unsigned, unsigned,unsigned);
+
+unsigned Install_Handler (unsigned routine, unsigned *vector)
+/* Updates contents of 'vector' to contain branch instruction */
+/* to reach 'routine' from 'vector'. Function return value is */ /* original contents of 'vector'. */
+/* NB: 'Routine' must be within range of 32Mbytes from 'vector'.*/
+{ unsigned vec, oldvec;
+ vec = ((routine - (unsigned)vector - 0x8)>>2);
+ if (vec & 0xff000000)
+ { printf ("Installation of Handler failed");
+ exit (0);
+ }
+ vec = 0xea000000 | vec;
+ oldvec = *vector;
+ *vector = vec;
+ return (oldvec);
+}
+
+void Update_Demon_Vec (unsigned *original, unsigned *Dvec)
+/* Returns updated instruction 'LDR pc, [pc,#offset]' when */
+/* moved from 'original' to 'Dvec' (ie recalculates offset). */
+/* Assumes 'Dvec' is higher in memory than 'original'. */
+{
+ *Dvec = ((*Dvec &0xfff)
+ - ((unsigned) Dvec - (unsigned) original))
+ | (*Dvec & 0xfffff000);
+}
+
+unsigned C_SWI_Handler (unsigned number, unsigned *reg)
+{ unsigned done = 1;
+
+ /* Set up parameter storage block pointers */
+ unsigned *called_256 = (unsigned *) 0x24;
+ unsigned *param_257 = (unsigned*) 0x28;
+ unsigned *param_258 = (unsigned*) 0x2c; /* + 0x30,0x34,0x38 */
+ unsigned *param_259 = (unsigned*) 0x3c; /* + 0x40,0x44,0x48 */
+ switch (number)
+ { case 256:
+ *called_256 = 256; /* Store a value to show that */
+ break; /* SWI was handled correctly. */
+ case 257:
+ *param_257 = reg [0]; /* Store parameter */
+ break;
+ case 258:
+ *param_258++ = reg [0]; /* Store parameters */
+ *param_258++ = reg [1];
+ *param_258++ = reg [2];
+ *param_258 = reg [3];
+ /* Now calculate result */
+ reg [0] += reg [1] + reg [2] + reg [3];
+ break;
+ case 259:
+ *param_259++ = reg [0]; /* Store parameters */
+ *param_259++ = reg [1];
+ *param_259++ = reg [2];
+ *param_259 = reg [3];
+ reg [0] *= 2; /* Calculate results */
+ reg [1] *= 3;
+ reg [2] *= 4;
+ reg [3] *= 5;
+ break;
+ default: done = 0; /* SWI not handled */
+ }
+ return (done);
+}
+
+int main ()
+{
+ struct four_results r_259; /* Results from SWI 259 */
+ unsigned *swivec = (unsigned *)0x8; /* Pointer to SWI vector */
+ *Dswivec = Install_Handler ((unsigned)SWIHandler, swivec);
+ Update_Demon_Vec (swivec, Dswivec);
+ MakeChain ();
+
+ printf("Hello 256\n");
+ my_swi_256 ();
+ printf("Hello 257\n");
+ my_swi_257 (257);
+ printf("Hello 258\n");
+ printf(" Result = %u\n",my_swi_258 (1,2,3,4));
+ printf ("Hello 259\n");
+ r_259 = my_swi_259 (10,20,30,40);
+ printf (" Results are: %u %u %u %u\n",r_259.a,r_259.b,r_259.c,r_259.d);
+ printf("The end\n");
+ return (0);
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALLH.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALLH.C
new file mode 100644
index 0000000..0413b49
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALLH.C
@@ -0,0 +1,17 @@
+typedef struct SWI_InstallHandler_struct
+{ unsigned exception;
+ unsigned workspace;
+ unsigned handler;
+} SWI_InstallHandler_block;
+
+
+SWI_InstallHandler_block
+ __value_in_regs
+ __swi(0x70) SWI_InstallHandler(unsigned r0, unsigned r1, unsigned r2);
+
+void InstallHandler(SWI_InstallHandler_block *regs_in,
+ SWI_InstallHandler_block *regs_out)
+{ *regs_out=SWI_InstallHandler(regs_in->exception,
+ regs_in->workspace,
+ regs_in->handler);
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/NEWLINE.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/NEWLINE.C
new file mode 100644
index 0000000..25bae33
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/NEWLINE.C
@@ -0,0 +1,6 @@
+void __swi(0) SWI_WriteC(int ch);
+
+void output_newline(void)
+{ SWI_WriteC(13);
+ SWI_WriteC(10);
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/READLINE.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/READLINE.C
new file mode 100644
index 0000000..2168320
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/READLINE.C
@@ -0,0 +1,9 @@
+char __swi(4) SWI_ReadC(void);
+
+void readline(char *buffer)
+{ char ch;
+ do {
+ *buffer++=ch=SWI_ReadC();
+ } while (ch!=13);
+ *buffer=0;
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWI.APJ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWI.APJ
new file mode 100644
index 0000000..2bbbc96
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWI.APJ
Binary files differ
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWIMANIP.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWIMANIP.C
new file mode 100644
index 0000000..231c76c
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/SWIMANIP.C
@@ -0,0 +1,9 @@
+unsigned __swi_indirect(0x80)
+ SWI_ManipulateObject(unsigned operationNumber, unsigned object,
+ unsigned parameter);
+
+unsigned DoSelectedManipulation(unsigned object, unsigned parameter,
+ unsigned operation)
+{
+ return SWI_ManipulateObject(operation, object, parameter);
+}
diff --git a/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/UNUSED/UNUSED.C b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/UNUSED/UNUSED.C
new file mode 100644
index 0000000..8e9ec27
--- /dev/null
+++ b/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/UNUSED/UNUSED.C
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void unused_function(void)
+{
+ printf("This function used to do something useful, but is now no longer called\n");
+}
+
+int main(void)
+{
+ printf("We used to call 'unused_function' here.\n");
+#if 0
+ unused_function();
+#endif
+}