Improved "stop events" by using an event ID for every byte of memory.
[mercenary-reloaded.git] / src / libcpu / execute.c
index 9d3180e..a173d2c 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 #include "../libsdl/print.h"
 #include "execute.h"
 #include "m68k.h"
@@ -31,6 +32,7 @@
 #define IOBASE 0x00dff000
 
 static uint8_t *memory = NULL;
+static uint8_t *stop_event = NULL;
 static uint32_t memory_size = 0;
 static uint16_t *chipreg = NULL;
 static uint16_t (*io_read)(uint32_t address) = NULL;
@@ -130,14 +132,27 @@ void m68k_write_memory_32(unsigned int address, unsigned int value)
        memory[address + 3] = value;
 }
 
-void execute_init(int32_t _memory_size, uint8_t *_memory, uint16_t *_chipreg, uint16_t (*_io_read)(uint32_t address), void (*_io_write)(uint32_t address, uint16_t value))
+void execute_init(int32_t _memory_size, uint8_t *_memory, uint8_t *_stop_event, uint16_t *_chipreg, uint16_t (*_io_read)(uint32_t address), void (*_io_write)(uint32_t address, uint16_t value), const struct cpu_stop stop_at[])
 {
+       int i;
+
        memory_size = _memory_size;
        memory = _memory;
+       stop_event = _stop_event;
        chipreg = _chipreg;
        io_read = _io_read;
        io_write = _io_write;
 
+       /* flag where the cpu shall stop at */
+       memset(stop_event, 0, _memory_size);
+       for (i = 0; stop_at[i].event; i++) {
+               if (stop_at[i].pc >= memory_size) {
+                       fprintf(stderr, "stop-event at PC=%x is out of memory=%x\n", stop_at[i].pc, memory_size);
+                       exit(0);
+               }
+               stop_event[stop_at[i].pc] = stop_at[i].event;
+       }
+
        /* init CPU */
        m68k_init();
         m68k_set_cpu_type(M68K_CPU_TYPE_68000);
@@ -148,11 +163,10 @@ void reset_cpu(void)
        m68k_pulse_reset();
 }
 
-int execute_cpu(int irq, const struct cpu_stop stop_at[], int *event)
+int execute_cpu(int irq, int *event)
 {
        int cycle_count = 0;
        int instruction_count = 0;
-       int i;
        uint32_t save_pc;
 
        if (irq) {
@@ -182,14 +196,14 @@ int execute_cpu(int irq, const struct cpu_stop stop_at[], int *event)
                                        break;
                        }
 
-                       for (i = 0; stop_at[i].event; i++) {
-                               if (REG_PC == stop_at[i].pc) {
-#ifdef DEBUG_CPU
-                                       print_error("execution to address 0x%06x took %d opcodes\n", REG_PC, instruction_count);
-#endif
-                                       *event = stop_at[i].event;
-                                       return cycle_count;
-                               }
+                       /* stop execution if there is an event */
+                       if (REG_PC >= memory_size) {
+                               print_error("CPU execution reaches PC=%x that is out of memory=%x\n", REG_PC, memory_size);
+                               exit(0);
+                       }
+                       if (stop_event[REG_PC]) {
+                               *event = stop_event[REG_PC];
+                               return cycle_count;
                        }
                } while (42);
        }