Mercurial > repos > rhope
view ds_hardware.c @ 75:0083b2f7b3c7
Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 06 Jul 2010 07:52:59 -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; }