From: Niklas Ekström Date: Tue, 1 Dec 2020 22:39:13 +0000 (+0100) Subject: Add code to autoconfigure A314 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=d926b66c4cb06a963d1bc8d58c1c504346a95ffd;p=pistorm Add code to autoconfigure A314 --- diff --git a/a314/a314.cc b/a314/a314.cc index 4d5dfe6..70b45d5 100644 --- a/a314/a314.cc +++ b/a314/a314.cc @@ -108,7 +108,9 @@ static int irq_fds[2]; extern "C" unsigned char fast_ram_array[]; extern "C" void write16(unsigned int address, unsigned int value); -// Register bank in 0xE90000 memory. +unsigned int a314_base; +int a314_base_configured; + struct ComArea { uint8_t a_events; @@ -116,6 +118,9 @@ struct ComArea uint8_t r_events; uint8_t r_enable; // Unused. + uint32_t mem_base; + uint32_t mem_size; + uint8_t a2r_tail; uint8_t r2a_head; uint8_t r2a_tail; @@ -1295,10 +1300,6 @@ static void write_r_events(uint8_t events) logger_error("Write to interrupt socket pair did not return 1\n"); } -#ifdef __cplusplus -extern "C" { -#endif - int a314_init() { std::string conf_filename("/etc/opt/a314/a314d.conf"); @@ -1322,6 +1323,12 @@ int a314_init() return 0; } +void a314_set_mem_base_size(unsigned int base, unsigned int size) +{ + ca.mem_base = htobe32(base); + ca.mem_size = htobe32(size); +} + void a314_process_events() { if (ca.a_events & ca.a_enable) @@ -1355,14 +1362,20 @@ unsigned int a314_read_memory_8(unsigned int address) unsigned int a314_read_memory_16(unsigned int address) { - // Not implemented. - return 0; + if (address >= sizeof(ca)) + return 0; + + uint16_t *p = (uint16_t *)&ca; + return be16toh(p[address >> 1]); } unsigned int a314_read_memory_32(unsigned int address) { - // Not implemented. - return 0; + if (address >= sizeof(ca)) + return 0; + + uint32_t *p = (uint32_t *)&ca; + return be32toh(p[address >> 2]); } void a314_write_memory_8(unsigned int address, unsigned int value) @@ -1399,7 +1412,3 @@ void a314_write_memory_32(unsigned int address, unsigned int value) { // Not implemented. } - -#ifdef __cplusplus -} -#endif diff --git a/a314/a314.h b/a314/a314.h index 14fca5b..fa15430 100644 --- a/a314/a314.h +++ b/a314/a314.h @@ -9,11 +9,13 @@ extern "C" { #define A314_ENABLED 1 -// TODO: Base address should be obtained dynamically through Auto-Config. -#define A314_COM_AREA_BASE 0xE90000 -#define A314_COM_AREA_SIZE (64*1024) +extern unsigned int a314_base; +extern int a314_base_configured; + +#define A314_COM_AREA_SIZE (64 * 1024) int a314_init(); +void a314_set_mem_base_size(unsigned int base, unsigned int size); void a314_process_events(); unsigned int a314_read_memory_8(unsigned int address); diff --git a/a314/a314device/fix_mem_region.c b/a314/a314device/fix_mem_region.c index 9d9587c..802dcae 100644 --- a/a314/a314device/fix_mem_region.c +++ b/a314/a314device/fix_mem_region.c @@ -106,7 +106,6 @@ void mark_region_a314(ULONG address, ULONG size) Enqueue(memlist, (struct Node *)new_mh); } - mh->mh_Node.ln_Pri = -20; mh->mh_Attributes |= MEMF_A314; Enqueue(memlist, (struct Node *)mh); return; @@ -117,15 +116,15 @@ void mark_region_a314(ULONG address, ULONG size) BOOL fix_memory() { Forbid(); - mark_region_a314(PISTORM_BASE, PISTORM_SIZE); + mark_region_a314(ca->mem_base, ca->mem_size); Permit(); return TRUE; } ULONG translate_address_a314(__reg("a0") void *address) { - ULONG offset = (ULONG)address - PISTORM_BASE; - if (offset < PISTORM_SIZE) + ULONG offset = (ULONG)address - ca->mem_base; + if (offset < ca->mem_size) return offset; return -1; } diff --git a/a314/a314device/int_server.asm b/a314/a314device/int_server.asm index 2a7b866..e7d582f 100644 --- a/a314/a314device/int_server.asm +++ b/a314/a314device/int_server.asm @@ -1,13 +1,11 @@ XDEF _IntServer CODE -COM_AREA equ $e90000 - SIGB_INT equ 14 SIGF_INT equ (1 << SIGB_INT) - ; a1 points to driver task -_IntServer: lea.l COM_AREA,a5 + ; a1 points to interrupt_data +_IntServer: move.l 4(a1),a5 ; interrupt_data.ca move.b 0(a5),d0 ; A_EVENTS and.b 1(a5),d0 ; A_ENABLE @@ -17,7 +15,7 @@ _IntServer: lea.l COM_AREA,a5 move.l $4.w,a6 move.l #SIGF_INT,d0 - ; a1 = pointer to driver task + move.l 0(a1),a1 ; interrupt_data.task jsr -324(a6) ; Signal() should_not_signal: diff --git a/a314/a314device/protocol.h b/a314/a314device/protocol.h index 6ff50a2..28dc168 100644 --- a/a314/a314device/protocol.h +++ b/a314/a314device/protocol.h @@ -19,11 +19,6 @@ #define A_EVENT_R2A_TAIL 1 #define A_EVENT_A2R_HEAD 2 -#define COM_AREA_BASE 0xe90000 - -#define PISTORM_BASE 0xc00000 -#define PISTORM_SIZE (3*512*1024) - // The communication area, used to create the physical channel. struct ComArea { @@ -32,6 +27,9 @@ struct ComArea volatile UBYTE r_events; volatile UBYTE r_enable; + ULONG mem_base; + ULONG mem_size; + volatile UBYTE a2r_tail; volatile UBYTE r2a_head; volatile UBYTE r2a_tail; diff --git a/a314/a314device/startup.c b/a314/a314device/startup.c index cce7a13..ccb3bb6 100644 --- a/a314/a314device/startup.c +++ b/a314/a314device/startup.c @@ -2,8 +2,11 @@ #include #include #include +#include +#include #include +#include #include "a314.h" #include "device.h" @@ -12,13 +15,24 @@ #include "fix_mem_region.h" #include "debug.h" +#define A314_MANUFACTURER 0x07db +#define A314_PRODUCT 0xa3 + #define TASK_PRIORITY 80 #define TASK_STACK_SIZE 1024 +struct ExpansionBase *ExpansionBase; struct MsgPort task_mp; struct Task *task; struct ComArea *ca; +struct InterruptData +{ + struct Task *task; + struct ComArea *ca; +}; + +struct InterruptData interrupt_data; struct Interrupt ports_interrupt; extern void task_main(); @@ -69,10 +83,13 @@ static void init_message_port() static void add_interrupt_handler() { + interrupt_data.task = task; + interrupt_data.ca = ca; + ports_interrupt.is_Node.ln_Type = NT_INTERRUPT; ports_interrupt.is_Node.ln_Pri = 0; ports_interrupt.is_Node.ln_Name = device_name; - ports_interrupt.is_Data = (APTR)task; + ports_interrupt.is_Data = (APTR)&interrupt_data; ports_interrupt.is_Code = IntServer; AddIntServer(INTB_PORTS, &ports_interrupt); @@ -80,10 +97,21 @@ static void add_interrupt_handler() BOOL task_start() { - if (!fix_memory()) + ExpansionBase = (struct ExpansionBase *)OpenLibrary(EXPANSIONNAME, 0); + if (!ExpansionBase) + return FALSE; + + struct ConfigDev *cd = FindConfigDev(NULL, A314_MANUFACTURER, A314_PRODUCT); + if (!cd) + { + CloseLibrary((struct Library *)ExpansionBase); return FALSE; + } - ca = (struct ComArea *)COM_AREA_BASE; + ca = (struct ComArea *)cd->cd_BoardAddr; + + if (!fix_memory()) + return FALSE; task = create_task(device_name, TASK_PRIORITY, (void *)task_main, TASK_STACK_SIZE); if (task == NULL) diff --git a/emulator.c b/emulator.c index 9b2b497..a18513b 100644 --- a/emulator.c +++ b/emulator.c @@ -85,7 +85,7 @@ unsigned int fast_base; #define AC_BASE 0xE80000 #define AC_SIZE (64 * 1024) -#define AC_PIC_COUNT 1 +#define AC_PIC_COUNT 2 int ac_current_pic = 0; int ac_done = 0; @@ -361,8 +361,17 @@ 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, 0x0, // 00/02, link into memory free list, 8 MB + 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 @@ -370,25 +379,56 @@ static unsigned char ac_fast_ram_rom[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x2, 0x0 // 18/.../26, serial }; -static unsigned int ac_fast_ram_read_memory_8(unsigned int address) { +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 = ac_fast_ram_rom[address / 2]; + val = rom[address / 2]; val <<= 4; if (address != 0 && address != 2 && address != 40 && address != 42) val ^= 0xf0; return (unsigned int)val; } -static void ac_fast_ram_write_memory_8(unsigned int address, unsigned int value) { +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] - fast_base = (value & 0xf0) << (16 - 4); + *base = (value & 0xf0) << (16 - 4); } else if (address == 0x48) { // base[23:20] - fast_base &= 0xff0fffff; - fast_base |= (value & 0xf0) << (20 - 4); - fast_base_configured = 1; + *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; @@ -401,18 +441,6 @@ static void ac_fast_ram_write_memory_8(unsigned int address, unsigned int value) } } -static unsigned int autoconfig_read_memory_8(unsigned int address) { - if (ac_current_pic == 0) { - return ac_fast_ram_read_memory_8(address); - } -} - -static void autoconfig_write_memory_8(unsigned int address, unsigned int value) { - if (ac_current_pic == 0) { - return ac_fast_ram_write_memory_8(address, value); - } -} - unsigned int m68k_read_memory_8(unsigned int address) { if (fast_base_configured && address >= fast_base && address < fast_base + FAST_SIZE) { return fast_ram_array[address - fast_base]; @@ -435,8 +463,8 @@ unsigned int m68k_read_memory_8(unsigned int address) { } #if A314_ENABLED - if (address >= A314_COM_AREA_BASE && address < A314_COM_AREA_BASE + A314_COM_AREA_SIZE) { - return a314_read_memory_8(address - A314_COM_AREA_BASE); + if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) { + return a314_read_memory_8(address - a314_base); } #endif @@ -466,8 +494,8 @@ unsigned int m68k_read_memory_16(unsigned int address) { } #if A314_ENABLED - if (address >= A314_COM_AREA_BASE && address < A314_COM_AREA_BASE + A314_COM_AREA_SIZE) { - return a314_read_memory_16(address - A314_COM_AREA_BASE); + if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) { + return a314_read_memory_16(address - a314_base); } #endif @@ -497,8 +525,8 @@ unsigned int m68k_read_memory_32(unsigned int address) { } #if A314_ENABLED - if (address >= A314_COM_AREA_BASE && address < A314_COM_AREA_BASE + A314_COM_AREA_SIZE) { - return a314_read_memory_32(address - A314_COM_AREA_BASE); + if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) { + return a314_read_memory_32(address - a314_base); } #endif @@ -519,7 +547,8 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) { } if (!ac_done && address >= AC_BASE && address < AC_BASE + AC_SIZE) { - return autoconfig_write_memory_8(address - AC_BASE, value); + autoconfig_write_memory_8(address - AC_BASE, value); + return; } if (gayle_emulation_enabled) { @@ -530,8 +559,8 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) { } #if A314_ENABLED - if (address >= A314_COM_AREA_BASE && address < A314_COM_AREA_BASE + A314_COM_AREA_SIZE) { - a314_write_memory_8(address - A314_COM_AREA_BASE, value); + if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) { + a314_write_memory_8(address - a314_base, value); return; } #endif @@ -565,8 +594,8 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) { } #if A314_ENABLED - if (address >= A314_COM_AREA_BASE && address < A314_COM_AREA_BASE + A314_COM_AREA_SIZE) { - a314_write_memory_16(address - A314_COM_AREA_BASE, value); + if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) { + a314_write_memory_16(address - a314_base, value); return; } #endif @@ -592,8 +621,8 @@ void m68k_write_memory_32(unsigned int address, unsigned int value) { } #if A314_ENABLED - if (address >= A314_COM_AREA_BASE && address < A314_COM_AREA_BASE + A314_COM_AREA_SIZE) { - a314_write_memory_32(address - A314_COM_AREA_BASE, value); + if (a314_base_configured && address >= a314_base && address < a314_base + A314_COM_AREA_SIZE) { + a314_write_memory_32(address - a314_base, value); return; } #endif