summaryrefslogtreecommitdiffstats
path: root/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/SWI/INSTALL.C
blob: 9c0fadfdde40e9dcee008635c68e5fc33731d5a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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);
}