#include "sim_cycle_timers.h"
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);
+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);
enum {
// SREG bit indexes
} avr_symbol_t;
// locate the maker for mcu "name" and allocates a new avr instance
-avr_t * avr_make_mcu_by_name(const char *name);
+avr_t *
+avr_make_mcu_by_name(
+ const char *name);
// initializes a new AVR instance. Will call the IO registers init(), and then reset()
-int avr_init(avr_t * avr);
+int
+avr_init(
+ avr_t * avr);
// resets the AVR, and the IO modules
-void avr_reset(avr_t * avr);
+void
+avr_reset(
+ avr_t * avr);
// run one cycle of the AVR, sleep if necessary
-int avr_run(avr_t * avr);
+int
+avr_run(
+ avr_t * avr);
// finish any pending operations
-void avr_terminate(avr_t * avr);
+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);
+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);
+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);
-
+void
+avr_loadcode(
+ avr_t * avr,
+ uint8_t * code,
+ uint32_t size,
+ uint32_t address);
/*
* these are accessors for avr->data but allows watchpoints to be set for gdb
* IO modules use that to set values to registers, and the AVR core decoder uses
* that to register "public" read by instructions.
*/
-void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v);
-uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr);
+void
+avr_core_watch_write(
+ avr_t *avr,
+ uint16_t addr,
+ uint8_t v);
+uint8_t
+avr_core_watch_read(
+ avr_t *avr,
+ uint16_t addr);
// called when the core has detected a crash somehow.
// this might activate gdb server
-void avr_sadly_crashed(avr_t *avr, uint8_t signal);
+void
+avr_sadly_crashed(
+ avr_t *avr,
+ uint8_t signal);
/*
#include "sim_time.h"
#include "sim_cycle_timers.h"
-#define TIMER_COUNT sizeof(cycle_timer)
// no sanity checks checking here, on purpose
-static void avr_cycle_timer_insert(avr_t * avr, avr_cycle_count_t when, avr_cycle_timer_t timer, void * param)
+static void
+avr_cycle_timer_insert(
+ avr_t * avr,
+ avr_cycle_count_t when,
+ avr_cycle_timer_t timer,
+ void * param)
{
avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
pool->count++;
}
-void avr_cycle_timer_register(avr_t * avr, avr_cycle_count_t when, avr_cycle_timer_t timer, void * param)
+void
+avr_cycle_timer_register(
+ avr_t * avr,
+ avr_cycle_count_t when,
+ avr_cycle_timer_t timer,
+ void * param)
{
avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
avr_cycle_timer_insert(avr, when, timer, param);
}
-void avr_cycle_timer_register_usec(avr_t * avr, uint32_t when, avr_cycle_timer_t timer, void * param)
+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)
+void
+avr_cycle_timer_cancel(
+ avr_t * avr,
+ avr_cycle_timer_t timer,
+ void * param)
{
avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
* cycles left for it to fire, and if not present, return zero
*/
avr_cycle_count_t
-avr_cycle_timer_status(avr_t * avr, avr_cycle_timer_t timer, void * param)
+avr_cycle_timer_status(
+ avr_t * avr,
+ avr_cycle_timer_t timer,
+ void * param)
{
avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
* 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)
+avr_cycle_count_t
+avr_cycle_timer_process(
+ avr_t * avr)
{
avr_cycle_timer_pool_t * pool = &avr->cycle_timers;
/*
sim_cycle_timers.h
- Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
+ Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
This file is part of simavr.
#define MAX_CYCLE_TIMERS 32
-typedef avr_cycle_count_t (*avr_cycle_timer_t)(struct avr_t * avr, avr_cycle_count_t when, void * param);
+typedef avr_cycle_count_t (*avr_cycle_timer_t)(
+ struct avr_t * avr,
+ avr_cycle_count_t when,
+ void * param);
typedef struct avr_cycle_timer_slot_t {
avr_cycle_count_t when;
// register for calling 'timer' in 'when' cycles
-void avr_cycle_timer_register(struct avr_t * avr, avr_cycle_count_t when, avr_cycle_timer_t timer, void * param);
+void
+avr_cycle_timer_register(
+ struct 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(struct avr_t * avr, uint32_t when, avr_cycle_timer_t timer, void * param);
+void
+avr_cycle_timer_register_usec(
+ struct avr_t * avr,
+ uint32_t when,
+ avr_cycle_timer_t timer,
+ void * param);
// cancel a previously set timer
-void avr_cycle_timer_cancel(struct avr_t * avr, avr_cycle_timer_t timer, void * param);
+void
+avr_cycle_timer_cancel(
+ struct avr_t * avr,
+ avr_cycle_timer_t timer,
+ void * param);
/*
* Check to see if a timer is present, if so, return the number (+1) of
* cycles left for it to fire, and if not present, return zero
*/
avr_cycle_count_t
-avr_cycle_timer_status(struct avr_t * avr, avr_cycle_timer_t timer, void * param);
-
+avr_cycle_timer_status(
+ struct avr_t * avr,
+ avr_cycle_timer_t timer,
+ void * param);
//
// Private, called from the core
//
-avr_cycle_count_t avr_cycle_timer_process(struct avr_t * avr);
+avr_cycle_count_t
+avr_cycle_timer_process(
+ struct avr_t * avr);
#ifdef __cplusplus
};
/*
sim_interrupts.c
- Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
+ Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
This file is part of simavr.
#define INT_FIFO_SIZE (sizeof(avr->pending) / sizeof(avr_int_vector_t *))
#define INT_FIFO_MOD(_v) ((_v) & (INT_FIFO_SIZE - 1))
-void avr_register_vector(avr_t *avr, avr_int_vector_t * vector)
+void
+avr_register_vector(
+ avr_t *avr,
+ avr_int_vector_t * vector)
{
if (vector->vector) {
vector->irq.irq = vector->vector;
}
}
-int avr_has_pending_interrupts(avr_t * avr)
+int
+avr_has_pending_interrupts(
+ avr_t * avr)
{
return avr->pending_r != avr->pending_w;
}
-int avr_is_interrupt_pending(avr_t * avr, avr_int_vector_t * vector)
+int
+avr_is_interrupt_pending(
+ avr_t * avr,
+ avr_int_vector_t * vector)
{
return vector->pending;
}
-int avr_is_interrupt_enabled(avr_t * avr, avr_int_vector_t * vector)
+int
+avr_is_interrupt_enabled(
+ avr_t * avr,
+ avr_int_vector_t * vector)
{
return avr_regbit_get(avr, vector->enable);
}
-int avr_raise_interrupt(avr_t * avr, avr_int_vector_t * vector)
+int
+avr_raise_interrupt(
+ avr_t * avr,
+ avr_int_vector_t * vector)
{
if (!vector || !vector->vector)
return 0;
return 1;
}
-void avr_clear_interrupt(avr_t * avr, avr_int_vector_t * vector)
+void
+avr_clear_interrupt(
+ avr_t * avr,
+ avr_int_vector_t * vector)
{
if (!vector)
return;
avr_regbit_clear(avr, vector->raised);
}
-int avr_clear_interrupt_if(avr_t * avr, avr_int_vector_t * vector, uint8_t old)
+int
+avr_clear_interrupt_if(
+ avr_t * avr,
+ avr_int_vector_t * vector,
+ uint8_t old)
{
if (avr_regbit_get(avr, vector->raised)) {
avr_clear_interrupt(avr, vector);
return 0;
}
-avr_irq_t * avr_get_interrupt_irq(avr_t * avr, uint8_t v)
+avr_irq_t *
+avr_get_interrupt_irq(
+ avr_t * avr,
+ uint8_t v)
{
for (int i = 0; i < avr->vector_count; i++)
if (avr->vector[i]->vector == v)
* check whether interrupts are pending. If so, check if the interrupt "latency" is reached,
* and if so triggers the handlers and jump to the vector.
*/
-void avr_service_interrupts(avr_t * avr)
+void
+avr_service_interrupts(
+ avr_t * avr)
{
if (!avr->sreg[S_I])
return;
/*
sim_interrupts.h
- Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
+ Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
This file is part of simavr.
* Interrupt Helper Functions
*/
// register an interrupt vector. It's only needed if you want to use the "r_raised" flags
-void avr_register_vector(avr_t *avr, avr_int_vector_t * vector);
+void
+avr_register_vector(
+ avr_t *avr,
+ avr_int_vector_t * vector);
// raise an interrupt (if enabled). The interrupt is latched and will be called later
// return non-zero if the interrupt was raised and is now pending
-int avr_raise_interrupt(avr_t * avr, avr_int_vector_t * vector);
+int
+avr_raise_interrupt(
+ avr_t * avr,
+ avr_int_vector_t * vector);
// return non-zero if the AVR core has any pending interrupts
-int avr_has_pending_interrupts(avr_t * avr);
+int
+avr_has_pending_interrupts(
+ avr_t * avr);
// return nonzero if a specific interrupt vector is pending
-int avr_is_interrupt_pending(avr_t * avr, avr_int_vector_t * vector);
+int
+avr_is_interrupt_pending(
+ avr_t * avr,
+ avr_int_vector_t * vector);
// clear the "pending" status of an interrupt
-void avr_clear_interrupt(avr_t * avr, avr_int_vector_t * vector);
+void
+avr_clear_interrupt(
+ avr_t * avr,
+ avr_int_vector_t * vector);
// called by the core at each cycle to check whether an interrupt is pending
-void avr_service_interrupts(avr_t * avr);
+void
+avr_service_interrupts(
+ avr_t * avr);
// clear the interrupt (inc pending) if "raised" flag is 1
-int avr_clear_interrupt_if(avr_t * avr, avr_int_vector_t * vector, uint8_t old);
+int
+avr_clear_interrupt_if(
+ avr_t * avr,
+ avr_int_vector_t * vector,
+ uint8_t old);
// return the IRQ that is raised when the vector is enabled and called/cleared
// this allows tracing of pending interrupts
-avr_irq_t * avr_get_interrupt_irq(avr_t * avr, uint8_t v);
+avr_irq_t *
+avr_get_interrupt_irq(
+ avr_t * avr,
+ uint8_t v);
#ifdef __cplusplus
};