comparison ds_hardware.c @ 0:76568becd6d6

Rhope Alpha 2a source import
author Mike Pavone <pavone@retrodev.com>
date Tue, 28 Apr 2009 23:06:07 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:76568becd6d6
1 #include <nds/interrupts.h>
2 #include <nds.h>
3 #include "datum.h"
4 #include "interp.h"
5 #include "structs.h"
6 #include <string.h>
7
8 #define IRQ_STUB(num) void irq_stub_##num () { rhope_irq(num); }
9
10 datum * irq_workers[MAX_INTERRUPTS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
11 program * irq_programs[MAX_INTERRUPTS];
12 worker_instance irq_instances[MAX_INTERRUPTS];
13 int irq_queue[MAX_INTERRUPTS];
14 int irq_queue_count = 0;
15
16 void rhope_irq(int num)
17 {
18 if(num < MAX_INTERRUPTS && irq_workers[num])
19 {
20 if(irq_queue_count < MAX_INTERRUPTS)
21 irq_queue[irq_queue_count++] = num;
22 //TODO Add some kind of error handling for when the IRQ_QUEUE Is full?
23 }
24 }
25
26 IRQ_STUB(0)
27 IRQ_STUB(1)
28 IRQ_STUB(2)
29 IRQ_STUB(3)
30 IRQ_STUB(4)
31 IRQ_STUB(5)
32 IRQ_STUB(6)
33 IRQ_STUB(7)
34 IRQ_STUB(8)
35 IRQ_STUB(9)
36 IRQ_STUB(10)
37 IRQ_STUB(11)
38 IRQ_STUB(12)
39 IRQ_STUB(13)
40 IRQ_STUB(14)
41 IRQ_STUB(15)
42 IRQ_STUB(16)
43 IRQ_STUB(17)
44 IRQ_STUB(18)
45 IRQ_STUB(19)
46 IRQ_STUB(20)
47 IRQ_STUB(21)
48 IRQ_STUB(22)
49 IRQ_STUB(23)
50 IRQ_STUB(24)
51
52
53
54
55 VoidFunctionPointer handlerList[MAX_INTERRUPTS] = {irq_stub_0,irq_stub_1,irq_stub_2,irq_stub_3,irq_stub_4,irq_stub_5,irq_stub_6,irq_stub_7,irq_stub_8,irq_stub_9,irq_stub_10,irq_stub_11,irq_stub_12,irq_stub_13,irq_stub_14,irq_stub_15,irq_stub_16,irq_stub_17,irq_stub_18,irq_stub_19,irq_stub_20,irq_stub_21,irq_stub_22,irq_stub_23,irq_stub_24};
56
57 int vis_register_handler(datum ** params, queue_entry * entry)
58 {
59 int num = params[0]->c.integers.num_a;
60 if(num >= MAX_INTERRUPTS)
61 {
62 release_ref(params[1]);
63 params[1] = copy_datum(params[0], 0);
64 params[0] = NULL;
65 params[1]->c.integers.num_a = MAX_INTERRUPTS-1;
66 return 0;
67 }
68 REG_IME = IME_DISABLE;
69 if(irq_workers[num])
70 release_ref(irq_workers[num]);
71 irqSet(1<<num, handlerList[num]);
72 irq_workers[num] = params[1];
73 irq_programs[num] = entry->instance->def->program; //technically the worker could be from a different program than the one doing the registering, but it's doubtful
74 irq_instances[num].def = irq_programs[num]->defs->deflist;
75 irq_instances[num].caller_instance = NULL;
76 irq_instances[num].trans = NULL;
77 irq_instances[num].num_workers = irq_instances[num].num_wires = 0;
78 VIS_InitializeCriticalSection(inst.counter_lock);
79 REG_IME = IME_ENABLE;
80 params[1] = NULL;
81 return 0;
82 }
83
84 int vis_clear_handler(datum ** params, queue_entry * entry)
85 {
86 int num = params[0]->c.integers.num_a;
87 if(num >= MAX_INTERRUPTS)
88 {
89 release_ref(params[1]);
90 params[1] = copy_datum(params[0], 0);
91 params[0] = NULL;
92 params[1]->c.integers.num_a = MAX_INTERRUPTS-1;
93 return 0;
94 }
95 REG_IME = IME_DISABLE;
96 if(irq_workers[num])
97 release_ref(irq_workers[num]);
98 irqClear(1<<num);
99 irq_workers[num] = NULL;
100 REG_IME = IME_ENABLE;
101 params[1] = NULL;
102 return 0;
103 }
104
105
106 void run_queued_irqs()
107 {
108 int irq_queue_copy[MAX_INTERRUPTS];
109 int irq_queue_count_copy;
110 int i;
111 queue_entry entry;
112 datum * params[32];
113 entry.worker_num = 0;
114 //Could this result in missed interrupts or will they just be queued in hardware until I re-enable them?
115 REG_IME = IME_DISABLE;
116 irq_queue_count_copy = irq_queue_count;
117 memcpy(irq_queue_copy, irq_queue, sizeof(int) * irq_queue_count);
118 irq_queue_count = 0;
119 REG_IME = IME_ENABLE;
120 for(i = 0; i < irq_queue_count_copy; ++i)
121 {
122 params[0] = add_ref(irq_workers[irq_queue_copy[i]]);
123 params[1] = create_list(irq_programs[irq_queue_copy[i]]);
124 params[2] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, irq_programs[irq_queue_copy[i]]);
125 params[2]->c.integers.num_a = irq_queue_copy[i];
126 vis_list_append(params + 1, &entry);
127 entry.instance = &irq_instances[irq_queue_copy[i]];
128 entry.instance->in_progress_count = entry.instance->in_queue_count = 1000;
129 vis_worker_do(params, &entry);
130 }
131
132 }
133
134 const char ndsKeyLetters[15] = "ABESRLUD><XYMC";
135 #define NDS_MAX_KEY_BITS 14
136
137 int vis_held_keys(datum ** params, queue_entry * worker_entry)
138 {
139 datum * workparams[3];
140 datum * yes;
141 char key_string[2] = " ";
142 int held,i;
143 scanKeys();
144 held = keysHeld();
145 workparams[0] = create_dict(worker_entry->instance->def->program);
146 yes = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
147 yes->c.integers.num_a = 1;
148 for(i = 0; i < NDS_MAX_KEY_BITS; ++i)
149 if(held & (1 << i))
150 {
151 key_string[0] = ndsKeyLetters[i];
152 workparams[1] = make_string(key_string, -1, worker_entry->instance->def->program);
153 workparams[2] = add_ref(yes);
154 vis_dict_set(workparams, worker_entry);
155 }
156 params[0] = workparams[0];
157 release_ref(yes);
158 return 0;
159 }
160
161 int vis_touch_position(datum ** params, queue_entry * worker_entry)
162 {
163 touchPosition touchXY;
164 touchXY=touchReadXY();
165 params[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
166 params[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
167 params[0]->c.integers.num_a = touchXY.px;
168 params[1]->c.integers.num_a = touchXY.py;
169 return 0;
170 }