#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+
#include "Gayle.h"
+#include "a314/a314.h"
#include "ide.h"
#include "m68k.h"
#include "main.h"
reset |= (1 << (no)); \
} while (0)
-#define FASTBASE 0x07FFFFFF
-#define FASTSIZE 0xFFFFFFF
-#define GAYLEBASE 0xD80000 // D7FFFF
-#define GAYLESIZE 0x6FFFF
+int fast_base_configured;
+unsigned int fast_base;
+#define FAST_SIZE (8 * 1024 * 1024)
+
+#define GAYLEBASE 0xD80000
+#define GAYLESIZE (448 * 1024)
#define KICKBASE 0xF80000
-#define KICKSIZE 0x7FFFF
+#define KICKSIZE (512 * 1024)
+
+#define AC_BASE 0xE80000
+#define AC_SIZE (64 * 1024)
+
+#define AC_PIC_COUNT 2
+int ac_current_pic = 0;
+int ac_done = 0;
int mem_fd;
int mem_fd_gpclk;
volatile uint32_t srdata2;
volatile uint32_t srdata2_old;
-unsigned char g_kick[524288];
-unsigned char g_ram[FASTSIZE + 1]; /* RAM */
+unsigned char g_kick[KICKSIZE];
+unsigned char fast_ram_array[FAST_SIZE]; /* RAM */
unsigned char toggle;
static volatile unsigned char ovl;
static volatile unsigned char maprom;
printf("IPL thread running/n");
while (42) {
-
- if (GET_GPIO(1) == 0){
- toggle = 1;
+ if (GET_GPIO(1) == 0) {
+ toggle = 1;
m68k_end_timeslice();
- //printf("thread!/n");
+ //printf("thread!/n");
} else {
- toggle = 0;
+ toggle = 0;
};
usleep(1);
}
-
}
int main(int argc, char *argv[]) {
}
}
+#if A314_ENABLED
+ int err = a314_init();
+ if (err < 0) {
+ printf("Unable to initialize A314 emulation\n");
+ return -1;
+ }
+#endif
+
sched_setscheduler(0, SCHED_FIFO, &priority);
mlockall(MCL_CURRENT); // lock in memory to keep us from paging out
m68k_set_reg(M68K_REG_PC, 0x0);
}
-/*
+ /*
pthread_t id;
int err;
err = pthread_create(&id, NULL, &iplThread, NULL);
m68k_pulse_reset();
while (42) {
-
m68k_execute(300);
-/*
+ /*
if (toggle == 1){
srdata = read_reg();
m68k_set_irq((srdata >> 13) & 0xff);
usleep(1);
*/
+#if A314_ENABLED
+ a314_process_events();
+#endif
- if (GET_GPIO(1) == 0){
+ if (GET_GPIO(1) == 0) {
srdata = read_reg();
m68k_set_irq((srdata >> 13) & 0xff);
} else {
- if (CheckIrq() == 1){
+ if (CheckIrq() == 1) {
write16(0xdff09c, 0x8008);
- m68k_set_irq(2);}
- else
- m68k_set_irq(0);
+ m68k_set_irq(2);
+ } else
+ m68k_set_irq(0);
};
-
}
return 0;
return level;
}
+#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
+
+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
+};
+
+static unsigned int autoconfig_read_memory_8(unsigned int address) {
+ unsigned char *rom = NULL;
+
+ if (ac_current_pic == 0)
+ rom = ac_fast_ram_rom;
+ else if (ac_current_pic == 1)
+ rom = ac_a314_rom;
+
+ unsigned char val = 0;
+ if ((address & 1) == 0 && (address / 2) < sizeof(ac_fast_ram_rom))
+ val = rom[address / 2];
+ val <<= 4;
+ if (address != 0 && address != 2 && address != 40 && address != 42)
+ val ^= 0xf0;
+ return (unsigned int)val;
+}
+
+static void autoconfig_write_memory_8(unsigned int address, unsigned int value) {
+ int done = 0;
+
+ unsigned int *base = NULL;
+ int *base_configured = NULL;
+
+ if (ac_current_pic == 0) {
+ base = &fast_base;
+ base_configured = &fast_base_configured;
+ } else if (ac_current_pic == 1) {
+ base = &a314_base;
+ base_configured = &a314_base_configured;
+ }
+
+ 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);
+ *base_configured = 1;
+
+ if (ac_current_pic == 0) // fast ram
+ a314_set_mem_base_size(*base, FAST_SIZE);
+
+ done = 1;
+ } else if (address == 0x4c) { // shut up
+ done = 1;
+ }
+
+ if (done) {
+ ac_current_pic++;
+ if (ac_current_pic == AC_PIC_COUNT)
+ ac_done = 1;
+ }
+}
+
unsigned int m68k_read_memory_8(unsigned int address) {
- if (address > FASTBASE && address < FASTBASE + FASTSIZE) {
- return g_ram[address - FASTBASE];
+ if (fast_base_configured && address >= fast_base && address < fast_base + FAST_SIZE) {
+ return fast_ram_array[address - fast_base];
+ }
+
+ if (!ac_done && address >= AC_BASE && address < AC_BASE + AC_SIZE) {
+ return autoconfig_read_memory_8(address - AC_BASE);
}
if (maprom == 1) {
- if (address > KICKBASE && address < KICKBASE + KICKSIZE) {
+ if (address >= KICKBASE && address < KICKBASE + KICKSIZE) {
return g_kick[address - KICKBASE];
}
}
if (gayle_emulation_enabled) {
- if (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
+ if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
return readGayleB(address);
}
}
- address &=0xFFFFFF;
-// if (address < 0xffffff) {
- return read8((uint32_t)address);
-// }
+#if A314_ENABLED
+ if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) {
+ return a314_read_memory_8(address - a314_base);
+ }
+#endif
-// return 1;
+ address &= 0xFFFFFF;
+ // if (address < 0xffffff) {
+ return read8((uint32_t)address);
+ // }
+
+ // return 1;
}
unsigned int m68k_read_memory_16(unsigned int address) {
- if (address > FASTBASE && address < FASTBASE + FASTSIZE) {
- return be16toh(*(uint16_t *)&g_ram[address - FASTBASE]);
+ if (fast_base_configured && address >= fast_base && address < fast_base + FAST_SIZE) {
+ return be16toh(*(uint16_t *)&fast_ram_array[address - fast_base]);
}
if (maprom == 1) {
- if (address > KICKBASE && address < KICKBASE + KICKSIZE) {
+ if (address >= KICKBASE && address < KICKBASE + KICKSIZE) {
return be16toh(*(uint16_t *)&g_kick[address - KICKBASE]);
}
}
if (gayle_emulation_enabled) {
- if (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
+ if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
return readGayle(address);
}
}
-// if (address < 0xffffff) {
- address &=0xFFFFFF;
- return (unsigned int)read16((uint32_t)address);
-// }
+#if A314_ENABLED
+ if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) {
+ return a314_read_memory_16(address - a314_base);
+ }
+#endif
+
+ // if (address < 0xffffff) {
+ address &= 0xFFFFFF;
+ return (unsigned int)read16((uint32_t)address);
+ // }
-// return 1;
+ // return 1;
}
unsigned int m68k_read_memory_32(unsigned int address) {
- if (address > FASTBASE && address < FASTBASE + FASTSIZE) {
- return be32toh(*(uint32_t *)&g_ram[address - FASTBASE]);
+ if (fast_base_configured && address >= fast_base && address < fast_base + FAST_SIZE) {
+ return be32toh(*(uint32_t *)&fast_ram_array[address - fast_base]);
}
if (maprom == 1) {
- if (address > KICKBASE && address < KICKBASE + KICKSIZE) {
+ if (address >= KICKBASE && address < KICKBASE + KICKSIZE) {
return be32toh(*(uint32_t *)&g_kick[address - KICKBASE]);
}
}
if (gayle_emulation_enabled) {
- if (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
+ if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
return readGayleL(address);
}
}
-// if (address < 0xffffff) {
- address &=0xFFFFFF;
- uint16_t a = read16(address);
- uint16_t b = read16(address + 2);
- return (a << 16) | b;
-// }
+#if A314_ENABLED
+ if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) {
+ return a314_read_memory_32(address - a314_base);
+ }
+#endif
+
+ // if (address < 0xffffff) {
+ address &= 0xFFFFFF;
+ uint16_t a = read16(address);
+ uint16_t b = read16(address + 2);
+ return (a << 16) | b;
+ // }
-// return 1;
+ // return 1;
}
void m68k_write_memory_8(unsigned int address, unsigned int value) {
- if (address > FASTBASE && address < FASTBASE + FASTSIZE) {
- g_ram[address - FASTBASE] = value;
+ if (fast_base_configured && address >= fast_base && address < fast_base + FAST_SIZE) {
+ fast_ram_array[address - fast_base] = value;
+ return;
+ }
+
+ if (!ac_done && address >= AC_BASE && address < AC_BASE + AC_SIZE) {
+ autoconfig_write_memory_8(address - AC_BASE, value);
return;
}
if (gayle_emulation_enabled) {
- if (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
+ if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
writeGayleB(address, value);
return;
}
}
-/*
+
+#if A314_ENABLED
+ if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) {
+ a314_write_memory_8(address - a314_base, value);
+ return;
+ }
+#endif
+
+ /*
if (address == 0xbfe001) {
ovl = (value & (1 << 0));
printf("OVL:%x\n", ovl);
}
*/
-// if (address < 0xffffff) {
- address &=0xFFFFFF;
- write8((uint32_t)address, value);
- return;
-// }
+ // if (address < 0xffffff) {
+ address &= 0xFFFFFF;
+ write8((uint32_t)address, value);
+ return;
+ // }
-// return;
+ // return;
}
void m68k_write_memory_16(unsigned int address, unsigned int value) {
- if (address > FASTBASE && address < FASTBASE + FASTSIZE) {
- *(uint16_t *)&g_ram[address - FASTBASE] = htobe16(value);
+ if (fast_base_configured && address >= fast_base && address < fast_base + FAST_SIZE) {
+ *(uint16_t *)&fast_ram_array[address - fast_base] = htobe16(value);
return;
}
if (gayle_emulation_enabled) {
- if (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
+ if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
writeGayle(address, value);
return;
}
}
-// if (address < 0xffffff) {
- address &=0xFFFFFF;
- write16((uint32_t)address, value);
+#if A314_ENABLED
+ if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) {
+ a314_write_memory_16(address - a314_base, value);
return;
-// }
-// return;
+ }
+#endif
+
+ // if (address < 0xffffff) {
+ address &= 0xFFFFFF;
+ write16((uint32_t)address, value);
+ return;
+ // }
+ // return;
}
void m68k_write_memory_32(unsigned int address, unsigned int value) {
- if (address > FASTBASE && address < FASTBASE + FASTSIZE) {
- *(uint32_t *)&g_ram[address - FASTBASE] = htobe32(value);
+ if (fast_base_configured && address >= fast_base && address < fast_base + FAST_SIZE) {
+ *(uint32_t *)&fast_ram_array[address - fast_base] = htobe32(value);
return;
}
if (gayle_emulation_enabled) {
- if (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
+ if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) {
writeGayleL(address, value);
}
}
-// if (address < 0xffffff) {
- address &=0xFFFFFF;
- write16(address, value >> 16);
- write16(address + 2, value);
+#if A314_ENABLED
+ if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) {
+ a314_write_memory_32(address - a314_base, value);
return;
-// }
+ }
+#endif
+
+ // if (address < 0xffffff) {
+ address &= 0xFFFFFF;
+ write16(address, value >> 16);
+ write16(address + 2, value);
+ return;
+ // }
-// return;
+ // return;
}
void write16(uint32_t address, uint32_t data) {
// asm volatile ("dmb" ::: "memory");
W16
- *(gpio) = gpfsel0_o;
+ *(gpio) = gpfsel0_o;
*(gpio + 1) = gpfsel1_o;
*(gpio + 2) = gpfsel2_o;
// asm volatile ("dmb" ::: "memory");
W8
- *(gpio) = gpfsel0_o;
+ *(gpio) = gpfsel0_o;
*(gpio + 1) = gpfsel1_o;
*(gpio + 2) = gpfsel2_o;
// asm volatile ("dmb" ::: "memory");
R16
- *(gpio) = gpfsel0_o;
+ *(gpio) = gpfsel0_o;
*(gpio + 1) = gpfsel1_o;
*(gpio + 2) = gpfsel2_o;
// asm volatile ("dmb" ::: "memory");
R8
- *(gpio) = gpfsel0_o;
+ *(gpio) = gpfsel0_o;
*(gpio + 1) = gpfsel1_o;
*(gpio + 2) = gpfsel2_o;