X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=emulator.c;h=b13bbdc5ff93b8468879326287022af627b46f44;hb=e764148bb1100936360b13f666d55cf5d5bef6f3;hp=7dc17075b73ea46da73bb7b40f5916a414747034;hpb=b896610573badcc13db90775f61dda6a763150bb;p=pistorm diff --git a/emulator.c b/emulator.c index 7dc1707..b13bbdc 100644 --- a/emulator.c +++ b/emulator.c @@ -23,7 +23,11 @@ #include "platforms/amiga/gayle-ide/ide.h" #include "platforms/amiga/amiga-registers.h" #include "platforms/amiga/rtg/rtg.h" -#include "gpio/gpio.h" +#include "platforms/amiga/piscsi/piscsi.h" +#include "platforms/amiga/piscsi/piscsi-enums.h" +#include "platforms/amiga/net/pi-net.h" +#include "platforms/amiga/net/pi-net-enums.h" +#include "gpio/ps_protocol.h" unsigned char read_ranges; unsigned int read_addr[8]; @@ -41,8 +45,15 @@ int cpu_emulation_running = 1; char mouse_dx = 0, mouse_dy = 0; char mouse_buttons = 0; +extern uint8_t gayle_int; +extern uint8_t gayle_a4k_int; extern volatile unsigned int *gpio; extern volatile uint16_t srdata; +extern uint8_t realtime_graphics_debug; +uint8_t realtime_disassembly, int2_enabled = 0; +uint32_t do_disasm = 0; + +char disasm_buf[4096]; #define KICKBASE 0xF80000 #define KICKSIZE 0x7FFFF @@ -53,6 +64,12 @@ int gayle_emulation_enabled = 1; int irq; int gayleirq; +// Configurable emulator options +unsigned int cpu_type = M68K_CPU_TYPE_68000; +unsigned int loop_cycles = 300; +struct emulator_config *cfg = NULL; +char keyboard_file[256] = "/dev/input/event1"; + void *iplThread(void *args) { printf("IPL thread running\n"); @@ -65,7 +82,8 @@ void *iplThread(void *args) { irq = 0; if (gayle_emulation_enabled) { - if ((gayle_int & 0x80) && get_ide(0)->drive->intrq) { + if (((gayle_int & 0x80) || gayle_a4k_int) && (get_ide(0)->drive[0].intrq || get_ide(0)->drive[1].intrq)) { + //get_ide(0)->drive[0].intrq = 0; gayleirq = 1; m68k_end_timeslice(); } @@ -77,12 +95,21 @@ void *iplThread(void *args) { return args; } +void stop_cpu_emulation(uint8_t disasm_cur) { + m68k_end_timeslice(); + if (disasm_cur) { + m68k_disassemble(disasm_buf, m68k_get_reg(NULL, M68K_REG_PC), cpu_type); + printf("REGA: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1), m68k_get_reg(NULL, M68K_REG_A2), m68k_get_reg(NULL, M68K_REG_A3), \ + m68k_get_reg(NULL, M68K_REG_A4), m68k_get_reg(NULL, M68K_REG_A5), m68k_get_reg(NULL, M68K_REG_A6), m68k_get_reg(NULL, M68K_REG_A7)); + printf("REGD: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1), m68k_get_reg(NULL, M68K_REG_D2), m68k_get_reg(NULL, M68K_REG_D3), \ + m68k_get_reg(NULL, M68K_REG_D4), m68k_get_reg(NULL, M68K_REG_D5), m68k_get_reg(NULL, M68K_REG_D6), m68k_get_reg(NULL, M68K_REG_D7)); + printf("%.8X (%.8X)]] %s\n", m68k_get_reg(NULL, M68K_REG_PC), (m68k_get_reg(NULL, M68K_REG_PC) & 0xFFFFFF), disasm_buf); + realtime_disassembly = 1; + } -// Configurable emulator options -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"; + cpu_emulation_running = 0; + do_disasm = 0; +} //unsigned char g_kick[524288]; //unsigned char g_ram[FASTSIZE + 1]; /* RAM */ @@ -181,7 +208,7 @@ int main(int argc, char *argv[]) { InitGayle(); signal(SIGINT, sigint_handler); - setup_io(); + /*setup_io(); //goto skip_everything; @@ -200,25 +227,30 @@ int main(int argc, char *argv[]) { // reset amiga and statemachine skip_everything:; - cpu_pulse_reset(); - ovl = 1; - m68k_write_memory_8(0xbfe201, 0x0001); // AMIGA OVL - m68k_write_memory_8(0xbfe001, 0x0001); // AMIGA OVL high (ROM@0x0) usleep(1500); m68k_init(); printf("Setting CPU type to %d.\n", cpu_type); m68k_set_cpu_type(cpu_type); - m68k_pulse_reset(); + cpu_pulse_reset(); if (maprom == 1) { m68k_set_reg(M68K_REG_PC, 0xF80002); } else { m68k_set_reg(M68K_REG_PC, 0x0); - } + }*/ + ps_setup_protocol(); + ps_reset_state_machine(); + ps_pulse_reset(); + + usleep(1500); + m68k_init(); + printf("Setting CPU type to %d.\n", cpu_type); + m68k_set_cpu_type(cpu_type); + cpu_pulse_reset(); - char c = 0; + char c = 0, c_code = 0, c_type = 0; pthread_t id; int err; @@ -231,40 +263,71 @@ int main(int argc, char *argv[]) { m68k_pulse_reset(); while (42) { if (mouse_hook_enabled) { - if (get_mouse_status(&mouse_dx, &mouse_dy, &mouse_buttons)) { - //printf("Maus: %d (%.2X), %d (%.2X), B:%.2X\n", mouse_dx, mouse_dx, mouse_dy, mouse_dy, mouse_buttons); - } + get_mouse_status(&mouse_dx, &mouse_dy, &mouse_buttons); + } + + if (realtime_disassembly && (do_disasm || cpu_emulation_running)) { + m68k_disassemble(disasm_buf, m68k_get_reg(NULL, M68K_REG_PC), cpu_type); + printf("REGA: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1), m68k_get_reg(NULL, M68K_REG_A2), m68k_get_reg(NULL, M68K_REG_A3), \ + m68k_get_reg(NULL, M68K_REG_A4), m68k_get_reg(NULL, M68K_REG_A5), m68k_get_reg(NULL, M68K_REG_A6), m68k_get_reg(NULL, M68K_REG_A7)); + printf("REGD: 0:$%.8X 1:$%.8X 2:$%.8X 3:$%.8X 4:$%.8X 5:$%.8X 6:$%.8X 7:$%.8X\n", m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1), m68k_get_reg(NULL, M68K_REG_D2), m68k_get_reg(NULL, M68K_REG_D3), \ + m68k_get_reg(NULL, M68K_REG_D4), m68k_get_reg(NULL, M68K_REG_D5), m68k_get_reg(NULL, M68K_REG_D6), m68k_get_reg(NULL, M68K_REG_D7)); + printf("%.8X (%.8X)]] %s\n", m68k_get_reg(NULL, M68K_REG_PC), (m68k_get_reg(NULL, M68K_REG_PC) & 0xFFFFFF), disasm_buf); + if (do_disasm) + do_disasm--; + m68k_execute(1); + } + else { + if (cpu_emulation_running) + m68k_execute(loop_cycles); } - if (cpu_emulation_running) - m68k_execute(loop_cycles); - if (irq) { unsigned int status = read_reg(); m68k_set_irq((status & 0xe000) >> 13); } - else if (gayleirq) { + else if (gayleirq && int2_enabled) { write16(0xdff09c, 0x8000 | (1 << 3)); - //PAULA_SET_IRQ(3); // IRQ 3 = INT2 m68k_set_irq(2); } - else { - m68k_set_irq(0); - } + /*else { + m68k_set_irq(0); + }*/ - //usleep(0); - // FIXME: Rework this to use keyboard events instead. - /*while (get_key_char(&c)) { - if (c == cfg->keyboard_toggle_key && !kb_hook_enabled) { + while (get_key_char(&c, &c_code, &c_type)) { + if (c && c == cfg->keyboard_toggle_key && !kb_hook_enabled) { kb_hook_enabled = 1; printf("Keyboard hook enabled.\n"); } - else if (c == 0x1B && kb_hook_enabled) { - kb_hook_enabled = 0; - printf("Keyboard hook disabled.\n"); + else if (kb_hook_enabled) { + if (c == 0x1B && c_type) { + kb_hook_enabled = 0; + printf("Keyboard hook disabled.\n"); + } + else { + /*printf("Key code: %.2X - ", c_code); + switch (c_type) { + case 0: + printf("released.\n"); + break; + case 1: + printf("pressed.\n"); + break; + case 2: + printf("repeat.\n"); + break; + default: + printf("unknown.\n"); + break; + }*/ + if (queue_keypress(c_code, c_type, cfg->platform->id) && int2_enabled) { + m68k_set_irq(2); + } + } } - if (!kb_hook_enabled) { - if (c == cfg->mouse_toggle_key) { + + if (!kb_hook_enabled && c_type) { + if (c && 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; @@ -273,20 +336,41 @@ int main(int argc, char *argv[]) { cpu_emulation_running ^= 1; printf("CPU emulation is now %s\n", cpu_emulation_running ? "running" : "stopped"); } + if (c == 'g') { + realtime_graphics_debug ^= 1; + printf("Real time graphics debug is now %s\n", realtime_graphics_debug ? "on" : "off"); + } if (c == 'R') { cpu_pulse_reset(); - m68k_pulse_reset(); + //m68k_pulse_reset(); printf("CPU emulation reset.\n"); } if (c == 'q') { printf("Quitting and exiting emulator.\n"); goto stop_cpu_emulation; } + if (c == 'd') { + realtime_disassembly ^= 1; + do_disasm = 1; + printf("Real time disassembly is now %s\n", realtime_disassembly ? "on" : "off"); + } + if (c == 'D') { + int r = get_mapped_item_by_address(cfg, 0x08000000); + if (r != -1) { + printf("Dumping first 16MB of mapped range %d.\n", r); + FILE *dmp = fopen("./memdmp.bin", "wb+"); + fwrite(cfg->map_data[r], 16 * SIZE_MEGA, 1, dmp); + fclose(dmp); + } + } + if (c == 's' && realtime_disassembly) { + do_disasm = 1; + } + if (c == 'S' && realtime_disassembly) { + do_disasm = 128; + } } - }*/ - - //gpio_handle_irq(); - //GPIO_HANDLE_IRQ; + } } stop_cpu_emulation:; @@ -300,11 +384,20 @@ int main(int argc, char *argv[]) { } void cpu_pulse_reset(void) { - write_reg(0x00); + ps_pulse_reset(); + //write_reg(0x00); // printf("Status Reg%x\n",read_reg()); - usleep(100000); - write_reg(0x02); + //usleep(100000); + //write_reg(0x02); // printf("Status Reg%x\n",read_reg()); + if (cfg->platform->handle_reset) + cfg->platform->handle_reset(cfg); + + ovl = 1; + m68k_write_memory_8(0xbfe201, 0x0001); // AMIGA OVL + m68k_write_memory_8(0xbfe001, 0x0001); // AMIGA OVL high (ROM@0x0) + + m68k_pulse_reset(); } int cpu_irq_ack(int level) { @@ -313,13 +406,25 @@ int cpu_irq_ack(int level) { } static unsigned int target = 0; +static uint8_t send_keypress = 0; + +uint8_t cdtv_dmac_reg_idx_read(); +void cdtv_dmac_reg_idx_write(uint8_t value); +uint32_t cdtv_dmac_read(uint32_t address, uint8_t type); +void cdtv_dmac_write(uint32_t address, uint32_t value, uint8_t type); #define PLATFORM_CHECK_READ(a) \ if (address >= cfg->custom_low && address < cfg->custom_high) { \ unsigned int target = 0; \ switch(cfg->platform->id) { \ case PLATFORM_AMIGA: { \ - if (address >= PIGFX_RTG_BASE && address < PIGFX_RTG_BASE + PIGFX_RTG_SIZE) { \ + if (address >= PISCSI_OFFSET && address < PISCSI_UPPER) { \ + return handle_piscsi_read(address, a); \ + } \ + if (address >= PINET_OFFSET && address < PINET_UPPER) { \ + return handle_pinet_read(address, a); \ + } \ + if (address >= PIGFX_RTG_BASE && address < PIGFX_UPPER) { \ return rtg_read((address & 0x0FFFFFFF), a); \ } \ if (custom_read_amiga(cfg, address, &target, a) != -1) { \ @@ -339,49 +444,137 @@ static unsigned int target = 0; unsigned int m68k_read_memory_8(unsigned int address) { PLATFORM_CHECK_READ(OP_TYPE_BYTE); - address &=0xFFFFFF; - return read8((uint32_t)address); + /*if (address >= 0xE90000 && address < 0xF00000) { + printf("BYTE read from DMAC @%.8X:", address); + uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_BYTE); + printf("%.2X\n", v); + m68k_end_timeslice(); + cpu_emulation_running = 0; + return v; + }*/ + + /*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x080032F0 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x080032F0 + 0x4000) { + stop_cpu_emulation(1); + }*/ + + + if (address & 0xFF000000) + return 0; + + unsigned char result = (unsigned int)read8((uint32_t)address); + + if (mouse_hook_enabled) { + if (address == CIAAPRA) { + if (mouse_buttons & 0x01) { + //mouse_buttons -= 1; + return (unsigned int)(result ^ 0x40); + } + else + return (unsigned int)result; + } + } + if (kb_hook_enabled) { + if (address == CIAAICR) { + if (get_num_kb_queued() && (!send_keypress || send_keypress == 1)) { + result |= 0x08; + if (!send_keypress) + send_keypress = 1; + } + if (send_keypress == 2) { + result |= 0x02; + send_keypress = 0; + } + return result; + } + if (address == CIAADAT) { + if (send_keypress) { + uint8_t c = 0, t = 0; + pop_queued_key(&c, &t); + t ^= 0x01; + result = ((c << 1) | t) ^ 0xFF; + send_keypress = 2; + } + return result; + } + } + + return result; } unsigned int m68k_read_memory_16(unsigned int address) { PLATFORM_CHECK_READ(OP_TYPE_WORD); + /*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x080032F0 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x080032F0 + 0x4000) { + stop_cpu_emulation(1); + }*/ + + /*if (address >= 0xE90000 && address < 0xF00000) { + printf("WORD read from DMAC @%.8X:", address); + uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_WORD); + printf("%.2X\n", v); + m68k_end_timeslice(); + cpu_emulation_running = 0; + return v; + }*/ + if (mouse_hook_enabled) { if (address == JOY0DAT) { // Forward mouse valueses to Amyga. unsigned short result = (mouse_dy << 8) | (mouse_dx); - mouse_dx = mouse_dy = 0; return (unsigned int)result; } - if (address == CIAAPRA) { + /*if (address == CIAAPRA) { unsigned short result = (unsigned int)read16((uint32_t)address); if (mouse_buttons & 0x01) { - mouse_buttons -= 1; return (unsigned int)(result | 0x40); } else return (unsigned int)result; - } + }*/ if (address == POTGOR) { unsigned short result = (unsigned int)read16((uint32_t)address); if (mouse_buttons & 0x02) { - mouse_buttons -= 2; - return (unsigned int)(result | 0x2); + return (unsigned int)(result ^ (0x2 << 9)); } else - return (unsigned int)result; + return (unsigned int)(result & 0xFFFD); } } + if (address & 0xFF000000) + return 0; - address &=0xFFFFFF; + if (address & 0x01) { + return ((read8(address) << 8) | read8(address + 1)); + } return (unsigned int)read16((uint32_t)address); } unsigned int m68k_read_memory_32(unsigned int address) { PLATFORM_CHECK_READ(OP_TYPE_LONGWORD); - address &=0xFFFFFF; + /*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x080032F0 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x080032F0 + 0x4000) { + stop_cpu_emulation(1); + }*/ + + /*if (address >= 0xE90000 && address < 0xF00000) { + printf("LONGWORD read from DMAC @%.8X:", address); + uint32_t v = cdtv_dmac_read(address & 0xFFFF, OP_TYPE_LONGWORD); + printf("%.2X\n", v); + m68k_end_timeslice(); + cpu_emulation_running = 0; + return v; + }*/ + + if (address & 0xFF000000) + return 0; + + if (address & 0x01) { + uint32_t c = read8(address); + c |= (be16toh(read16(address+1)) << 8); + c |= (read8(address + 3) << 24); + return htobe32(c); + } uint16_t a = read16(address); uint16_t b = read16(address + 2); return (a << 16) | b; @@ -391,7 +584,13 @@ unsigned int m68k_read_memory_32(unsigned int address) { if (address >= cfg->custom_low && address < cfg->custom_high) { \ switch(cfg->platform->id) { \ case PLATFORM_AMIGA: { \ - if (address >= PIGFX_RTG_BASE && address < PIGFX_RTG_BASE + PIGFX_RTG_SIZE) { \ + if (address >= PISCSI_OFFSET && address < PISCSI_UPPER) { \ + handle_piscsi_write(address, value, a); \ + } \ + if (address >= PINET_OFFSET && address < PINET_UPPER) { \ + handle_pinet_write(address, value, a); \ + } \ + if (address >= PIGFX_RTG_BASE && address < PIGFX_UPPER) { \ rtg_write((address & 0x0FFFFFFF), value, a); \ return; \ } \ @@ -412,6 +611,14 @@ unsigned int m68k_read_memory_32(unsigned int address) { void m68k_write_memory_8(unsigned int address, unsigned int value) { PLATFORM_CHECK_WRITE(OP_TYPE_BYTE); + /*if (address >= 0xE90000 && address < 0xF00000) { + printf("BYTE write to DMAC @%.8X: %.2X\n", address, value); + cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_BYTE); + m68k_end_timeslice(); + cpu_emulation_running = 0; + return; + }*/ + if (address == 0xbfe001) { if (ovl != (value & (1 << 0))) { ovl = (value & (1 << 0)); @@ -419,7 +626,9 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) { } } - address &=0xFFFFFF; + if (address & 0xFF000000) + return; + write8((uint32_t)address, value); return; } @@ -427,7 +636,35 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) { void m68k_write_memory_16(unsigned int address, unsigned int value) { PLATFORM_CHECK_WRITE(OP_TYPE_WORD); - address &=0xFFFFFF; + /*if (address >= 0xE90000 && address < 0xF00000) { + printf("WORD write to DMAC @%.8X: %.4X\n", address, value); + cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_WORD); + m68k_end_timeslice(); + cpu_emulation_running = 0; + return; + }*/ + + if (address == 0xDFF030) { + char *beb = (char *)&value; + printf("%c%c", beb[1], beb[0]); + } + if (address == 0xDFF09A) { + if (!(value & 0x8000)) { + if (value & 0x04) { + int2_enabled = 0; + } + } + else if (value & 0x04) { + int2_enabled = 1; + } + } + + if (address & 0xFF000000) + return; + + if (address & 0x01) + printf("Unaligned WORD write!\n"); + write16((uint32_t)address, value); return; } @@ -435,7 +672,20 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) { void m68k_write_memory_32(unsigned int address, unsigned int value) { PLATFORM_CHECK_WRITE(OP_TYPE_LONGWORD); - address &=0xFFFFFF; + /*if (address >= 0xE90000 && address < 0xF00000) { + printf("LONGWORD write to DMAC @%.8X: %.8X\n", address, value); + cdtv_dmac_write(address & 0xFFFF, value, OP_TYPE_LONGWORD); + m68k_end_timeslice(); + cpu_emulation_running = 0; + return; + }*/ + + if (address & 0xFF000000) + return; + + if (address & 0x01) + printf("Unaligned LONGWORD write!\n"); + write16(address, value >> 16); write16(address + 2, value); return;