Mercurial > repos > rhope
view ds_hardware.c @ 118:b3f56e1d54a0
Merged changes from interpreted version of compiler to compiled version
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 15 Oct 2010 00:55:02 -0400 |
parents | 76568becd6d6 |
children |
line wrap: on
line source
#include <nds/interrupts.h> #include <nds.h> #include "datum.h" #include "interp.h" #include "structs.h" #include <string.h> #define IRQ_STUB(num) void irq_stub_##num () { rhope_irq(num); } 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}; program * irq_programs[MAX_INTERRUPTS]; worker_instance irq_instances[MAX_INTERRUPTS]; int irq_queue[MAX_INTERRUPTS]; int irq_queue_count = 0; void rhope_irq(int num) { if(num < MAX_INTERRUPTS && irq_workers[num]) { if(irq_queue_count < MAX_INTERRUPTS) irq_queue[irq_queue_count++] = num; //TODO Add some kind of error handling for when the IRQ_QUEUE Is full? } } 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) 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}; int vis_register_handler(datum ** params, queue_entry * entry) { int num = params[0]->c.integers.num_a; if(num >= MAX_INTERRUPTS) { release_ref(params[1]); params[1] = copy_datum(params[0], 0); params[0] = NULL; params[1]->c.integers.num_a = MAX_INTERRUPTS-1; return 0; } REG_IME = IME_DISABLE; if(irq_workers[num]) release_ref(irq_workers[num]); irqSet(1<<num, handlerList[num]); irq_workers[num] = params[1]; 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 irq_instances[num].def = irq_programs[num]->defs->deflist; irq_instances[num].caller_instance = NULL; irq_instances[num].trans = NULL; irq_instances[num].num_workers = irq_instances[num].num_wires = 0; VIS_InitializeCriticalSection(inst.counter_lock); REG_IME = IME_ENABLE; params[1] = NULL; return 0; } int vis_clear_handler(datum ** params, queue_entry * entry) { int num = params[0]->c.integers.num_a; if(num >= MAX_INTERRUPTS) { release_ref(params[1]); params[1] = copy_datum(params[0], 0); params[0] = NULL; params[1]->c.integers.num_a = MAX_INTERRUPTS-1; return 0; } REG_IME = IME_DISABLE; if(irq_workers[num]) release_ref(irq_workers[num]); irqClear(1<<num); irq_workers[num] = NULL; REG_IME = IME_ENABLE; params[1] = NULL; return 0; } void run_queued_irqs() { int irq_queue_copy[MAX_INTERRUPTS]; int irq_queue_count_copy; int i; queue_entry entry; datum * params[32]; entry.worker_num = 0; //Could this result in missed interrupts or will they just be queued in hardware until I re-enable them? REG_IME = IME_DISABLE; irq_queue_count_copy = irq_queue_count; memcpy(irq_queue_copy, irq_queue, sizeof(int) * irq_queue_count); irq_queue_count = 0; REG_IME = IME_ENABLE; for(i = 0; i < irq_queue_count_copy; ++i) { params[0] = add_ref(irq_workers[irq_queue_copy[i]]); params[1] = create_list(irq_programs[irq_queue_copy[i]]); params[2] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, irq_programs[irq_queue_copy[i]]); params[2]->c.integers.num_a = irq_queue_copy[i]; vis_list_append(params + 1, &entry); entry.instance = &irq_instances[irq_queue_copy[i]]; entry.instance->in_progress_count = entry.instance->in_queue_count = 1000; vis_worker_do(params, &entry); } } const char ndsKeyLetters[15] = "ABESRLUD><XYMC"; #define NDS_MAX_KEY_BITS 14 int vis_held_keys(datum ** params, queue_entry * worker_entry) { datum * workparams[3]; datum * yes; char key_string[2] = " "; int held,i; scanKeys(); held = keysHeld(); workparams[0] = create_dict(worker_entry->instance->def->program); yes = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program); yes->c.integers.num_a = 1; for(i = 0; i < NDS_MAX_KEY_BITS; ++i) if(held & (1 << i)) { key_string[0] = ndsKeyLetters[i]; workparams[1] = make_string(key_string, -1, worker_entry->instance->def->program); workparams[2] = add_ref(yes); vis_dict_set(workparams, worker_entry); } params[0] = workparams[0]; release_ref(yes); return 0; } int vis_touch_position(datum ** params, queue_entry * worker_entry) { touchPosition touchXY; touchXY=touchReadXY(); params[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); params[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); params[0]->c.integers.num_a = touchXY.px; params[1]->c.integers.num_a = touchXY.py; return 0; }