]> git.sesse.net Git - pistorm/commitdiff
Merge pull request #4 from beeanyew/rom-mirror-fix
authorcaptain-amygdala <claude.schwarz@gmail.com>
Wed, 9 Dec 2020 14:18:15 +0000 (15:18 +0100)
committerGitHub <noreply@github.com>
Wed, 9 Dec 2020 14:18:15 +0000 (15:18 +0100)
Add support for ROM mirroring

17 files changed:
Makefile
config_file/config_file.c
config_file/config_file.h
default.cfg
emulator.c
input/input.c
input/input.h
memory_mapped.c
platforms/amiga/amiga-autoconf.c [new file with mode: 0644]
platforms/amiga/amiga-autoconf.h [new file with mode: 0644]
platforms/amiga/amiga-platform.c [new file with mode: 0644]
platforms/amiga/amiga-registers.c [moved from registers/registers_amiga.c with 80% similarity]
platforms/dummy/dummy-platform.c [new file with mode: 0644]
platforms/dummy/dummy-registers.c [new file with mode: 0644]
platforms/platforms.c [new file with mode: 0644]
platforms/platforms.h [new file with mode: 0644]
registers/registers_dummy.c [deleted file]

index 9060f95b774dd77e2f74c45d66952bb22f781b14..6e7f301f484c9cd4847844cf250b6840d92c4d5e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,18 @@
 EXENAME          = emulator
 
-MAINFILES        = emulator.c Gayle.c ide.c memory_mapped.c config_file/config_file.c registers/registers_amiga.c input/input.c
+MAINFILES        = emulator.c \
+       Gayle.c \
+       ide.c \
+       memory_mapped.c \
+       config_file/config_file.c \
+       input/input.c \
+       platforms/platforms.c \
+       platforms/amiga/amiga-autoconf.c \
+       platforms/amiga/amiga-platform.c \
+       platforms/amiga/amiga-registers.c \
+       platforms/dummy/dummy-platform.c \
+       platforms/dummy/dummy-registers.c
+
 MUSASHIFILES     = m68kcpu.c softfloat/softfloat.c 
 MUSASHIGENCFILES = m68kops.c
 MUSASHIGENHFILES = m68kops.h
index b7eff98a05b8e9d75ca2ff3781b90239c7c68c64..f16782a89b7fffbd79291d3297bd5dc09125d8cc 100644 (file)
@@ -1,4 +1,4 @@
-#include "config_file.h"
+#include "../platforms/platforms.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -32,6 +32,7 @@ const char *config_item_names[CONFITEM_NUM] = {
   "loopcycles",
   "mouse",
   "keyboard",
+  "platform",
 };
 
 const char *mapcmd_names[MAPCMD_NUM] = {
@@ -212,12 +213,13 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
       }
       fseek(in, 0, SEEK_SET);
       cfg->map_data[index] = (unsigned char *)calloc(1, cfg->map_size[index]);
+      cfg->rom_size[index] = (cfg->map_size[index] <= file_size) ? cfg->map_size[index] : file_size;
       if (!cfg->map_data[index]) {
         printf("ERROR: Unable to allocate memory for mapped ROM!\n");
         goto mapping_failed;
       }
       memset(cfg->map_data[index], 0x00, cfg->map_size[index]);
-      fread(cfg->map_data[index], (cfg->map_size[index] <= file_size) ? cfg->map_size[index] : file_size, 1, in);
+      fread(cfg->map_data[index], cfg->rom_size[index], 1, in);
       fclose(in);
       break;
     case MAPTYPE_REGISTER:
@@ -226,7 +228,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad
       break;
   }
 
-  printf("[MAP %d] Added %s mapping for range %.8lX-%.8lX (%lX)\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_offset[index] + cfg->map_size[index] - 1, (uint64_t)cfg->map_data[index]);
+  printf("[MAP %d] Added %s mapping for range %.8lX-%.8lX ID: %s\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_offset[index] + cfg->map_size[index] - 1, cfg->map_id[index] ? cfg->map_id[index] : "None");
 
   return;
 
@@ -351,6 +353,19 @@ struct emulator_config *load_config_file(char *filename) {
         cfg->keyboard_toggle_key = cur_cmd[0];
         printf("Enabled keyboard event forwarding, toggle key %c.\n", cfg->keyboard_toggle_key);
         break;
+      case CONFITEM_PLATFORM: {
+        char platform_name[128], platform_sub[128];
+        memset(platform_name, 0x00, 128);
+        memset(platform_sub, 0x00, 128);
+        get_next_string(parse_line, platform_name, &str_pos, ' ');
+        printf("Setting platform to %s", platform_name);
+        get_next_string(parse_line, platform_sub, &str_pos, ' ');
+        if (strlen(platform_sub))
+          printf(" (sub: %s)", platform_sub);
+        printf("\n");
+        cfg->platform = make_platform_config(platform_name, platform_sub);
+        break;
+      }
       case CONFITEM_NONE:
       default:
         printf("Unknown config item %s on line %d.\n", cur_cmd, cur_line);
@@ -378,3 +393,17 @@ struct emulator_config *load_config_file(char *filename) {
 
   return cfg;
 }
+
+int get_named_mapped_item(struct emulator_config *cfg, char *name) {
+  if (strlen(name) == 0)
+    return -1;
+
+  for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) {
+    if (cfg->map_type[i] == MAPTYPE_NONE || !cfg->map_id[i])
+      continue;
+    if (strcmp(name, cfg->map_id[i]) == 0)
+      return i;
+  }
+
+  return -1;
+}
index 6c56a687028d640bde35c8f7976bfa3a3a04c855..e6e766dcad79acd641bc38cb300bdca132ba7ee9 100644 (file)
@@ -32,6 +32,7 @@ typedef enum {
   CONFITEM_LOOPCYCLES,
   CONFITEM_MOUSE,
   CONFITEM_KEYBOARD,
+  CONFITEM_PLATFORM,
   CONFITEM_NUM,
 } config_items;
 
@@ -49,10 +50,13 @@ struct emulator_config {
   unsigned char map_type[MAX_NUM_MAPPED_ITEMS];
   long map_offset[MAX_NUM_MAPPED_ITEMS];
   unsigned int map_size[MAX_NUM_MAPPED_ITEMS];
+  unsigned int rom_size[MAX_NUM_MAPPED_ITEMS];
   unsigned char *map_data[MAX_NUM_MAPPED_ITEMS];
   int map_mirror[MAX_NUM_MAPPED_ITEMS];
   char *map_id[MAX_NUM_MAPPED_ITEMS];
 
+  struct platform_config *platform;
+
   char *mouse_file;
 
   char mouse_toggle_key, keyboard_toggle_key;
@@ -61,10 +65,22 @@ struct emulator_config {
   unsigned int loop_cycles;
 };
 
+struct platform_config {
+  char *subsys;
+
+  int (*custom_read)(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type);
+  int (*custom_write)(struct emulator_config *cfg, unsigned int addr, unsigned int val, unsigned char type);
+
+  int (*register_read)(unsigned int addr, unsigned char type, unsigned int *val);
+  int (*register_write)(unsigned int addr, unsigned int value, unsigned char type);
+
+  int (*platform_initial_setup)(struct emulator_config *cfg);
+  void (*setvar)(char *var, char *val);
+};
+
 unsigned int get_m68k_cpu_type(char *name);
 struct emulator_config *load_config_file(char *filename);
 
 int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type, unsigned char mirror);
 int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, unsigned int value, unsigned char type, unsigned char mirror);
-int handle_register_read(unsigned int addr, unsigned char type, unsigned int *val);
-int handle_register_write(unsigned int addr, unsigned int value, unsigned char type);
+int get_named_mapped_item(struct emulator_config *cfg, char *name);
index fd8a3fcaedce65452ae15fdde1d1ad636bdd37e7..9caf4e9e8f0d7e16f82aa1de1d293be5c77f9001 100644 (file)
@@ -1,17 +1,30 @@
 # Sets CPU type. Valid types are (probably) 68000, 68010, 68020, 68EC020, 68030, 68EC030, 68040, 68EC040, 68LC040 and some STTTT thing.
 cpu 68020
 # Map 512KB kickstart ROM to default offset.
-map type=rom address=0xF80000 size=0x80000 file=kick512.rom ovl=0
-# This is for mapping a 256KB kickstart ROM. I can probably add some additional thing about kicking this file into low/high area.
-#map type=rom address=0xFC0000 size=0x40000 file=kick256.rom ovl=0
+map type=rom address=0xF80000 size=0x80000 file=kick.rom ovl=0
 # Want to map an extended ROM, such as CDTV or CD32?
-#map type=rom address=0xF00000 size=0x90000 file=cdtv.rom
-# Map 256MB of Fast RAM at 0x8000000.
-map type=ram address=0x08000000 size=128M
+#map type=rom address=0xF00000 size=0x80000 file=cdtv.rom
+
+# Map 128MB of Fast RAM at 0x8000000.
+map type=ram address=0x08000000 size=128M id=cpu_slot_ram
+# Map 128MB of Z3 Fast. Note that the address here is not actually used, as it gets auto-assigned by Kickstart itself.
+# Enabling Z3 fast requires a Kickstart that actually supports Zorro III, for instance from an A3000 or A4000.
+#map type=ram address=0x10000000 size=128M id=z3_autoconf_fast
+# Max 8MB of Z2 Fast can be mapped due to addressing space limitations, but for instance 2+4MB can be chained to leave 2MB for something else.
+#map type=ram address=0x200000 size=8M id=z2_autoconf_fast
+#map type=ram address=0x200000 size=2M id=z2_autoconf_fast
+#map type=ram address=0x400000 size=4M id=z2_autoconf_fast
+
+# This is fake Chip RAM, do not use on a real Amiga.
+#map type=ram address=0x0 size=2M
+
 # Map Gayle as a register range.
 map type=register address=0xD80000 size=0x70000
 # Number of instructions to run every main loop.
 loopcycles 300
+# Set the platform to Amiga to enable all the registers and stuff.
+platform amiga
+
 # Forward mouse events to host system, defaults to off unless toggle key is pressed on the Pi.
 # Syntax is mouse [device] [toggle key]
 #mouse /dev/input/mouse0 m
index dbd4096b45adebfaf660442d7967910c3828ef0d..39648f37d5ced344308a6d744a656ffd1fb186e7 100644 (file)
@@ -18,7 +18,7 @@
 #include "ide.h"
 #include "m68k.h"
 #include "main.h"
-#include "config_file/config_file.h"
+#include "platforms/platforms.h"
 #include "input/input.h"
 
 //#define BCM2708_PERI_BASE        0x20000000  //pi0-1
@@ -89,7 +89,7 @@ char mouse_buttons = 0;
 #define KICKBASE 0xF80000
 #define KICKSIZE 0x7FFFF
 
-int mem_fd, mouse_fd = -1;
+int mem_fd, mouse_fd = -1, keyboard_fd = -1;
 int mem_fd_gpclk;
 int gayle_emulation_enabled = 1;
 void *gpio_map;
@@ -99,6 +99,7 @@ void *gpclk_map;
 unsigned int cpu_type = M68K_CPU_TYPE_68000;
 unsigned int loop_cycles = 300;
 struct emulator_config *cfg = NULL;
+char keyboard_file[256] = "/dev/input/event0";
 
 // I/O access
 volatile unsigned int *gpio;
@@ -208,6 +209,14 @@ int main(int argc, char *argv[]) {
         cfg = load_config_file(argv[g]);
       }
     }
+    else if (strcmp(argv[g], "--keyboard-file") == 0 || strcmp(argv[g], "--kbfile") == 0) {
+      if (g + 1 >= argc) {
+        printf("%s switch found, but no keyboard device path specified.\n", argv[g]);
+      } else {
+        g++;
+        strcpy(keyboard_file, argv[g]);
+      }
+    }
   }
 
   if (!cfg) {
@@ -227,6 +236,10 @@ int main(int argc, char *argv[]) {
   if (cfg) {
     if (cfg->cpu_type) cpu_type = cfg->cpu_type;
     if (cfg->loop_cycles) loop_cycles = cfg->loop_cycles;
+
+    if (!cfg->platform)
+      cfg->platform = make_platform_config("none", "generic");
+    cfg->platform->platform_initial_setup(cfg);
   }
 
   if (cfg->mouse_enabled) {
@@ -237,6 +250,11 @@ int main(int argc, char *argv[]) {
     }
   }
 
+  keyboard_fd = open(keyboard_file, O_RDONLY | O_NONBLOCK);
+  if (keyboard_fd == -1) {
+    printf("Failed to open keyboard event source.\n");
+  }
+
   sched_setscheduler(0, SCHED_FIFO, &priority);
   mlockall(MCL_CURRENT);  // lock in memory to keep us from paging out
 
@@ -349,6 +367,7 @@ int main(int argc, char *argv[]) {
           else
               printf("\n IPL Thread created successfully\n");
 */
+  char c = 0;
 
   m68k_pulse_reset();
   while (42) {
@@ -362,8 +381,7 @@ int main(int argc, char *argv[]) {
       m68k_execute(loop_cycles);
     
     // FIXME: Rework this to use keyboard events instead.
-    /*while (kbhit()) {
-      char c = getchar();
+    while (get_key_char(&c)) {
       if (c == cfg->keyboard_toggle_key && !kb_hook_enabled) {
         kb_hook_enabled = 1;
         printf("Keyboard hook enabled.\n");
@@ -372,25 +390,27 @@ int main(int argc, char *argv[]) {
         kb_hook_enabled = 0;
         printf("Keyboard hook disabled.\n");
       }
-      if (c == cfg->mouse_toggle_key) {
-        mouse_hook_enabled ^= 1;
-        printf("Mouse hook %s.\n", mouse_hook_enabled ? "enabled" : "disabled");
-        mouse_dx = mouse_dy = mouse_buttons = 0;
-      }
-      if (c == 'r') {
-        cpu_emulation_running ^= 1;
-        printf("CPU emulation is now %s\n", cpu_emulation_running ? "running" : "stopped");
-      }
-      if (c == 'R') {
-        cpu_pulse_reset();
-        m68k_pulse_reset();
-        printf("CPU emulation reset.\n");
-      }
-      if (c == 'q') {
-        printf("Quitting and exiting emulator.\n");
-        goto stop_cpu_emulation;
+      if (!kb_hook_enabled) {
+        if (c == cfg->mouse_toggle_key) {
+          mouse_hook_enabled ^= 1;
+          printf("Mouse hook %s.\n", mouse_hook_enabled ? "enabled" : "disabled");
+          mouse_dx = mouse_dy = mouse_buttons = 0;
+        }
+        if (c == 'r') {
+          cpu_emulation_running ^= 1;
+          printf("CPU emulation is now %s\n", cpu_emulation_running ? "running" : "stopped");
+        }
+        if (c == 'R') {
+          cpu_pulse_reset();
+          m68k_pulse_reset();
+          printf("CPU emulation reset.\n");
+        }
+        if (c == 'q') {
+          printf("Quitting and exiting emulator.\n");
+          goto stop_cpu_emulation;
+        }
       }
-    }*/
+    }
 /*
     if (toggle == 1){
       srdata = read_reg();
@@ -442,6 +462,10 @@ int cpu_irq_ack(int level) {
 static unsigned int target = 0;
 
 unsigned int m68k_read_memory_8(unsigned int address) {
+  if (cfg->platform->custom_read && cfg->platform->custom_read(cfg, address, &target, OP_TYPE_BYTE) != -1) {
+    return target;
+  }
+
   if (cfg) {
     int ret = handle_mapped_read(cfg, address, &target, OP_TYPE_BYTE, ovl);
     if (ret != -1)
@@ -457,6 +481,10 @@ unsigned int m68k_read_memory_8(unsigned int address) {
 }
 
 unsigned int m68k_read_memory_16(unsigned int address) {
+  if (cfg->platform->custom_read && cfg->platform->custom_read(cfg, address, &target, OP_TYPE_WORD) != -1) {
+    return target;
+  }
+
   if (cfg) {
     int ret = handle_mapped_read(cfg, address, &target, OP_TYPE_WORD, ovl);
     if (ret != -1)
@@ -499,6 +527,10 @@ unsigned int m68k_read_memory_16(unsigned int address) {
 }
 
 unsigned int m68k_read_memory_32(unsigned int address) {
+  if (cfg->platform->custom_read && cfg->platform->custom_read(cfg, address, &target, OP_TYPE_LONGWORD) != -1) {
+    return target;
+  }
+
   if (cfg) {
     int ret = handle_mapped_read(cfg, address, &target, OP_TYPE_LONGWORD, ovl);
     if (ret != -1)
@@ -516,6 +548,10 @@ unsigned int m68k_read_memory_32(unsigned int address) {
 }
 
 void m68k_write_memory_8(unsigned int address, unsigned int value) {
+  if (cfg->platform->custom_write && cfg->platform->custom_write(cfg, address, value, OP_TYPE_BYTE) != -1) {
+    return;
+  }
+
   if (cfg) {
     int ret = handle_mapped_write(cfg, address, value, OP_TYPE_BYTE, ovl);
     if (ret != -1)
@@ -537,6 +573,10 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) {
 }
 
 void m68k_write_memory_16(unsigned int address, unsigned int value) {
+  if (cfg->platform->custom_write && cfg->platform->custom_write(cfg, address, value, OP_TYPE_WORD) != -1) {
+    return;
+  }
+
   if (cfg) {
     int ret = handle_mapped_write(cfg, address, value, OP_TYPE_WORD, ovl);
     if (ret != -1)
@@ -552,6 +592,10 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) {
 }
 
 void m68k_write_memory_32(unsigned int address, unsigned int value) {
+  if (cfg->platform->custom_write && cfg->platform->custom_write(cfg, address, value, OP_TYPE_LONGWORD) != -1) {
+    return;
+  }
+
   if (cfg) {
     int ret = handle_mapped_write(cfg, address, value, OP_TYPE_LONGWORD, ovl);
     if (ret != -1)
index b0274e34366f08f4d6cb0aebb2467897e3a76d73..9958a990d3c27233d765d36b6b65751d26354116 100644 (file)
 #include <unistd.h>
 #include <linux/input.h>
 
-int kbhit()
+static int lshift = 0, rshift = 0, lctrl = 0, rctrl = 0, lalt = 0, altgr = 0;
+extern int mouse_fd;
+extern int keyboard_fd;
+
+enum keypress_type {
+  KEYPRESS_RELEASE,
+  KEYPRESS_PRESS,
+  KEYPRESS_REPEAT,
+};
+
+int handle_modifier(struct input_event *ev) {
+  int *target_modifier = NULL;
+  if (ev->value != KEYPRESS_REPEAT && (ev->code == KEY_LEFTSHIFT || ev->code == KEY_RIGHTSHIFT || ev->code == KEY_LEFTALT || ev->code == KEY_RIGHTALT || ev->code == KEY_LEFTCTRL || ev->code == KEY_RIGHTCTRL)) {
+    switch(ev->code) {
+      case KEY_LEFTSHIFT:
+        target_modifier = &lshift;
+        break;
+      case KEY_RIGHTSHIFT:
+        target_modifier = &rshift;
+        break;
+      case KEY_LEFTALT:
+        target_modifier = &lalt;
+        break;
+      case KEY_RIGHTALT:
+        target_modifier = &altgr;
+        break;
+      case KEY_LEFTCTRL:
+        target_modifier = &lshift;
+        break;
+      case KEY_RIGHTCTRL:
+        target_modifier = &rshift;
+        break;
+    }
+    *target_modifier = (ev->value == KEYPRESS_RELEASE) ? 0 : 1;
+    return 1;
+  }
+  else {
+    return 0;
+  }
+}
+
+#define KEYCASE(a, b, c)case a: return (lshift || rshift) ? c : b;
+
+char char_from_input_event(struct input_event *ev) {
+  switch(ev->code) {
+    KEYCASE(KEY_A, 'a', 'A');
+    KEYCASE(KEY_B, 'b', 'B');
+    KEYCASE(KEY_C, 'c', 'C');
+    KEYCASE(KEY_D, 'd', 'D');
+    KEYCASE(KEY_E, 'e', 'E');
+    KEYCASE(KEY_F, 'f', 'F');
+    KEYCASE(KEY_G, 'g', 'G');
+    KEYCASE(KEY_H, 'h', 'H');
+    KEYCASE(KEY_I, 'i', 'I');
+    KEYCASE(KEY_J, 'j', 'J');
+    KEYCASE(KEY_K, 'k', 'K');
+    KEYCASE(KEY_L, 'l', 'L');
+    KEYCASE(KEY_M, 'm', 'M');
+    KEYCASE(KEY_N, 'n', 'N');
+    KEYCASE(KEY_O, 'o', 'O');
+    KEYCASE(KEY_P, 'p', 'P');
+    KEYCASE(KEY_Q, 'q', 'Q');
+    KEYCASE(KEY_R, 'r', 'R');
+    KEYCASE(KEY_S, 's', 'S');
+    KEYCASE(KEY_T, 't', 'T');
+    KEYCASE(KEY_U, 'u', 'U');
+    KEYCASE(KEY_V, 'c', 'V');
+    KEYCASE(KEY_W, 'w', 'W');
+    KEYCASE(KEY_X, 'x', 'X');
+    KEYCASE(KEY_Y, 'y', 'Y');
+    KEYCASE(KEY_Z, 'z', 'Z');
+    KEYCASE(KEY_1, '1', '!');
+    KEYCASE(KEY_2, '2', '@');
+    KEYCASE(KEY_3, '3', '#');
+    KEYCASE(KEY_4, '4', '$');
+    KEYCASE(KEY_5, '5', '%');
+    KEYCASE(KEY_6, '6', '^');
+    KEYCASE(KEY_7, '7', '&');
+    KEYCASE(KEY_8, '8', '*');
+    KEYCASE(KEY_9, '9', '(');
+    KEYCASE(KEY_0, '0', ')');
+    KEYCASE(KEY_F12, 0x1B, 0x1B);
+    default:
+      return 0;
+  }
+}
+
+int get_key_char(char *c)
 {
+  if (keyboard_fd == -1)
+    return 0;
+
+  struct input_event ie;
+  while(read(keyboard_fd, &ie, sizeof(struct input_event)) != -1) {
+    if (ie.type == EV_KEY) {
+      if (handle_modifier(&ie))
+        continue;
+      char ret = char_from_input_event(&ie);
+      if (ret != 0) {
+        *c = ret;
+        return 1;
+      }
+    }
+  }
+
   return 0;
 }
 
-extern int mouse_fd;
-
 int get_mouse_status(char *x, char *y, char *b) {
   struct input_event ie;
   if (read(mouse_fd, &ie, sizeof(struct input_event)) != -1) {
index b6565bf90b9ad4ca04bca2e83698d2023784888a..ea2e482577967ef9cbecbed48086a4bc245a1837 100644 (file)
@@ -1,2 +1,2 @@
 int get_mouse_status(char *x, char *y, char *b);
-int kbhit();
+int get_key_char(char *c);
index c5a99e7e09659ed883207ddb68e252400f938ea5..e2dd9a43760a747894560052f5f63aefdbf6e65e 100644 (file)
@@ -27,9 +27,9 @@ int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, unsigned
     switch(cfg->map_type[i]) {
       case MAPTYPE_ROM:
         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
-          read_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]);
+          read_addr = cfg->map_data[i] + ((addr - cfg->map_offset[i]) % cfg->rom_size[i]);
         else if (cfg->map_mirror[i] != -1 && mirror && CHKRANGE(addr, cfg->map_mirror[i], cfg->map_size[i]))
-          read_addr = cfg->map_data[i] + (addr - cfg->map_mirror[i]);
+          read_addr = cfg->map_data[i] + ((addr - cfg->map_mirror[i]) % cfg->rom_size[i]);
         break;
       case MAPTYPE_RAM:
         if (CHKRANGE(addr, cfg->map_offset[i], cfg->map_size[i]))
@@ -45,9 +45,11 @@ int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, unsigned
       continue;
     
     if (handle_regs) {
-      if (handle_register_read(addr, type, &target) != -1) {
-        *val = target;
-        return 1;
+      if (cfg->platform && cfg->platform->register_read) {
+        if (cfg->platform->register_read(addr, type, &target) != -1) {
+          *val = target;
+          return 1;
+        }
       }
       return -1;
     }
@@ -109,7 +111,9 @@ int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, unsigned
       continue;
     
     if (handle_regs) {
-      return handle_register_write(addr, value, type);
+      if (cfg->platform && cfg->platform->register_write) {
+        return cfg->platform->register_write(addr, value, type);
+      }
     }
     else if (write_addr) {
       //printf("[PC: %.8X] Write %s to %s (%.8X) (%d)\n", m68k_get_reg(NULL, M68K_REG_PC), op_type_names[type], map_type_names[cfg->map_type[i]], addr, mirror);
diff --git a/platforms/amiga/amiga-autoconf.c b/platforms/amiga/amiga-autoconf.c
new file mode 100644 (file)
index 0000000..913d6c2
--- /dev/null
@@ -0,0 +1,300 @@
+#include "../platforms.h"
+#include "amiga-autoconf.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static unsigned char ac_fast_ram_rom[] = {
+    0xe, AC_MEM_SIZE_8MB,                   // 00/02, link into memory free list, 8 MB
+    0x6, 0x9,                               // 04/06, product id
+    0x8, 0x0,                               // 08/0a, preference to 8 MB space
+    0x0, 0x0,                               // 0c/0e, reserved
+    0x0, 0x7, 0xd, 0xb,                     // 10/12/14/16, mfg id
+    0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x2, 0x0  // 18/.../26, serial
+};
+
+static unsigned char ac_a314_rom[] = {
+    0xc, AC_MEM_SIZE_64KB,                  // 00/02, 64 kB
+    0xa, 0x3,                               // 04/06, product id
+    0x0, 0x0,                               // 08/0a, any space okay
+    0x0, 0x0,                               // 0c/0e, reserved
+    0x0, 0x7, 0xd, 0xb,                     // 10/12/14/16, mfg id
+    0xa, 0x3, 0x1, 0x4, 0x0, 0x0, 0x0, 0x0  // 18/.../26, serial
+};
+
+int ac_z2_current_pic = 0;
+int ac_z2_pic_count = 0;
+int ac_z2_done = 0;
+int ac_z2_type[AC_PIC_LIMIT];
+int ac_z2_index[AC_PIC_LIMIT];
+unsigned int ac_base[AC_PIC_LIMIT];
+
+int ac_z3_current_pic = 0;
+int ac_z3_pic_count = 0;
+int ac_z3_done = 0;
+int ac_z3_type[AC_PIC_LIMIT];
+int ac_z3_index[AC_PIC_LIMIT];
+
+
+unsigned char get_autoconf_size(int size) {
+  if (size == 8 * SIZE_MEGA)
+    return AC_MEM_SIZE_8MB;
+  if (size == 4 * SIZE_MEGA)
+    return AC_MEM_SIZE_4MB;
+  if (size == 2 * SIZE_MEGA)
+    return AC_MEM_SIZE_2MB;
+  else
+    return AC_MEM_SIZE_64KB;
+}
+
+unsigned char get_autoconf_size_ext(int size) {
+  if (size == 16 * SIZE_MEGA)
+    return AC_MEM_SIZE_EXT_16MB;
+  if (size == 32 * SIZE_MEGA)
+    return AC_MEM_SIZE_EXT_32MB;
+  if (size == 64 * SIZE_MEGA)
+    return AC_MEM_SIZE_EXT_64MB;
+  if (size == 128 * SIZE_MEGA)
+    return AC_MEM_SIZE_EXT_128MB;
+  if (size == 256 * SIZE_MEGA)
+    return AC_MEM_SIZE_EXT_256MB;
+  if (size == 512 * SIZE_MEGA)
+    return AC_MEM_SIZE_EXT_512MB;
+  if (size == 1024 * SIZE_MEGA)
+    return AC_MEM_SIZE_EXT_1024MB;
+  else
+    return AC_MEM_SIZE_EXT_64MB;
+}
+
+unsigned int autoconfig_read_memory_z3_8(struct emulator_config *cfg, unsigned int address_) {
+  int address = address_ - AC_Z3_BASE;
+  int index = ac_z3_index[ac_z3_current_pic];
+  unsigned char val = 0;
+
+  if ((address & 0xFF) >= AC_Z3_REG_RES50 && (address & 0xFF) <= AC_Z3_REG_RES7C)
+    val = 0;
+  else {
+    switch(address & 0xFF) {
+      case AC_Z3_REG_ER_TYPE:
+        val |= BOARDTYPE_Z3;
+        if (cfg->map_type[index] == MAPTYPE_RAM)
+          val |= BOARDTYPE_FREEMEM;
+        if (cfg->map_size[index] > 8 * SIZE_MEGA)
+          val |= get_autoconf_size_ext(cfg->map_size[index]);
+        else
+          val |= get_autoconf_size(cfg->map_size[index]);
+        if (ac_z3_current_pic + 1 < ac_z3_pic_count)
+          val |= BOARDTYPE_LINKED;
+        // Pre-invert this value, since it's the only value not physically complemented
+        // for Zorro III.
+        val ^= 0xFF;
+        break;
+      case AC_Z3_REG_ER_PRODUCT:
+        // 1.1... maybe...
+        val = 0x11;
+        break;
+      case AC_Z3_REG_ER_FLAGS:
+        if (cfg->map_type[index] == MAPTYPE_RAM)
+          val |= Z3_FLAGS_MEMORY;
+        if (cfg->map_size[index] > 8 * SIZE_MEGA)
+          val |= Z3_FLAGS_EXTENSION;
+        val |= Z3_FLAGS_RESERVED;
+        // Bottom four bits are zero, useless unles you want really odd RAM sizes.
+        break;
+      // Manufacturer ID low/high bytes.
+      case AC_Z3_REG_MAN_LO:
+        val = PISTORM_MANUF_ID & 0x00FF;
+        break;
+      case AC_Z3_REG_MAN_HI:
+        val = (PISTORM_MANUF_ID >> 8);
+        break;
+      case AC_Z3_REG_SER_BYTE0:
+      case AC_Z3_REG_SER_BYTE1:
+      case AC_Z3_REG_SER_BYTE2:
+      case AC_Z3_REG_SER_BYTE3:
+        // Expansion board serial assigned by manufacturer.
+        val = 0;
+        break;
+      case AC_Z3_REG_INIT_DIAG_VEC_LO:
+      case AC_Z3_REG_INIT_DIAG_VEC_HI:
+        // 16-bit offset to boot ROM in assigned memory range.
+        val = 0;
+        break;
+      // Additional reserved/unused registers.
+      case AC_Z3_REG_ER_RES03:
+      case AC_Z3_REG_ER_RES0D:
+      case AC_Z3_REG_ER_RES0E:
+      case AC_Z3_REG_ER_RES0F:
+      case AC_Z3_REG_ER_Z2_INT:
+      default:
+        val = 0;
+        break;
+    }
+  }
+  //printf("Read byte %d from Z3 autoconf for PIC %d (%.2X).\n", address, ac_z3_current_pic, val);
+  return (address & 0x100) ? (val << 4) ^ 0xFF : (val & 0xF0) ^ 0xFF;
+}
+
+int nib_latch = 0;
+
+void autoconfig_write_memory_z3_8(struct emulator_config *cfg, unsigned int address_, unsigned int value) {
+  int address = address_ - AC_Z3_BASE;
+  int index = ac_z3_index[ac_z3_current_pic];
+  unsigned char val = (unsigned char)value;
+  int done = 0;
+
+  switch(address & 0xFF) {
+    case AC_Z3_REG_WR_ADDR_LO:
+      if (nib_latch) {
+        ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xFF0F0000) | ((val & 0xF0) << 16);
+        nib_latch = 0;
+      }
+      else
+        ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xFF000000) | (val << 16);
+      break;
+    case AC_Z3_REG_WR_ADDR_HI:
+      if (nib_latch) {
+        ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0x0FFF0000) | ((val & 0xF0) << 24);
+        nib_latch = 0;
+      }
+      ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0x00FF0000) | (val << 24);
+      done = 1;
+      break;
+    case AC_Z3_REG_WR_ADDR_NIB_LO:
+      ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xFFF00000) | ((val & 0xF0) << 12);
+      nib_latch = 1;
+      break;
+    case AC_Z3_REG_WR_ADDR_NIB_HI:
+      ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0xF0FF0000) | ((val & 0xF0) << 20);
+      nib_latch = 1;
+      break;
+    case AC_Z3_REG_SHUTUP:
+      //printf("Write to Z3 shutup register for PIC %d.\n", ac_z3_current_pic);
+      done = 1;
+      break;
+    default:
+      break;
+  }
+
+  if (done) {
+    nib_latch = 0;
+    printf("Address of Z3 autoconf RAM assigned to $%.8x\n", ac_base[ac_z3_current_pic]);
+    cfg->map_offset[index] = ac_base[ac_z3_current_pic];
+    ac_z3_current_pic++;
+    if (ac_z3_current_pic == ac_z3_pic_count)
+      ac_z3_done = 1;
+  }
+
+  return;
+}
+
+void autoconfig_write_memory_z3_16(struct emulator_config *cfg, unsigned int address_, unsigned int value) {
+  int address = address_ - AC_Z3_BASE;
+  int index = ac_z3_index[ac_z3_current_pic];
+  unsigned short val = (unsigned short)value;
+  int done = 0;
+
+  switch(address & 0xFF) {
+    case AC_Z3_REG_WR_ADDR_HI:
+      // This is, as far as I know, the only regiter it should write a 16-bit value to.
+      ac_base[ac_z3_current_pic] = (ac_base[ac_z3_current_pic] & 0x00000000) | (val << 16);
+      done = 1;
+      break;
+    default:
+      printf("Unknown WORD write to Z3 autoconf address $%.2X", address & 0xFF);
+      //stop_cpu_emulation();
+      break;
+  }
+
+  if (done) {
+    printf("Address of Z3 autoconf RAM assigned to $%.8x\n", ac_base[ac_z3_current_pic]);
+    cfg->map_offset[index] = ac_base[ac_z3_current_pic];
+    ac_z3_current_pic++;
+    if (ac_z3_current_pic == ac_z3_pic_count)
+      ac_z3_done = 1;
+  }
+
+  return;
+}
+
+unsigned int autoconfig_read_memory_8(struct emulator_config *cfg, unsigned int address_) {
+  unsigned char *rom = NULL;
+  int address = address_ - AC_Z2_BASE;
+  unsigned char val = 0;
+
+  switch(ac_z2_type[ac_z2_current_pic]) {
+    case ACTYPE_MAPFAST_Z2:
+      rom = ac_fast_ram_rom;
+      break;
+    case ACTYPE_A314:
+      rom = ac_a314_rom;
+      break;
+    default:
+      return 0;
+      break;
+  }
+
+  
+  if ((address & 1) == 0 && (address / 2) < (int)sizeof(ac_fast_ram_rom)) {
+    if (ac_z2_type[ac_z2_current_pic] == ACTYPE_MAPFAST_Z2 && address / 2 == 1) {
+      val = get_autoconf_size(cfg->map_size[ac_z2_index[ac_z2_current_pic]]);
+      if (ac_z2_current_pic + 1 < ac_z2_pic_count)
+        val |= BOARDTYPE_LINKED;
+    }
+    else
+      val = rom[address / 2];
+    //printf("Read byte %d from Z2 autoconf for PIC %d (%.2X).\n", address/2, ac_z2_current_pic, val);
+  }
+  val <<= 4;
+  if (address != 0 && address != 2 && address != 40 && address != 42)
+    val ^= 0xff;
+  
+  return (unsigned int)val;
+}
+
+void autoconfig_write_memory_8(struct emulator_config *cfg, unsigned int address_, unsigned int value) {
+  int address = address_ - AC_Z2_BASE;
+  int done = 0;
+
+  unsigned int *base = NULL;
+
+  switch(ac_z2_type[ac_z2_current_pic]) {
+    case ACTYPE_MAPFAST_Z2:
+      base = &ac_base[ac_z2_current_pic];
+      break;
+    case ACTYPE_A314:
+      //base = &a314_base;
+      break;
+    default:
+      break;
+  }
+
+  if (!base) {
+    //printf("Failed to set up the base for autoconfig PIC %d.\n", ac_z2_current_pic);
+    done = 1;
+  }
+  else {
+    if (address == 0x4a) {  // base[19:16]
+      *base = (value & 0xf0) << (16 - 4);
+    } else if (address == 0x48) {  // base[23:20]
+      *base &= 0xff0fffff;
+      *base |= (value & 0xf0) << (20 - 4);
+
+      if (ac_z2_type[ac_z2_current_pic] == ACTYPE_MAPFAST_Z2) { // fast ram
+        //a314_set_mem_base_size(*base, cfg->map_size[ac_index[ac_z2_current_pic]]);
+      }
+      done = 1;
+    } else if (address == 0x4c) {  // shut up
+      //printf("Write to Z2 shutup register for PIC %d.\n", ac_z2_current_pic);
+      done = 1;
+    }
+  }
+
+  if (done) {
+    printf("Address of Z2 autoconf RAM assigned to $%.8x\n", ac_base[ac_z2_current_pic]);
+    cfg->map_offset[ac_z2_index[ac_z2_current_pic]] = ac_base[ac_z2_current_pic];
+    ac_z2_current_pic++;
+    if (ac_z2_current_pic == ac_z2_pic_count)
+      ac_z2_done = 1;
+  }
+}
diff --git a/platforms/amiga/amiga-autoconf.h b/platforms/amiga/amiga-autoconf.h
new file mode 100644 (file)
index 0000000..c39fdf1
--- /dev/null
@@ -0,0 +1,86 @@
+#define AC_Z2_BASE 0xE80000
+#define AC_Z3_BASE 0xFF000000
+#define AC_SIZE (64 * 1024)
+#define AC_PIC_LIMIT 8
+
+#define AC_MEM_SIZE_8MB 0
+#define AC_MEM_SIZE_64KB 1
+#define AC_MEM_SIZE_128KB 2
+#define AC_MEM_SIZE_256KB 3
+#define AC_MEM_SIZE_512KB 4
+#define AC_MEM_SIZE_1MB 5
+#define AC_MEM_SIZE_2MB 6
+#define AC_MEM_SIZE_4MB 7
+
+#define AC_MEM_SIZE_EXT_16MB 0
+#define AC_MEM_SIZE_EXT_32MB 1
+#define AC_MEM_SIZE_EXT_64MB 2
+#define AC_MEM_SIZE_EXT_128MB 3
+#define AC_MEM_SIZE_EXT_256MB 4
+#define AC_MEM_SIZE_EXT_512MB 5
+#define AC_MEM_SIZE_EXT_1024MB 6
+#define AC_MEM_SIZE_EXT_RES 7
+
+enum autoconf_types {
+    ACTYPE_MAPFAST_Z2,
+    ACTYPE_MAPFAST_Z3,
+    ACTYPE_A314,
+    ACTYPE_NUM,
+};
+
+enum autoconfg_z3_regs {
+    AC_Z3_REG_ER_TYPE           = 0x00,
+    AC_Z3_REG_ER_PRODUCT        = 0x04,
+    AC_Z3_REG_ER_FLAGS          = 0x08,
+    AC_Z3_REG_ER_RES03          = 0x0C,
+    AC_Z3_REG_MAN_HI            = 0x10,
+    AC_Z3_REG_MAN_LO            = 0x14,
+    AC_Z3_REG_SER_BYTE0         = 0x18,
+    AC_Z3_REG_SER_BYTE1         = 0x1C,
+    AC_Z3_REG_SER_BYTE2         = 0x20,
+    AC_Z3_REG_SER_BYTE3         = 0x24,
+    AC_Z3_REG_INIT_DIAG_VEC_HI  = 0x28,
+    AC_Z3_REG_INIT_DIAG_VEC_LO  = 0x2C,
+    AC_Z3_REG_ER_RES0C          = 0x30,
+    AC_Z3_REG_ER_RES0D          = 0x34,
+    AC_Z3_REG_ER_RES0E          = 0x38,
+    AC_Z3_REG_ER_RES0F          = 0x3C,
+    AC_Z3_REG_ER_Z2_INT         = 0x40,
+    AC_Z3_REG_WR_ADDR_HI        = 0x44,
+    AC_Z3_REG_WR_ADDR_NIB_HI    = 0x46,
+    AC_Z3_REG_WR_ADDR_LO        = 0x48,
+    AC_Z3_REG_WR_ADDR_NIB_LO    = 0x4A,
+    AC_Z3_REG_SHUTUP            = 0x4C,
+    AC_Z3_REG_RES50             = 0x50,
+    AC_Z3_REG_RES54             = 0x54,
+    AC_Z3_REG_RES58             = 0x58,
+    AC_Z3_REG_RES5C             = 0x5C,
+    AC_Z3_REG_RES60             = 0x60,
+    AC_Z3_REG_RES64             = 0x64,
+    AC_Z3_REG_RES68             = 0x68,
+    AC_Z3_REG_RES6C             = 0x6C,
+    AC_Z3_REG_RES70             = 0x70,
+    AC_Z3_REG_RES74             = 0x74,
+    AC_Z3_REG_RES78             = 0x78,
+    AC_Z3_REG_RES7C             = 0x7C,
+};
+
+#define BOARDTYPE_Z3 0x80
+#define BOARDTYPE_Z2 (0x80|0x40)
+#define BOARDTYPE_FREEMEM 0x20
+#define BOARDTYPE_BOOTROM 0x10
+#define BOARDTYPE_LINKED 0x08
+
+#define Z3_FLAGS_MEMORY    0x80
+#define Z3_FLAGS_NOSHUTUP  0x40
+#define Z3_FLAGS_EXTENSION 0x20
+#define Z3_FLAGS_RESERVED  0x10
+
+#define PISTORM_MANUF_ID 0xDEBE
+
+unsigned int autoconfig_read_memory_8(struct emulator_config *cfg, unsigned int address);
+void autoconfig_write_memory_8(struct emulator_config *cfg, unsigned int address, unsigned int value);
+
+unsigned int autoconfig_read_memory_z3_8(struct emulator_config *cfg, unsigned int address_);
+void autoconfig_write_memory_z3_8(struct emulator_config *cfg, unsigned int address_, unsigned int value);
+void autoconfig_write_memory_z3_16(struct emulator_config *cfg, unsigned int address_, unsigned int value);
diff --git a/platforms/amiga/amiga-platform.c b/platforms/amiga/amiga-platform.c
new file mode 100644 (file)
index 0000000..33e1796
--- /dev/null
@@ -0,0 +1,184 @@
+#include "../platforms.h"
+#include "amiga-autoconf.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int handle_register_read_amiga(unsigned int addr, unsigned char type, unsigned int *val);
+int handle_register_write_amiga(unsigned int addr, unsigned int value, unsigned char type);
+
+extern int ac_z2_done;
+extern int ac_z2_pic_count;
+extern int ac_z2_type[AC_PIC_LIMIT];
+extern int ac_z2_index[AC_PIC_LIMIT];
+
+extern int ac_z3_pic_count;
+extern int ac_z3_done;
+extern int ac_z3_type[AC_PIC_LIMIT];
+extern int ac_z3_index[AC_PIC_LIMIT];
+
+char *z2_autoconf_id = "z2_autoconf_fast";
+char *z2_autoconf_zap_id = "^2_autoconf_fast";
+char *z3_autoconf_id = "z3_autoconf_fast";
+char *z3_autoconf_zap_id = "^3_autoconf_fast";
+
+extern const char *op_type_names[OP_TYPE_NUM];
+
+int custom_read_amiga(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type) {
+    if (!ac_z2_done && addr >= AC_Z2_BASE && addr < AC_Z2_BASE + AC_SIZE) {
+        if (ac_z2_pic_count == 0) {
+            ac_z2_done = 1;
+            return -1;
+        }
+
+        if (type == OP_TYPE_BYTE) {
+            *val = autoconfig_read_memory_8(cfg, addr);
+            return 1;
+        }
+    }
+    if (!ac_z3_done && addr >= AC_Z3_BASE && addr < AC_Z3_BASE + AC_SIZE) {
+        if (ac_z3_pic_count == 0) {
+            ac_z3_done = 1;
+            return -1;
+        }
+
+        if (type == OP_TYPE_BYTE) {
+            *val = autoconfig_read_memory_z3_8(cfg, addr);
+            return 1;
+        }
+        else {
+            printf("Unexpected %s read from Z3 autoconf addr %.X\n", op_type_names[type], addr - AC_Z3_BASE);
+            //stop_emulation();
+        }
+    }
+
+    return -1;
+}
+
+int custom_write_amiga(struct emulator_config *cfg, unsigned int addr, unsigned int val, unsigned char type) {
+    if (!ac_z2_done && addr >= AC_Z2_BASE && addr < AC_Z2_BASE + AC_SIZE) {
+        if (type == OP_TYPE_BYTE) {
+            if (ac_z2_pic_count == 0) {
+                ac_z2_done = 1;
+                return -1;
+            }
+
+            printf("Write to Z2 autoconf area.\n");
+            autoconfig_write_memory_8(cfg, addr, val);
+            return 1;
+        }
+    }
+
+    if (!ac_z3_done && addr >= AC_Z3_BASE && addr < AC_Z3_BASE + AC_SIZE) {
+        if (type == OP_TYPE_BYTE) {
+            if (ac_z3_pic_count == 0) {
+                ac_z3_done = 1;
+                return -1;
+            }
+
+            //printf("Write to autoconf area.\n");
+            autoconfig_write_memory_z3_8(cfg, addr, val);
+            return 1;
+        }
+        else if (type == OP_TYPE_WORD) {
+            autoconfig_write_memory_z3_16(cfg, addr, val);
+            return 1;
+        }
+        else {
+            printf("Unexpected %s write to Z3 autoconf addr %.X\n", op_type_names[type], addr - AC_Z3_BASE);
+            //stop_emulation();
+        }
+    }
+
+    return -1;
+}
+
+int setup_platform_amiga(struct emulator_config *cfg) {
+    if (cfg) {}
+    printf("Performing setup for Amiga platform.\n");
+    // Look for Z2 autoconf Fast RAM by id
+    int index = get_named_mapped_item(cfg, z2_autoconf_id);
+    more_z2_fast:;
+    if (index != -1) {
+        // "Zap" config items as they are processed.
+        cfg->map_id[index][0] = '^';
+        int resize_data = 0;
+        if (cfg->map_size[index] > 8 * SIZE_MEGA) {
+            printf("Attempted to configure more than 8MB of Z2 Fast RAM, downsizng to 8MB.\n");
+            resize_data = 8 * SIZE_MEGA;
+        }
+        else if(cfg->map_size[index] != 2 * SIZE_MEGA && cfg->map_size[index] != 4 * SIZE_MEGA && cfg->map_size[index] != 8 * SIZE_MEGA) {
+            printf("Z2 Fast RAM may only provision 2, 4 or 8MB of memory, resizing to ");
+            if (cfg->map_size[index] > 8 * SIZE_MEGA)
+                resize_data = 8 * SIZE_MEGA;
+            else if (cfg->map_size[index] > 4 * SIZE_MEGA)
+                resize_data = 4 * SIZE_MEGA;
+            else
+                resize_data = 2 * SIZE_MEGA;
+            printf("%dMB.\n", resize_data / SIZE_MEGA);
+        }
+        if (resize_data) {
+            free(cfg->map_data[index]);
+            cfg->map_size[index] = resize_data;
+            cfg->map_data[index] = (unsigned char *)malloc(cfg->map_size[index]);
+        }
+        printf("%dMB of Z2 Fast RAM configured at $%lx\n", cfg->map_size[index] / SIZE_MEGA, cfg->map_offset[index]);
+        ac_z2_type[ac_z2_pic_count] = ACTYPE_MAPFAST_Z2;
+        ac_z2_index[ac_z2_pic_count] = index;
+        ac_z2_pic_count++;
+    }
+    else
+        printf("No Z2 Fast RAM configured.\n");
+
+    index = get_named_mapped_item(cfg, z2_autoconf_id);
+    if (index != -1)
+        goto more_z2_fast;
+    
+    for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i ++) {
+        // Restore any "zapped" autoconf items so they can be reinitialized if needed.
+        if (cfg->map_id[i] && strcmp(cfg->map_id[i], z2_autoconf_zap_id) == 0) {
+            cfg->map_id[i][0] = z2_autoconf_id[0];
+        }
+    }
+
+    index = get_named_mapped_item(cfg, z3_autoconf_id);
+    more_z3_fast:;
+    if (index != -1) {
+        cfg->map_id[index][0] = '^';
+        printf("%dMB of Z3 Fast RAM configured at $%lx\n", cfg->map_size[index] / SIZE_MEGA, cfg->map_offset[index]);
+        ac_z3_type[ac_z3_pic_count] = ACTYPE_MAPFAST_Z3;
+        ac_z3_index[ac_z3_pic_count] = index;
+        ac_z3_pic_count++;
+    }
+    else
+        printf("No Z3 Fast RAM configured.\n");
+    index = get_named_mapped_item(cfg, z3_autoconf_id);
+    if (index != -1)
+        goto more_z3_fast;
+    for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i ++) {
+        if (cfg->map_id[i] && strcmp(cfg->map_id[i], z3_autoconf_zap_id) == 0) {
+            cfg->map_id[i][0] = z3_autoconf_id[0];
+        }
+    }
+    
+    return 0;
+}
+
+void setvar_amiga(char *var, char *val) {
+    if (var || val) {}
+}
+
+void create_platform_amiga(struct platform_config *cfg, char *subsys) {
+    cfg->register_read = handle_register_read_amiga;
+    cfg->register_write = handle_register_write_amiga;
+    cfg->custom_read = custom_read_amiga;
+    cfg->custom_write = custom_write_amiga;
+    cfg->platform_initial_setup = setup_platform_amiga;
+
+    cfg->setvar = setvar_amiga;
+
+    if (subsys) {
+        cfg->subsys = malloc(strlen(subsys) + 1);
+        strcpy(cfg->subsys, subsys);
+    }
+}
similarity index 80%
rename from registers/registers_amiga.c
rename to platforms/amiga/amiga-registers.c
index 62e4255244614fe62d1fe98b8e9116b577973fac..0357dfc1cee4e199f21ea7dba9c7874129109fd5 100644 (file)
@@ -1,10 +1,10 @@
-#include "../Gayle.h"
-#include "../config_file/config_file.h"
+#include "../../Gayle.h"
+#include "../../config_file/config_file.h"
 
 #define GAYLEBASE 0xD80000  // D7FFFF
 #define GAYLESIZE 0x6FFFF
 
-int handle_register_read(unsigned int addr, unsigned char type, unsigned int *val) {
+int handle_register_read_amiga(unsigned int addr, unsigned char type, unsigned int *val) {
     if (addr > GAYLEBASE && addr < GAYLEBASE + GAYLESIZE) {
         switch(type) {
         case OP_TYPE_BYTE:
@@ -27,7 +27,7 @@ int handle_register_read(unsigned int addr, unsigned char type, unsigned int *va
     return -1;
 }
 
-int handle_register_write(unsigned int addr, unsigned int value, unsigned char type) {
+int handle_register_write_amiga(unsigned int addr, unsigned int value, unsigned char type) {
     if (addr > GAYLEBASE && addr < GAYLEBASE + GAYLESIZE) {
         switch(type) {
         case OP_TYPE_BYTE:
diff --git a/platforms/dummy/dummy-platform.c b/platforms/dummy/dummy-platform.c
new file mode 100644 (file)
index 0000000..7e431e0
--- /dev/null
@@ -0,0 +1,24 @@
+#include "../platforms.h"
+#include <stdlib.h>
+#include <string.h>
+
+int handle_register_read_dummy(unsigned int addr, unsigned char type, unsigned int *val);
+int handle_register_write_dummy(unsigned int addr, unsigned int value, unsigned char type);
+
+int setup_platform_dummy(struct emulator_config *cfg) {
+    if (cfg) {}
+    return 0;
+}
+
+void create_platform_dummy(struct platform_config *cfg, char *subsys) {
+    cfg->custom_read = NULL;
+    cfg->custom_write = NULL;
+    cfg->register_read = handle_register_read_dummy;
+    cfg->register_write = handle_register_write_dummy;
+    cfg->platform_initial_setup = setup_platform_dummy;
+
+    if (subsys) {
+        cfg->subsys = malloc(strlen(subsys) + 1);
+        strcpy(cfg->subsys, subsys);
+    }
+}
diff --git a/platforms/dummy/dummy-registers.c b/platforms/dummy/dummy-registers.c
new file mode 100644 (file)
index 0000000..b9c4dea
--- /dev/null
@@ -0,0 +1,13 @@
+int handle_register_read_dummy(unsigned int addr, unsigned char type, unsigned int *val) {
+    if (addr) {}
+    if (type) {}
+    if (val) {}
+    return -1;
+}
+
+int handle_register_write_dummy(unsigned int addr, unsigned int value, unsigned char type) {
+    if (addr) {}
+    if (type) {}
+    if (value) {}
+    return -1;
+}
diff --git a/platforms/platforms.c b/platforms/platforms.c
new file mode 100644 (file)
index 0000000..c28004e
--- /dev/null
@@ -0,0 +1,60 @@
+#include "platforms.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char*platform_names[PLATFORM_NUM] = {
+    "none",
+    "amiga",
+    "mac68k",
+    "x68000",
+};
+
+int get_platform_index(char *name) {
+    if (!name || strlen(name) == 0)
+        return -1;
+
+    for (int i = 0; i < PLATFORM_NUM; i++) {
+        if (strcmp(name, platform_names[i]) == 0)
+            return i;
+    }
+    return -1;
+}
+
+void create_platform_amiga(struct platform_config *cfg, char *subsys);
+void create_platform_dummy(struct platform_config *cfg, char *subsys);
+
+struct platform_config *make_platform_config(char *name, char *subsys) {
+    struct platform_config *cfg = NULL;
+    int platform_id = get_platform_index(name);
+
+    if (platform_id == -1) {
+        // Display a warning if no match is found for the config name, in case it was mistyped.
+        printf("No match found for platform name \'%s\', defaulting to none/generic.\n", name);
+        platform_id = PLATFORM_NONE;
+    }
+    else {
+        printf("Creating platform config for %s...\n", name);
+    }
+
+    cfg = (struct platform_config *)malloc(sizeof(struct platform_config));
+    if (!cfg) {
+        printf("Failed to allocate memory for new platform config!.\n");
+        return NULL;
+    }
+    memset(cfg, 0x00, sizeof(struct platform_config));
+
+    switch(platform_id) {
+        case PLATFORM_AMIGA:
+            create_platform_amiga(cfg, subsys);
+            break;
+        case PLATFORM_NONE:
+        case PLATFORM_MAC:
+        case PLATFORM_X68000:
+        default:
+            create_platform_dummy(cfg, subsys);
+            break;
+    }
+
+    return cfg;
+}
\ No newline at end of file
diff --git a/platforms/platforms.h b/platforms/platforms.h
new file mode 100644 (file)
index 0000000..82a2868
--- /dev/null
@@ -0,0 +1,11 @@
+#include "../config_file/config_file.h"
+
+enum base_platforms {
+    PLATFORM_NONE,
+    PLATFORM_AMIGA,
+    PLATFORM_MAC,
+    PLATFORM_X68000,
+    PLATFORM_NUM,
+};
+
+struct platform_config *make_platform_config(char *name, char *subsys);
diff --git a/registers/registers_dummy.c b/registers/registers_dummy.c
deleted file mode 100644 (file)
index e00159c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-int handle_register_read(unsigned int addr, unsigned char type) {
-    return -1;
-}
-
-int handle_register_write(unsigned int addr, unsigned char type) {
-    return -1;
-}