obj:
@mkdir -p obj
-obj/sim_%.o : cores/sim_%.h ${wildcard cores/*.h} ${wildcard sim/*.h}
obj/sim_%.o : cores/sim_%.c
- @gcc $(CFLAGS) \
+ @gcc $(CFLAGS) -MD \
-I${AVR_ROOT}/include/ \
$< -c -o $@
@echo CORE $<
-obj/%.o: %.h sim/*.h
obj/%.o: %.c
- @gcc $(CFLAGS) \
+ @gcc $(CFLAGS) -MD \
$< -c -o $@
@echo CC $<
clean:
rm -rf ${target} obj *.a
+# include the dependency files generated by gcc, if any
+-include ${wildcard obj/*.d}
+
return 0;
}
-static void avr_eeprom_write(avr_t * avr, uint8_t addr, uint8_t v, void * param)
+static void avr_eeprom_write(avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
avr_eeprom_t * p = (avr_eeprom_t *)param;
uint8_t eempe = avr_regbit_get(avr, p->eempe);
#include <stdio.h>
#include "avr_ioport.h"
-static uint8_t avr_ioport_read(struct avr_t * avr, uint8_t addr, void * param)
+static uint8_t avr_ioport_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
{
avr_ioport_t * p = (avr_ioport_t *)param;
uint8_t v = avr->data[addr];
return v;
}
-static void avr_ioport_write(struct avr_t * avr, uint8_t addr, uint8_t v, void * param)
+static void avr_ioport_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
avr_ioport_t * p = (avr_ioport_t *)param;
uint8_t oldv = avr->data[addr];
typedef struct avr_ioport_t {
avr_io_t io;
char name;
- uint8_t r_port;
- uint8_t r_ddr;
- uint8_t r_pin;
+ avr_io_addr_t r_port;
+ avr_io_addr_t r_ddr;
+ avr_io_addr_t r_pin;
avr_int_vector_t pcint; // PCINT vector
- uint8_t r_pcint; // pcint 8 pins mask
+ avr_io_addr_t r_pcint; // pcint 8 pins mask
} avr_ioport_t;
void avr_ioport_init(avr_t * avr, avr_ioport_t * port);
#include <stdio.h>
#include "avr_spi.h"
-static uint8_t avr_spi_read(struct avr_t * avr, uint8_t addr, void * param)
+static uint8_t avr_spi_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
{
avr_spi_t * p = (avr_spi_t *)param;
uint8_t v = p->input_data_register;
return v;
}
-static void avr_spi_write(struct avr_t * avr, uint8_t addr, uint8_t v, void * param)
+static void avr_spi_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
avr_spi_t * p = (avr_spi_t *)param;
char name;
avr_regbit_t disabled; // bit in the PRR
- uint8_t r_spdr; // data register
- uint8_t r_spcr; // control register
- uint8_t r_spsr; // status register
+ avr_io_addr_t r_spdr; // data register
+ avr_io_addr_t r_spcr; // control register
+ avr_io_addr_t r_spsr; // status register
avr_regbit_t spe; // spi enable
avr_regbit_t mstr; // master/slave
return p->compb_cycles ? when + p->compb_cycles : 0;
}
-static uint8_t avr_timer8_tcnt_read(struct avr_t * avr, uint8_t addr, void * param)
+static uint8_t avr_timer8_tcnt_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
{
//avr_timer8_t * p = (avr_timer8_t *)param;
// made to trigger potential watchpoints
return avr_core_watch_read(avr, addr);
}
-static void avr_timer8_write(struct avr_t * avr, uint8_t addr, uint8_t v, void * param)
+static void avr_timer8_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
avr_timer8_t * p = (avr_timer8_t *)param;
char name;
avr_regbit_t disabled; // bit in the PRR
- uint8_t r_ocra, r_ocrb, r_ocrc, r_tcnt;
+ avr_io_addr_t r_ocra, r_ocrb, r_ocrc, r_tcnt;
avr_regbit_t wgm[4];
avr_regbit_t cs[4];
return 0;
}
-static uint8_t avr_uart_read(struct avr_t * avr, uint8_t addr, void * param)
+static uint8_t avr_uart_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
{
avr_uart_t * p = (avr_uart_t *)param;
return v;
}
-static void avr_uart_write(struct avr_t * avr, uint8_t addr, uint8_t v, void * param)
+static void avr_uart_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
avr_uart_t * p = (avr_uart_t *)param;
char name;
avr_regbit_t disabled; // bit in the PRR
- uint8_t r_udr;
- uint8_t r_ucsra;
- uint8_t r_ucsrb;
- uint8_t r_ucsrc;
+ avr_io_addr_t r_udr;
+ avr_io_addr_t r_ucsra;
+ avr_io_addr_t r_ucsrb;
+ avr_io_addr_t r_ucsrc;
avr_regbit_t rxen; // receive enabled
avr_regbit_t txen; // transmit enable
- uint8_t r_ubrrl,r_ubrrh;
+ avr_io_addr_t r_ubrrl,r_ubrrh;
avr_int_vector_t rxc;
avr_int_vector_t txc;
#include <stdint.h>
typedef uint64_t avr_cycle_count_t;
+typedef uint16_t avr_io_addr_t;
struct avr_t;
-typedef uint8_t (*avr_io_read_t)(struct avr_t * avr, uint8_t addr, void * param);
-typedef void (*avr_io_write_t)(struct avr_t * avr, uint8_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);
typedef avr_cycle_count_t (*avr_cycle_timer_t)(struct avr_t * avr, avr_cycle_count_t when, void * param);
enum {
/*
* callback when specific IO registers are read/written
+ * these should probably be allocated dynamically in init()..
*/
struct {
void * param;
#endif
// DEBUG ONLY
- // keeps track of wich registers gets touched by instructions
+ // keeps track of which registers gets touched by instructions
// reset before each new instructions. Allows meaningful traces
uint32_t touched[256 / 32]; // debug
avr->io_port = io;
}
-void avr_register_io_read(avr_t *avr, uint8_t addr, avr_io_read_t readp, void * param)
+void avr_register_io_read(avr_t *avr, avr_io_addr_t addr, avr_io_read_t readp, void * param)
{
avr->ior[AVR_DATA_TO_IO(addr)].param = param;
avr->ior[AVR_DATA_TO_IO(addr)].r = readp;
}
-void avr_register_io_write(avr_t *avr, uint8_t addr, avr_io_write_t writep, void * param)
+void avr_register_io_write(avr_t *avr, avr_io_addr_t addr, avr_io_write_t writep, void * param)
{
avr->iow[AVR_DATA_TO_IO(addr)].param = param;
avr->iow[AVR_DATA_TO_IO(addr)].w = writep;
// one after instanciation, for whatever purpose...
void avr_register_io(avr_t *avr, avr_io_t * io);
// register a callback for when IO register "addr" is read
-void avr_register_io_read(avr_t *avr, uint8_t addr, avr_io_read_t read, void * param);
+void avr_register_io_read(avr_t *avr, avr_io_addr_t addr, avr_io_read_t read, void * param);
// register a callback for when the IO register is written. callback has to set the memory itself
-void avr_register_io_write(avr_t *avr, uint8_t addr, avr_io_write_t write, void * param);
+void avr_register_io_write(avr_t *avr, avr_io_addr_t addr, avr_io_write_t write, void * param);
// call every IO modules until one responds to this
int avr_ioctl(avr_t *avr, uint32_t ctl, void * io_param);
// get the specific irq for a module, check AVR_IOCTL_IOPORT_GETIRQ for example
* (or consecutive bits). This allows a way to set/get/clear them.
* gcc is happy passing these as register value, so you don't need to
* use a pointer when passing them along to functions.
+ *
+ * 9 bits ought to be enough, as it's the maximum I've seen (atmega2560)
*/
typedef struct avr_regbit_t {
- unsigned long reg : 8, bit : 3, mask : 8;
+ unsigned long reg : 9, bit : 3, mask : 8;
} avr_regbit_t;
/*