summaryrefslogtreecommitdiffstats
path: root/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI
diff options
context:
space:
mode:
authorSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
committerSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
commit33613a85afc4b1481367fbe92a17ee59c240250b (patch)
tree670b842326116b376b505ec2263878912fca97e2 /Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI
downloadStudium-master.tar.gz
Studium-master.tar.bz2
add new repoHEADmaster
Diffstat (limited to 'Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI')
-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
7 files changed, 188 insertions, 0 deletions
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);
+}