X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=emulator.c;h=a18513b3960218283474b7fca959a65764288634;hb=d926b66c4cb06a963d1bc8d58c1c504346a95ffd;hp=35b6b9e7847ac6044ee8ad17daa87c3086d06326;hpb=e35f5657b27f144832817a4eac710adb7a3d4625;p=pistorm diff --git a/emulator.c b/emulator.c index 35b6b9e..a18513b 100644 --- a/emulator.c +++ b/emulator.c @@ -1,3 +1,7 @@ +/* +Copyright 2020 Claude Schwartz +*/ + #include #include #include @@ -13,7 +17,9 @@ #include #include #include + #include "Gayle.h" +#include "a314/a314.h" #include "ide.h" #include "m68k.h" #include "main.h" @@ -66,16 +72,26 @@ 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; +int gayle_emulation_enabled = 1; void *gpio_map; void *gpclk_map; @@ -125,8 +141,8 @@ volatile uint16_t srdata; 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; @@ -137,17 +153,39 @@ void sigint_handler(int sig_num) { } void *iplThread(void *args) { - printf("thread!/n"); + printf("IPL thread running/n"); while (42) { + if (GET_GPIO(1) == 0) { + toggle = 1; + m68k_end_timeslice(); + //printf("thread!/n"); + } else { + toggle = 0; + }; usleep(1); } } -int main() { +int main(int argc, char *argv[]) { int g; const struct sched_param priority = {99}; + // Some command line switch stuffles + for (g = 1; g < argc; g++) { + if (strcmp(argv[g], "--disable-gayle") == 0) { + gayle_emulation_enabled = 0; + } + } + +#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 @@ -259,7 +297,7 @@ int main() { usleep(1500); m68k_init(); - m68k_set_cpu_type(M68K_CPU_TYPE_68030); + m68k_set_cpu_type(M68K_CPU_TYPE_68020); m68k_pulse_reset(); if (maprom == 1) { @@ -269,23 +307,41 @@ int main() { } /* - pthread_t id; - int err; - //err = pthread_create(&id, NULL, &iplThread, NULL); + pthread_t id; + int err; + err = pthread_create(&id, NULL, &iplThread, NULL); if (err != 0) printf("\ncan't create IPL thread :[%s]", strerror(err)); else printf("\n IPL Thread created successfully\n"); - */ +*/ m68k_pulse_reset(); while (42) { - m68k_execute(3000); + m68k_execute(300); + /* + if (toggle == 1){ + srdata = read_reg(); + m68k_set_irq((srdata >> 13) & 0xff); + } else { + m68k_set_irq(0); + }; + usleep(1); +*/ + +#if A314_ENABLED + a314_process_events(); +#endif + if (GET_GPIO(1) == 0) { srdata = read_reg(); m68k_set_irq((srdata >> 13) & 0xff); } else { - m68k_set_irq(0); + if (CheckIrq() == 1) { + write16(0xdff09c, 0x8008); + m68k_set_irq(2); + } else + m68k_set_irq(0); }; } @@ -305,133 +361,280 @@ int cpu_irq_ack(int level) { 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 (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { - return readGayleB(address); + if (gayle_emulation_enabled) { + if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { + return readGayleB(address); + } } - 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 0; + 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 (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { - return readGayle(address); + if (gayle_emulation_enabled) { + if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { + return readGayle(address); + } } - if (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 - return 0; + // if (address < 0xffffff) { + address &= 0xFFFFFF; + return (unsigned int)read16((uint32_t)address); + // } + + // 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 (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { - return readGayleL(address); + if (gayle_emulation_enabled) { + if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { + return readGayleL(address); + } } - if (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 - return 0; + // if (address < 0xffffff) { + address &= 0xFFFFFF; + uint16_t a = read16(address); + uint16_t b = read16(address + 2); + return (a << 16) | b; + // } + + // 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 (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { - writeGayleB(address, value); + if (!ac_done && address >= AC_BASE && address < AC_BASE + AC_SIZE) { + autoconfig_write_memory_8(address - AC_BASE, value); return; } - if (address == 0xbfe001) { - ovl = (value & (1 << 0)); - printf("OVL:%x\n", ovl); + if (gayle_emulation_enabled) { + if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { + writeGayleB(address, value); + return; + } } - if (address < 0xffffff) { - write8((uint32_t)address, value); +#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; + // } + + // 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 (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { - writeGayle(address, value); - return; + if (gayle_emulation_enabled) { + if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { + writeGayle(address, value); + return; + } } - if (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; } +#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 (address > GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { - writeGayleL(address, value); + if (gayle_emulation_enabled) { + if (address >= GAYLEBASE && address < GAYLEBASE + GAYLESIZE) { + writeGayleL(address, value); + } } - if (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; } void write16(uint32_t address, uint32_t data) { @@ -443,7 +646,8 @@ void write16(uint32_t address, uint32_t data) { uint32_t data_r = (~data & 0x0000ffff) << 8; // asm volatile ("dmb" ::: "memory"); - W16 *(gpio) = gpfsel0_o; + W16 + *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; @@ -484,7 +688,8 @@ void write8(uint32_t address, uint32_t data) { uint32_t data_r = (~data & 0x0000ffff) << 8; // asm volatile ("dmb" ::: "memory"); - W8 *(gpio) = gpfsel0_o; + W8 + *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; @@ -521,7 +726,6 @@ uint32_t read16(uint32_t address) { // asm volatile ("dmb" ::: "memory"); R16 - *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; @@ -558,7 +762,8 @@ uint32_t read8(uint32_t address) { uint32_t addr_l_r = (~address >> 16) << 8; // asm volatile ("dmb" ::: "memory"); - R8 *(gpio) = gpfsel0_o; + R8 + *(gpio) = gpfsel0_o; *(gpio + 1) = gpfsel1_o; *(gpio + 2) = gpfsel2_o; @@ -587,10 +792,9 @@ uint32_t read8(uint32_t address) { val = (val >> 8) & 0xffff; if ((address & 1) == 0) - val = (val >> 8) & 0xff; // EVEN, A0=0,UDS + return (val >> 8) & 0xff; // EVEN, A0=0,UDS else - val = val & 0xff; // ODD , A0=1,LDS - return val; + return val & 0xff; // ODD , A0=1,LDS } /******************************************************/