Silence gcc warnings by using PRIu64 in CRASH() printf().
[simavr] / simavr / sim / sim_avr.h
index 663a57f..3bb7eae 100644 (file)
 #define __SIM_AVR_H__
 
 #include <stdint.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sim_irq.h"
 
 typedef uint64_t avr_cycle_count_t;
 typedef uint16_t       avr_io_addr_t;
 
+// printf() conversion specifier for avr_cycle_count_t
+#define PRI_avr_cycle_count PRIu64
+
 struct avr_t;
 typedef uint8_t (*avr_io_read_t)(struct avr_t * avr, avr_io_addr_t addr, void * param);
 typedef void (*avr_io_write_t)(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param);
@@ -78,12 +88,16 @@ typedef struct avr_t {
        uint8_t         vector_size;
        uint8_t         signature[3];
        uint8_t         fuse[4];
+       avr_io_addr_t   rampz;  // optional, only for ELPM/SPM on >64Kb cores
+       avr_io_addr_t   eind;   // optional, only for EIJMP/EICALL on >64Kb cores
 
        // filled by the ELF data, this allow tracking of invalid jumps
        uint32_t                        codeend;
 
        int                                     state;          // stopped, running, sleeping
        uint32_t                        frequency;      // frequency we are running at
+       // mostly used by the ADC for now
+       uint32_t                        vcc,avcc,aref; // (optional) voltages in millivolts
 
        // cycles gets incremented when sleeping and when running; it corresponds
        // not only to "cycles that runs" but also "cycles that might have run"
@@ -92,13 +106,39 @@ typedef struct avr_t {
        
        // called at init time
        void (*init)(struct avr_t * avr);
+       // called at init time (for special purposes like using a memory mapped file as flash see: simduino)
+       void (*special_init)(struct avr_t * avr);
+       // called at termination time ( to clean special initalizations)
+       void (*special_deinit)(struct avr_t * avr);
        // called at reset time
        void (*reset)(struct avr_t * avr);
 
+       /*!
+        * Default AVR core run function.
+        * Two modes are available, a "raw" run that goes as fast as
+        * it can, and a "gdb" mode that also watchouts for gdb events
+        * and is a little bit slower.
+        */
+       void (*run)(struct avr_t * avr);
+
+       /*!
+        * Sleep default behaviour.
+        * In "raw" mode, it calls usleep, in gdb mode, it waits
+        * for howLong for gdb command on it's sockets.
+        */
+       void (*sleep)(struct avr_t * avr, avr_cycle_count_t howLong);
+
+       /*!
+        * Every IRQs will be stored in this pool. It is not
+        * mandatory (yet) but will allow listing IRQs and their connections
+        */
+       avr_irq_pool_t  irq_pool;
+
        // Mirror of the SREG register, to facilitate the access to bits
        // in the opcode decoder.
        // This array is re-synthetized back/forth when SREG changes
        uint8_t         sreg[8];
+       uint8_t         i_shadow;       // used to detect edges on I flag
 
        /* 
         * ** current PC **
@@ -130,6 +170,24 @@ typedef struct avr_t {
                } w;
        } io[MAX_IOs];
 
+       /*
+        * This block allows sharing of the IO write/read on addresses between
+        * multiple callbacks. In 99% of case it's not needed, however on the tiny*
+        * (tiny85 at last) some registers have bits that are used by different
+        * IO modules.
+        * If this case is detected, a special "dispatch" callback is installed that
+        * will handle this particular case, without impacting the performance of the
+        * other, normal cases...
+        */
+       int     io_shared_io_count;
+       struct {
+               int used;
+               struct {
+                       void * param;
+                       void * c;
+               } io[4];
+       } io_shared_io[4];
+
        // flash memory (initialized to 0xff, and code loaded into it)
        uint8_t *       flash;
        // this is the general purpose registers, IO registers, and SRAM
@@ -143,6 +201,7 @@ typedef struct avr_t {
        // these timers are one shots, then get cleared if the timer function returns zero,
        // they get reset if the callback function returns a new cycle number
        uint32_t        cycle_timer_map;
+       avr_cycle_count_t next_cycle_timer;
        struct {
                avr_cycle_count_t       when;
                avr_cycle_timer_t       timer;
@@ -232,6 +291,11 @@ void avr_terminate(avr_t * avr);
 // set an IO register to receive commands from the AVR firmware
 // it's optional, and uses the ELF tags
 void avr_set_command_register(avr_t * avr, avr_io_addr_t addr);
+
+// specify the "console register" -- output sent to this register
+// is printed on the simulator console, without using a UART
+void avr_set_console_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);
 
@@ -248,10 +312,22 @@ uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr);
 // this might activate gdb server
 void avr_sadly_crashed(avr_t *avr, uint8_t signal);
 
+
+/*
+ * These are callbacks for the two 'main' bahaviour in simavr
+ */
+void avr_callback_sleep_gdb(avr_t * avr, avr_cycle_count_t howLong);
+void avr_callback_run_gdb(avr_t * avr);
+void avr_callback_sleep_raw(avr_t * avr, avr_cycle_count_t howLong);
+void avr_callback_run_raw(avr_t * avr);
+
+#ifdef __cplusplus
+};
+#endif
+
 #include "sim_io.h"
 #include "sim_regbit.h"
 #include "sim_interrupts.h"
-#include "sim_irq.h"
 #include "sim_cycle_timers.h"
 
 #endif /*__SIM_AVR_H__*/