Commit a01329d1ee30a22840908d26087a72f22355f496
authorMichel Pollet <buserror@gmail.com>
Sat, 26 Dec 2009 13:34:15 +0000 (13:34 +0000)
committerMichel Pollet <buserror@gmail.com>
Sat, 26 Dec 2009 13:34:15 +0000 (13:34 +0000)
Moved cycle timer code into it's own files

Signed-off-by: Michel Pollet <buserror@gmail.com>
5 files changed:
simavr/sim/sim_avr.c
simavr/sim/sim_avr.h
simavr/sim/sim_core.c
simavr/sim/sim_cycle_timers.c [new file with mode: 0644]
simavr/sim/sim_cycle_timers.h [new file with mode: 0644]

index 1682c2e40d0c505d8ffc860d0461062ea9840015..0512c2acf3c5fd03d4f2741e0ac2f7ddb91185f4 100644 (file)
@@ -121,134 +121,6 @@ void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, uint32_t address)
        memcpy(avr->flash + address, code, size);
 }
 
-void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
-{
-       if (addr > avr->ramend) {
-               printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x out of ram\n",
-                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
-               CRASH();
-       }
-       if (addr < 32) {
-               printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x low registers\n",
-                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
-               CRASH();
-       }
-#if AVR_STACK_WATCH
-       /*
-        * this checks that the current "function" is not doctoring the stack frame that is located
-        * higher on the stack than it should be. It's a sign of code that has overrun it's stack
-        * frame and is munching on it's own return address.
-        */
-       if (avr->stack_frame_index > 1 && addr > avr->stack_frame[avr->stack_frame_index-2].sp) {
-               printf("\e[31m%04x : munching stack SP %04x, A=%04x <= %02x\e[0m\n", avr->pc, _avr_sp_get(avr), addr, v);
-       }
-#endif
-       avr->data[addr] = v;
-}
-
-uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr)
-{
-       if (addr > avr->ramend) {
-               printf("*** Invalid read address PC=%04x SP=%04x O=%04x Address %04x out of ram (%04x)\n",
-                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, avr->ramend);
-               CRASH();
-       }
-       return avr->data[addr];
-}
-
-// converts a number of usec to a number of machine cycles, at current speed
-avr_cycle_count_t avr_usec_to_cycles(avr_t * avr, uint32_t usec)
-{
-       return avr->frequency * (avr_cycle_count_t)usec / 1000000;
-}
-
-uint32_t avr_cycles_to_usec(avr_t * avr, avr_cycle_count_t cycles)
-{
-       return 1000000 * cycles / avr->frequency;
-}
-
-// converts a number of hz (to megahertz etc) to a number of cycle
-avr_cycle_count_t avr_hz_to_cycles(avr_t * avr, uint32_t hz)
-{
-       return avr->frequency / hz;
-}
-
-void avr_cycle_timer_register(avr_t * avr, avr_cycle_count_t when, avr_cycle_timer_t timer, void * param)
-{
-       avr_cycle_timer_cancel(avr, timer, param);
-
-       if (avr->cycle_timer_map == 0xffffffff) {
-               fprintf(stderr, "avr_cycle_timer_register is full!\n");
-               return;
-       }
-       when += avr->cycle;
-       for (int i = 0; i < 32; i++)
-               if (!(avr->cycle_timer_map & (1 << i))) {
-                       avr->cycle_timer[i].timer = timer;
-                       avr->cycle_timer[i].param = param;
-                       avr->cycle_timer[i].when = when;
-                       avr->cycle_timer_map |= (1 << i);
-                       return;
-               }
-}
-
-void avr_cycle_timer_register_usec(avr_t * avr, uint32_t when, avr_cycle_timer_t timer, void * param)
-{
-       avr_cycle_timer_register(avr, avr_usec_to_cycles(avr, when), timer, param);
-}
-
-void avr_cycle_timer_cancel(avr_t * avr, avr_cycle_timer_t timer, void * param)
-{
-       if (!avr->cycle_timer_map)
-               return;
-       for (int i = 0; i < 32; i++)
-               if ((avr->cycle_timer_map & (1 << i)) &&
-                               avr->cycle_timer[i].timer == timer &&
-                               avr->cycle_timer[i].param == param) {
-                       avr->cycle_timer[i].timer = NULL;
-                       avr->cycle_timer[i].param = NULL;
-                       avr->cycle_timer[i].when = 0;
-                       avr->cycle_timer_map &= ~(1 << i);
-                       return;
-               }
-}
-
-/*
- * run thru all the timers, call the ones that needs it,
- * clear the ones that wants it, and calculate the next
- * potential cycle we could sleep for...
- */
-static avr_cycle_count_t avr_cycle_timer_check(avr_t * avr)
-{
-       if (!avr->cycle_timer_map)
-               return (avr_cycle_count_t)-1;
-
-       avr_cycle_count_t min = (avr_cycle_count_t)-1;
-
-       for (int i = 0; i < 32; i++) {
-               if (!(avr->cycle_timer_map & (1 << i)))
-                       continue;
-               // do it several times, in case we're late
-               while (avr->cycle_timer[i].when && avr->cycle_timer[i].when <= avr->cycle) {
-                       // call it
-                       avr->cycle_timer[i].when =
-                                       avr->cycle_timer[i].timer(avr,
-                                                       avr->cycle_timer[i].when,
-                                                       avr->cycle_timer[i].param);
-                       if (avr->cycle_timer[i].when == 0) {
-                               // clear it
-                               avr->cycle_timer[i].timer = NULL;
-                               avr->cycle_timer[i].param = NULL;
-                               avr->cycle_timer[i].when = 0;
-                               avr->cycle_timer_map &= ~(1 << i);
-                               break;
-                       }
-               }
-               if (avr->cycle_timer[i].when && avr->cycle_timer[i].when < min)
-                       min = avr->cycle_timer[i].when;
-       }
-       return min - avr->cycle;
-}
 
 int avr_run(avr_t * avr)
 {
@@ -283,7 +155,7 @@ int avr_run(avr_t * avr)
                        port->run(port);
                port = port->next;
        }
-       avr_cycle_count_t sleep = avr_cycle_timer_check(avr);
+       avr_cycle_count_t sleep = avr_cycle_timer_process(avr);
 
        avr->pc = new_pc;
 
index 5a96a194875dbf50058bb5fc1435f5e0f8a163f4..663a57faa6b4deff3bdf434cefe252ae0650a053 100644 (file)
@@ -235,19 +235,6 @@ void avr_set_command_register(avr_t * avr, avr_io_addr_t addr);
 // load code in the "flash"
 void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, uint32_t address);
 
-// converts a number of usec to a nunber of machine cycles, at current speed
-avr_cycle_count_t avr_usec_to_cycles(avr_t * avr, uint32_t usec);
-// converts a number of hz (to megahertz etc) to a number of cycle
-avr_cycle_count_t avr_hz_to_cycles(avr_t * avr, uint32_t hz);
-// converts back a number of cycles to usecs (for usleep)
-uint32_t avr_cycles_to_usec(avr_t * avr, avr_cycle_count_t cycles);
-
-// register for calling 'timer' in 'when' cycles
-void avr_cycle_timer_register(avr_t * avr, avr_cycle_count_t when, avr_cycle_timer_t timer, void * param);
-// register a timer to call in 'when' usec
-void avr_cycle_timer_register_usec(avr_t * avr, uint32_t when, avr_cycle_timer_t timer, void * param);
-// cancel a previously set timer
-void avr_cycle_timer_cancel(avr_t * avr, avr_cycle_timer_t timer, void * param);
 
 /*
  * these are accessors for avr->data but allows watchpoints to be set for gdb
@@ -265,6 +252,7 @@ void avr_sadly_crashed(avr_t *avr, uint8_t signal);
 #include "sim_regbit.h"
 #include "sim_interrupts.h"
 #include "sim_irq.h"
+#include "sim_cycle_timers.h"
 
 #endif /*__SIM_AVR_H__*/
 
index e7e1f6f019f7c269fa25d8899ff049ccacd8fc96..ee95552831eb2b21d9476e35769ff926a32f19db 100644 (file)
@@ -84,6 +84,41 @@ int donttrace = 0;
 #define SREG()
 #endif
 
+void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
+{
+       if (addr > avr->ramend) {
+               printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x out of ram\n",
+                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
+               CRASH();
+       }
+       if (addr < 32) {
+               printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x low registers\n",
+                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
+               CRASH();
+       }
+#if AVR_STACK_WATCH
+       /*
+        * this checks that the current "function" is not doctoring the stack frame that is located
+        * higher on the stack than it should be. It's a sign of code that has overrun it's stack
+        * frame and is munching on it's own return address.
+        */
+       if (avr->stack_frame_index > 1 && addr > avr->stack_frame[avr->stack_frame_index-2].sp) {
+               printf("\e[31m%04x : munching stack SP %04x, A=%04x <= %02x\e[0m\n", avr->pc, _avr_sp_get(avr), addr, v);
+       }
+#endif
+       avr->data[addr] = v;
+}
+
+uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr)
+{
+       if (addr > avr->ramend) {
+               printf("*** Invalid read address PC=%04x SP=%04x O=%04x Address %04x out of ram (%04x)\n",
+                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, avr->ramend);
+               CRASH();
+       }
+       return avr->data[addr];
+}
+
 /*
  * Set a register (r < 256)
  * if it's an IO regisrer (> 31) also (try to) call any callback that was
diff --git a/simavr/sim/sim_cycle_timers.c b/simavr/sim/sim_cycle_timers.c
new file mode 100644 (file)
index 0000000..f2161d9
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+       sim_cycle_timers.c
+
+       Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr is free software: you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation, either version 3 of the License, or
+       (at your option) any later version.
+
+       simavr is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "sim_cycle_timers.h"
+
+void avr_cycle_timer_register(avr_t * avr, avr_cycle_count_t when, avr_cycle_timer_t timer, void * param)
+{
+       avr_cycle_timer_cancel(avr, timer, param);
+
+       if (avr->cycle_timer_map == 0xffffffff) {
+               fprintf(stderr, "avr_cycle_timer_register is full!\n");
+               return;
+       }
+       when += avr->cycle;
+       for (int i = 0; i < 32; i++)
+               if (!(avr->cycle_timer_map & (1 << i))) {
+                       avr->cycle_timer[i].timer = timer;
+                       avr->cycle_timer[i].param = param;
+                       avr->cycle_timer[i].when = when;
+                       avr->cycle_timer_map |= (1 << i);
+                       return;
+               }
+}
+
+void avr_cycle_timer_register_usec(avr_t * avr, uint32_t when, avr_cycle_timer_t timer, void * param)
+{
+       avr_cycle_timer_register(avr, avr_usec_to_cycles(avr, when), timer, param);
+}
+
+void avr_cycle_timer_cancel(avr_t * avr, avr_cycle_timer_t timer, void * param)
+{
+       if (!avr->cycle_timer_map)
+               return;
+       for (int i = 0; i < 32; i++)
+               if ((avr->cycle_timer_map & (1 << i)) &&
+                               avr->cycle_timer[i].timer == timer &&
+                               avr->cycle_timer[i].param == param) {
+                       avr->cycle_timer[i].timer = NULL;
+                       avr->cycle_timer[i].param = NULL;
+                       avr->cycle_timer[i].when = 0;
+                       avr->cycle_timer_map &= ~(1 << i);
+                       return;
+               }
+}
+
+/*
+ * run thru all the timers, call the ones that needs it,
+ * clear the ones that wants it, and calculate the next
+ * potential cycle we could sleep for...
+ */
+avr_cycle_count_t avr_cycle_timer_process(avr_t * avr)
+{
+       if (!avr->cycle_timer_map)
+               return (avr_cycle_count_t)-1;
+
+       avr_cycle_count_t min = (avr_cycle_count_t)-1;
+
+       for (int i = 0; i < 32; i++) {
+               if (!(avr->cycle_timer_map & (1 << i)))
+                       continue;
+               // do it several times, in case we're late
+               while (avr->cycle_timer[i].when && avr->cycle_timer[i].when <= avr->cycle) {
+                       // call it
+                       avr->cycle_timer[i].when =
+                                       avr->cycle_timer[i].timer(avr,
+                                                       avr->cycle_timer[i].when,
+                                                       avr->cycle_timer[i].param);
+                       if (avr->cycle_timer[i].when == 0) {
+                               // clear it
+                               avr->cycle_timer[i].timer = NULL;
+                               avr->cycle_timer[i].param = NULL;
+                               avr->cycle_timer[i].when = 0;
+                               avr->cycle_timer_map &= ~(1 << i);
+                               break;
+                       }
+               }
+               if (avr->cycle_timer[i].when && avr->cycle_timer[i].when < min)
+                       min = avr->cycle_timer[i].when;
+       }
+       return min - avr->cycle;
+}
diff --git a/simavr/sim/sim_cycle_timers.h b/simavr/sim/sim_cycle_timers.h
new file mode 100644 (file)
index 0000000..8496b6c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+       sim_cycle_timers.h
+
+       Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
+
+       This file is part of simavr.
+
+       simavr is free software: you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation, either version 3 of the License, or
+       (at your option) any later version.
+
+       simavr is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with simavr.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __SIM_CYCLE_TIMERS_H___
+#define __SIM_CYCLE_TIMERS_H___
+
+#include "sim_avr.h"
+
+// converts a number of usec to a number of machine cycles, at current speed
+static inline avr_cycle_count_t avr_usec_to_cycles(avr_t * avr, uint32_t usec)
+{
+       return avr->frequency * (avr_cycle_count_t)usec / 1000000;
+}
+
+// converts back a number of cycles to usecs (for usleep)
+static inline uint32_t avr_cycles_to_usec(avr_t * avr, avr_cycle_count_t cycles)
+{
+       return 1000000 * cycles / avr->frequency;
+}
+
+// converts a number of hz (to megahertz etc) to a number of cycle
+static inline avr_cycle_count_t avr_hz_to_cycles(avr_t * avr, uint32_t hz)
+{
+       return avr->frequency / hz;
+}
+
+// register for calling 'timer' in 'when' cycles
+void avr_cycle_timer_register(avr_t * avr, avr_cycle_count_t when, avr_cycle_timer_t timer, void * param);
+// register a timer to call in 'when' usec
+void avr_cycle_timer_register_usec(avr_t * avr, uint32_t when, avr_cycle_timer_t timer, void * param);
+// cancel a previously set timer
+void avr_cycle_timer_cancel(avr_t * avr, avr_cycle_timer_t timer, void * param);
+
+
+//
+// Private, called from the core
+//
+avr_cycle_count_t avr_cycle_timer_process(avr_t * avr);
+
+#endif /* __SIM_CYCLE_TIMERS_H___ */