#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include "../libsdl/print.h"
#include "execute.h"
#include "m68k.h"
#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;
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);
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) {
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);
}
struct cpu_stop {
uint32_t pc;
- int event;
+ uint8_t event;
};
-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[]);
void reset_cpu(void);
-int execute_cpu(int irq, const struct cpu_stop stop_at[], int *event);
+int execute_cpu(int irq, int *event);
#define IOSIZE 0x1000 /* bytes in io space */
#define MEMORY_SIZE 0x80000
static uint8_t *memory = NULL;
+static uint8_t *stop_event = NULL;
static uint8_t *image = NULL;
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200
/* execute until the rendered image is ready (wait for VBL) */
cycle_count = 0;
do {
- cycle_count += execute_cpu(0, mercenary_stop_at, &event);
+ cycle_count += execute_cpu(0, &event);
/* handle special events */
if (event != STOP_AT_WAIT_VBL)
special_event(event);
last_time = current_time - 1000 * SOUND_CHUNKS / IRQ_RATE;
}
while (diff > 1000 / IRQ_RATE) {
- execute_cpu(3, NULL, NULL);
- execute_cpu(4, NULL, NULL);
+ execute_cpu(3, NULL);
+ execute_cpu(4, NULL);
had_first_irq = 1;
/* render benson without game view
* because we only got benson refreshed during VBL IRQ
print_error("Failed to allocate cpu's memory\n");
goto done;
}
+ stop_event = calloc(MEMORY_SIZE, 1);
+ if (!stop_event) {
+ print_error("Failed to allocate cpu's stop_event memory\n");
+ goto done;
+ }
chipreg = calloc(IOSIZE, 1);
if (!chipreg) {
print_error("Failed to allocate chip register\n");
}
/* init cpu code */
- execute_init(MEMORY_SIZE, memory, chipreg, io_read, io_write);
+ execute_init(MEMORY_SIZE, memory, stop_event, chipreg, io_read, io_write, mercenary_stop_at);
/* init disk emulation */
disk_init(disk_read, disk_write);
if (chipreg)
free(chipreg);
+ if (stop_event)
+ free(stop_event);
if (memory)
free(memory);
if (sound_buffer)