Mercurial > repos > rhope
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 } |