Commit 7a77ebb65ab202837e4713f8758f096a39c0d95a
authorMichel Pollet <buserror@gmail.com>
Wed, 10 Jan 2018 09:26:54 +0000 (09:26 +0000)
committerMichel Pollet <buserror@gmail.com>
Wed, 10 Jan 2018 09:26:54 +0000 (09:26 +0000)
Added a special opcode at the end of flash to catch PC overflow, and
'wrap it'. Also log the condition.
This allow that case to be handled without having to add a
modulo/division for each instruction.

Signed-off-by: Michel Pollet <buserror@gmail.com>
3 files changed:
simavr/sim/sim_avr.c
simavr/sim/sim_core.c
simavr/sim/sim_core.h

index 1878b4190ceceab263c0bcd875a323c7a707c631..d33400abe397f72493cc818eee620c1c7a8aa061 100644 (file)
@@ -96,8 +96,9 @@ int
 avr_init(
                avr_t * avr)
 {
-       avr->flash = malloc(avr->flashend + 1);
+       avr->flash = malloc(avr->flashend + 4);
        memset(avr->flash, 0xff, avr->flashend + 1);
+       *((uint16_t*)&avr->flash[avr->flashend + 1]) = AVR_OVERFLOW_OPCODE;
        avr->codeend = avr->flashend;
        avr->data = malloc(avr->ramend + 1);
        memset(avr->data, 0, avr->ramend + 1);
index f3b163dce560213d3e0b30e87f5c911f62739c77..7be739b49b8555dabf4665b2d7531f5d908448bb 100644 (file)
@@ -1363,6 +1363,13 @@ run_one_again:
 
                case 0xf000: {
                        switch (opcode & 0xfe00) {
+                               case 0xf100: {  /* simavr special opcodes */
+                                       if (opcode == 0xf1f1) { // AVR_OVERFLOW_OPCODE
+                                               printf("FLASH overflow, soft reset\n");
+                                               new_pc = 0;
+                                               TRACE_JUMP();
+                                       }
+                               }       break;
                                case 0xf000:
                                case 0xf200:
                                case 0xf400:
index fa99638af2c74b6497989cc1d4c0c32e8bdcd6c5..403c119a63d596f1f82b19d573d60c0bde7c57df 100644 (file)
@@ -129,6 +129,12 @@ static inline void avr_sreg_set(avr_t * avr, uint8_t flag, uint8_t ival)
                                avr_sreg_set(avr, i, (src & (1 << i)) != 0); \
                }
 
+/*
+ * Opcode is sitting at the end of the flash to catch PC overflows.
+ * Apparently it's used by some code to simulate soft reset?
+ */
+#define AVR_OVERFLOW_OPCODE 0xf1f1
+
 #ifdef __cplusplus
 };
 #endif