File: avrcore.h

package info (click to toggle)
simulavr 0.1.2.2-6.2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 2,760 kB
  • ctags: 3,179
  • sloc: ansic: 19,986; sh: 3,623; python: 3,528; makefile: 406; asm: 308; yacc: 145; lex: 48
file content (469 lines) | stat: -rw-r--r-- 12,929 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
/*
 * $Id: avrcore.h,v 1.15 2004/01/30 07:09:56 troth Exp $
 *
 ****************************************************************************
 *
 * simulavr - A simulator for the Atmel AVR family of microcontrollers.
 * Copyright (C) 2001, 2002, 2003, 2004  Theodore A. Roth
 *
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 ****************************************************************************
 */

#ifndef SIM_AVRCORE_H
#define SIM_AVRCORE_H

#include "intvects.h"

#include "display.h"

/****************************************************************************\
 *
 * AvrCore(AvrClass) Definition
 *
\****************************************************************************/

extern int global_debug_inst_output;

typedef enum
{
    STATE_RUNNING,              /* normal running */
    STATE_STOPPED,              /* stopped, not running */
    STATE_BREAK_PT,             /* at a break point */
    STATE_SLEEP,                /* Sleep mode (there are many sleep modes. */
} StateType;

typedef struct _AvrCore AvrCore;

struct _AvrCore
{
    AvrClass parent;
    int state;                  /* What state is the device in */
    int sleep_mode;             /* If in sleep state, what mode? */
    int32_t PC;                 /* Program Counter */
    int32_t PC_size;            /* size of Program Counter in bytes */
    int32_t PC_max;             /* maximum value PC can hold for a given
                                   device (is flash_sz/2) */
    SREG *sreg;                 /* Status Register */
    GPWR *gpwr;                 /* General Purpose Working Registers */
    Flash *flash;               /* flash program memory */
    EEProm *eeprom;             /* internal eeprom memory */

    SRAM *sram;                 /* internal sram memory */
    Memory *mem;                /* memory space (gp reg, io reg, sram, ext
                                   sram, etc) */
    Stack *stack;               /* a stack implementaton */

    DList *breakpoints;         /* head of list of active breakpoints */

    DList *irq_pending;         /* head of list of pending interrupts (sorted
                                   by priority) */
    IntVect *irq_vtable;        /* interrupt vector table array */
    int irq_offset;             /* Some devices (e.g. mega128) will let you
                                   add an offset to the vector addr. */

    uint64_t CK;                /* for keeping track of how many clock cycles
                                   have occurred */
    int inst_CKS;               /* number of clocks the previously executed
                                   instruction took */

    DList *clk_cb;              /* head of list of clock callback items. If a
                                   clock callback function uses the time
                                   argument, it is to be interpreted as the
                                   number of clock cycles that have occured
                                   since a reset. */

    DList *async_cb;            /* head of list of asynchronous callback
                                   items. If an async callback function uses
                                   the time argument, it is to be interpreted
                                   as the approximate number of milliseconds
                                   that have elapsed from some unknown time on
                                   the host system. */

    /*
     * These registers will go somewhere else once I see a device that
     * actually uses them.
     */
    uint8_t RAMPX;              /* Registers concatenated with the X, Y and Z
                                   registers */
    uint8_t RAMPY;              /* enabling indirect addressing of the wholw
                                   data space */
    RAMPZ *rampz;               /* on MCUs with more than 64K bytes date
                                   space, and constant */
    /* data fetch on MCUs with more than 64K bytes profram space. */

    uint8_t RAMPD;              /* Register concatenated with the Z register
                                   enabling direct addressing of the while
                                   data space on MCUs with more than 64K bytes
                                   data space */

    uint8_t EIND;               /* Register concatenated with the instruction
                                   word enabling indirect jump and call to the
                                   whole program space on MCUs with more than
                                   64K bytes program space. */
};

extern AvrCore *avr_core_new (char *dev_name);
extern void avr_core_destroy (void *core);

extern void avr_core_get_sizes (AvrCore *core, int *flash, int *sram,
                                int *sram_start, int *eeprom);

/* Attach a Virtual Device to the core */

extern inline void
avr_core_attach_vdev (AvrCore *core, uint16_t addr, char *name, VDevice *vdev,
                      int flags, uint8_t reset_value, uint8_t rd_mask,
                      uint8_t wr_mask)
{
    vdev_set_core (vdev, (AvrClass *)core);
    mem_attach (core->mem, addr, name, vdev, flags, reset_value, rd_mask,
                wr_mask);
}

extern inline VDevice *
avr_core_get_vdev_by_name (AvrCore *core, char *name)
{
    return mem_get_vdevice_by_name (core->mem, name);
}

extern inline VDevice *
avr_core_get_vdev_by_addr (AvrCore *core, int addr)
{
    return mem_get_vdevice_by_addr (core->mem, addr);
}

extern inline void
avr_core_set_addr_name (AvrCore *core, int addr, char *name)
{
    mem_set_addr_name (core->mem, addr, name);
}


/* State Access Methods */

extern inline int
avr_core_get_state (AvrCore *core)
{
    return core->state;
}

extern inline void
avr_core_set_state (AvrCore *core, StateType state)
{
    core->state = state;
}

/* Sleep Mode Access Methods */

extern inline void
avr_core_set_sleep_mode (AvrCore *core, int sleep_mode)
{
    core->state = STATE_SLEEP;
    core->sleep_mode = ((unsigned int)1 << sleep_mode);
}

extern inline int
avr_core_get_sleep_mode (AvrCore *core)
{
    return core->sleep_mode;
}

/* Program Memory Space Access Methods */

static inline uint16_t
avr_core_flash_read (AvrCore *core, int addr)
{
    return flash_read (core->flash, addr);
}

static inline void
avr_core_flash_write (AvrCore *core, int addr, uint16_t val)
{
    flash_write (core->flash, addr, val);
}

static inline void
avr_core_flash_write_lo8 (AvrCore *core, int addr, uint8_t val)
{
    flash_write_lo8 (core->flash, addr, val);
}

static inline void
avr_core_flash_write_hi8 (AvrCore *core, int addr, uint8_t val)
{
    flash_write_hi8 (core->flash, addr, val);
}

/* Data Memory Space Access Methods */

static inline uint8_t
avr_core_mem_read (AvrCore *core, int addr)
{
    return mem_read (core->mem, addr);
}

static inline void
avr_core_mem_write (AvrCore *core, int addr, uint8_t val)
{
    mem_write (core->mem, addr, val);
}

/* Status Register Access Methods */

static inline uint8_t
avr_core_sreg_get (AvrCore *core)
{
    return sreg_get (core->sreg);
}

static inline void
avr_core_sreg_set (AvrCore *core, uint8_t v)
{
    sreg_set (core->sreg, v);
}

extern inline int
avr_core_sreg_get_bit (AvrCore *core, int b)
{
    return sreg_get_bit (core->sreg, b);
}

extern inline void
avr_core_sreg_set_bit (AvrCore *core, int b, int v)
{
    sreg_set_bit (core->sreg, b, v);
}

/* RAMPZ Access Methods */

extern inline uint8_t
avr_core_rampz_get (AvrCore *core)
{
    if (core->rampz)
        return rampz_get (core->rampz);
    else
        return 0;
}

extern inline void
avr_core_rampz_set (AvrCore *core, uint8_t v)
{
    if (core->rampz)
        rampz_set (core->rampz, v);
}

/* General Purpose Working Register Access Methods */

static inline uint8_t
avr_core_gpwr_get (AvrCore *core, int reg)
{
    return gpwr_get (core->gpwr, reg);
}

static inline void
avr_core_gpwr_set (AvrCore *core, int reg, uint8_t val)
{
    gpwr_set (core->gpwr, reg, val);
}

/* Direct I/O Register Access Methods */

extern void avr_core_io_display_names (AvrCore *core);

static inline uint8_t
avr_core_io_read (AvrCore *core, int reg)
{
    return avr_core_mem_read (core, reg + IO_REG_ADDR_BEGIN);
}

static inline void
avr_core_io_write (AvrCore *core, int reg, uint8_t val)
{
    avr_core_mem_write (core, reg + IO_REG_ADDR_BEGIN, val);
}

static inline void
avr_core_io_fetch (AvrCore *core, int reg, uint8_t * val, char *buf,
                   int bufsiz)
{
    mem_io_fetch (core->mem, reg + IO_REG_ADDR_BEGIN, val, buf, bufsiz);
}

/* Stack Access Methods */

extern inline uint32_t
avr_core_stack_pop (AvrCore *core, int bytes)
{
    return stack_pop (core->stack, bytes);
}

extern inline void
avr_core_stack_push (AvrCore *core, int bytes, uint32_t val)
{
    stack_push (core->stack, bytes, val);
}

/* Private
 
   Deal with PC reach-arounds.

   It's possible to set/incrment the program counter with large negative
   values which go past zero. These should be interpreted as wrapping back
   around the last address in the flash. */

extern inline void
_adjust_PC_to_max (AvrCore *core)
{
    if (core->PC < 0)
        core->PC = core->PC_max + core->PC;

    if (core->PC >= core->PC_max)
        core->PC -= core->PC_max;
}

/* Program Counter Access Methods */

extern inline int32_t
avr_core_PC_size (AvrCore *core)
{
    return core->PC_size;
}

static inline int32_t
avr_core_PC_max (AvrCore *core)
{
    return core->PC_max;
}

static inline int32_t
avr_core_PC_get (AvrCore *core)
{
    return core->PC;
}

static inline void
avr_core_PC_set (AvrCore *core, int32_t val)
{
    core->PC = val;
    _adjust_PC_to_max (core);
    display_pc (core->PC);
}

extern inline void
avr_core_PC_incr (AvrCore *core, int val)
{
    core->PC += val;
    _adjust_PC_to_max (core);
    display_pc (core->PC);
}

/* Interrupt Access Methods */

extern void avr_core_irq_raise (AvrCore *core, int irq);
extern void avr_core_irq_clear (AvrCore *core, IntVect *irq);

extern inline void
avr_core_irq_clear_all (AvrCore *core)
{
    dlist_delete_all (core->irq_pending);
    core->irq_pending = NULL;
}

extern IntVect *avr_core_irq_get_pending (AvrCore *core);

/* Loading files into various memory areas */
extern int avr_core_load_program (AvrCore *core, char *file, int format);
extern int avr_core_load_eeprom (AvrCore *core, char *file, int format);

/* Dump a core file */
extern void avr_core_dump_core (AvrCore *core, FILE * f_core);

/* Methods for running programs */
extern int avr_core_step (AvrCore *core);
extern void avr_core_run (AvrCore *core);
extern void avr_core_reset (AvrCore *core);

/* Methods for accessing CK and inst_CKS */

extern inline uint64_t
avr_core_CK_get (AvrCore *core)
{
    return core->CK;
}

extern inline void
avr_core_CK_incr (AvrCore *core)
{
    core->CK++;

    /* Send clock cycles to display */
    display_clock (core->CK);
}

extern inline int
avr_core_inst_CKS_get (AvrCore *core)
{
    return core->inst_CKS;
}

extern inline void
avr_core_inst_CKS_set (AvrCore *core, int val)
{
    core->inst_CKS = val;
}

/* Methods for handling clock callbacks */

extern inline void
avr_core_clk_cb_add (AvrCore *core, CallBack *cb)
{
    core->clk_cb = callback_list_add (core->clk_cb, cb);
}

extern inline void
avr_core_clk_cb_exec (AvrCore *core)
{
    core->clk_cb =
        callback_list_execute_all (core->clk_cb, avr_core_CK_get (core));
}

/* Methods for handling asynchronous callbacks */

extern inline void
avr_core_async_cb_add (AvrCore *core, CallBack *cb)
{
    core->async_cb = callback_list_add (core->async_cb, cb);
}

extern inline void
avr_core_async_cb_exec (AvrCore *core)
{
    core->async_cb =
        callback_list_execute_all (core->async_cb, get_program_time ());
}

/* For adding external read and write callback functions */
extern void avr_core_add_ext_rd_wr (AvrCore *core, int addr,
                                    PortFP_ExtRd ext_rd, PortFP_ExtWr ext_wr);

/* Break point access methods */
extern void avr_core_insert_breakpoint (AvrCore *core, int pc);
extern void avr_core_remove_breakpoint (AvrCore *core, int pc);
extern void avr_core_enable_breakpoints (AvrCore *core);
extern void avr_core_disable_breakpoints (AvrCore *core);

#endif /* SIM_AVRCORE_H */