misc: Point to correct simavr include dirs
[simavr] / simavr / sim / sim_io.c
index b23aad4..e2f4f62 100644 (file)
@@ -23,6 +23,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
+#include <stdint.h>
 #include "sim_io.h"
 
 int
@@ -61,10 +63,8 @@ avr_register_io_read(
        avr_io_addr_t a = AVR_DATA_TO_IO(addr);
        if (avr->io[a].r.param || avr->io[a].r.c) {
                if (avr->io[a].r.param != param || avr->io[a].r.c != readp) {
-                       fprintf(stderr,
-                                       "Error: avr_register_io_read(): Already registered, refusing to override.\n");
-                       fprintf(stderr,
-                                       "Error: avr_register_io_read(%04x : %p/%p): %p/%p\n", a,
+                       AVR_LOG(avr, LOG_ERROR, "IO: avr_register_io_read(): Already registered, refusing to override.\n");
+                       AVR_LOG(avr, LOG_ERROR, "IO: avr_register_io_read(%04x : %p/%p): %p/%p\n", a,
                                        avr->io[a].r.c, avr->io[a].r.param, readp, param);
                        abort();
                }
@@ -80,7 +80,7 @@ _avr_io_mux_write(
                uint8_t v,
                void * param)
 {
-       int io = (int)param;
+       int io = (intptr_t)param;
        for (int i = 0; i < avr->io_shared_io[io].used; i++) {
                avr_io_write_t c = avr->io_shared_io[io].io[i].c;
                if (c)
@@ -97,6 +97,11 @@ avr_register_io_write(
 {
        avr_io_addr_t a = AVR_DATA_TO_IO(addr);
 
+       if (a >= MAX_IOs) {
+               AVR_LOG(avr, LOG_ERROR, "IO: avr_register_io_write(): IO address 0x%04x out of range (max 0x%04x).\n",
+                                       a, MAX_IOs);
+               abort();
+       }
        /*
         * Verifying that some other piece of code is not installed to watch write
         * on this address. If there is, this code installs a "dispatcher" callback
@@ -108,23 +113,20 @@ avr_register_io_write(
                        if (avr->io[a].w.c != _avr_io_mux_write) {
                                int no = avr->io_shared_io_count++;
                                if (avr->io_shared_io_count > 4) {
-                                       fprintf(stderr,
-                                                       "Error: avr_register_io_write(): Too many shared IO registers.\n");
+                                       AVR_LOG(avr, LOG_ERROR, "IO: avr_register_io_write(): Too many shared IO registers.\n");
                                        abort();
                                }
-                               fprintf(stderr,
-                                               "Note: avr_register_io_write(%04x): Installing muxer on register.\n", addr);
+                               AVR_LOG(avr, LOG_TRACE, "IO: avr_register_io_write(%04x): Installing muxer on register.\n", addr);
                                avr->io_shared_io[no].used = 1;
                                avr->io_shared_io[no].io[0].param = avr->io[a].w.param;
                                avr->io_shared_io[no].io[0].c = avr->io[a].w.c;
-                               avr->io[a].w.param = (void*)no;
+                               avr->io[a].w.param = (void*)(intptr_t)no;
                                avr->io[a].w.c = _avr_io_mux_write;
                        }
-                       int no = (int)avr->io[a].w.param;
+                       int no = (intptr_t)avr->io[a].w.param;
                        int d = avr->io_shared_io[no].used++;
                        if (avr->io_shared_io[no].used > 4) {
-                               fprintf(stderr,
-                                               "Error: avr_register_io_write(): Too many callbacks on %04x.\n", addr);
+                               AVR_LOG(avr, LOG_ERROR, "IO: avr_register_io_write(): Too many callbacks on %04x.\n", addr);
                                abort();
                        }
                        avr->io_shared_io[no].io[d].param = param;
@@ -160,7 +162,7 @@ avr_iomem_getirq(
 {
        avr_io_addr_t a = AVR_DATA_TO_IO(addr);
        if (avr->io[a].irq == NULL) {
-               avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, NULL /* TODO: names*/);
+               avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, NULL);
                // mark the pin ones as filtered, so they only are raised when changing
                for (int i = 0; i < 8; i++)
                        avr->io[a].irq[i].flags |= IRQ_FLAG_FILTERED;
@@ -173,13 +175,60 @@ avr_io_setirqs(
                avr_io_t * io,
                uint32_t ctl,
                int count,
-               avr_irq_t * irqs)
+               avr_irq_t * irqs )
 {
        // allocate this module's IRQ
        io->irq_count = count;
-       io->irq = irqs ? irqs :
-               avr_alloc_irq(&io->avr->irq_pool, 0,
-                               count, NULL /* TODO: names*/);
+
+       if (!irqs) {
+               const char ** irq_names = NULL;
+
+               if (io->irq_names) {
+                       irq_names = malloc(count * sizeof(char*));
+                       memset(irq_names, 0, count * sizeof(char*));
+                       char buf[64];
+                       for (int i = 0; i < count; i++) {
+                               /*
+                                * this bit takes the io module 'kind' ("port")
+                                * the IRQ name ("=0") and the last character of the ioctl ('p','o','r','A')
+                                * to create a full name "=porta.0"
+                                */
+                               char * dst = buf;
+                               // copy the 'flags' of the name out
+                               const char * kind = io->irq_names[i];
+                               while (!isalpha(*kind))
+                                       *dst++ = *kind++;
+                               // add avr name
+//                             strcpy(dst, io->avr->mmcu);
+                               strcpy(dst, "avr");
+                               dst += strlen(dst);
+                               *dst ++ = '.';
+                               // add module 'kind'
+                               strcpy(dst, io->kind);
+                               dst += strlen(dst);
+                               // add port name, if any
+                               if ((ctl & 0xff) > ' ')
+                                       *dst ++ = tolower(ctl & 0xff);
+                               *dst ++ = '.';
+                               // add the rest of the irq name
+                               strcpy(dst, kind);
+                               dst += strlen(dst);
+                               *dst = 0;
+
+//                             printf("%s\n", buf);
+                               irq_names[i] = strdup(buf);
+                       }
+               }
+               irqs = avr_alloc_irq(&io->avr->irq_pool, 0,
+                                               count, irq_names);
+               if (irq_names) {
+                       for (int i = 0; i < count; i++)
+                               free((char*)irq_names[i]);
+                       free((char*)irq_names);
+               }
+       }
+
+       io->irq = irqs;
        io->irq_ioctl_get = ctl;
        return io->irq;
 }