From 40343f9a098c40dc8d6eb63ca7dbf283d468e778 Mon Sep 17 00:00:00 2001 From: beeanyew Date: Tue, 19 Jan 2021 13:58:16 +0100 Subject: [PATCH] Creepy CDTV experiments --- Makefile | 1 + buptest.c | 109 +++++++++++++++++++++++++------- emulator.c | 64 ++++++++++++++++++- platforms/amiga/cdtv-dmac.c | 71 +++++++++++++++++++++ platforms/amiga/gayle-ide/ide.c | 8 +-- 5 files changed, 224 insertions(+), 29 deletions(-) create mode 100644 platforms/amiga/cdtv-dmac.c diff --git a/Makefile b/Makefile index 00ac323..b738fa3 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ MAINFILES = emulator.c \ platforms/dummy/dummy-registers.c \ platforms/amiga/Gayle.c \ platforms/amiga/gayle-ide/ide.c \ + platforms/amiga/cdtv-dmac.c \ platforms/amiga/rtg/rtg.c \ platforms/amiga/rtg/rtg-output.c \ platforms/amiga/rtg/rtg-gfx.c \ diff --git a/buptest.c b/buptest.c index 3bbe521..bbba2ed 100644 --- a/buptest.c +++ b/buptest.c @@ -68,9 +68,11 @@ int main() { printf("Writing garbege datas.\n"); for (uint32_t i = 0; i < 512 * 1024; i++) { - garbege_datas[i] = (uint8_t)(rand() % 0xFF); + while(garbege_datas[i] == 0x00) + garbege_datas[i] = (uint8_t)(rand() % 0xFF); write8(i, (uint32_t)garbege_datas[i]); } + printf("Reading back garbege datas, read8()...\n"); for (uint32_t i = 0; i < 512 * 1024; i++) { uint32_t c = read8(i); @@ -83,6 +85,7 @@ int main() { printf("read8 errors total: %d.\n", errors); errors = 0; sleep (1); + printf("Reading back garbege datas, read16(), even addresses...\n"); for (uint32_t i = 0; i < (512 * 1024) - 2; i += 2) { uint32_t c = be16toh(read16(i)); @@ -95,20 +98,20 @@ int main() { printf("read16 even errors total: %d.\n", errors); errors = 0; sleep (1); - for (int x = 0; x < 20; x++) { - printf("Reading back garbege datas, read16(), odd addresses...\n"); - for (uint32_t i = 1; i < (512 * 1024) - 2; i += 2) { - uint32_t c = be16toh((read8(i) << 8) | read8(i + 1)); - if (c != *((uint16_t *)&garbege_datas[i])) { - if (errors < 512) - printf("READ16_ODD: Garbege data mismatch at $%.6X: %.4X should be %.4X.\n", i, c, *((uint16_t *)&garbege_datas[i])); - errors++; - } + + printf("Reading back garbege datas, read16(), odd addresses...\n"); + for (uint32_t i = 1; i < (512 * 1024) - 2; i += 2) { + uint32_t c = be16toh((read8(i) << 8) | read8(i + 1)); + if (c != *((uint16_t *)&garbege_datas[i])) { + if (errors < 512) + printf("READ16_ODD: Garbege data mismatch at $%.6X: %.4X should be %.4X.\n", i, c, *((uint16_t *)&garbege_datas[i])); + errors++; } - printf("read16 odd loop %d errors total: %d.\n", x+1, errors); - errors = 0; } + printf("read16 odd errors total: %d.\n", errors); + errors = 0; sleep (1); + printf("Reading back garbege datas, read32(), even addresses...\n"); for (uint32_t i = 0; i < (512 * 1024) - 4; i += 2) { uint32_t c = be32toh(read32(i)); @@ -121,21 +124,79 @@ int main() { printf("read32 even errors total: %d.\n", errors); errors = 0; sleep (1); - for (int x = 0; x < 20; x++) { - printf("Reading back garbege datas, read32(), odd addresses...\n"); - for (uint32_t i = 1; i < (512 * 1024) - 4; i += 2) { - uint32_t c = be32toh(read32(i)); - c = (c >> 8) | (read8(i + 3) << 24); - if (c != *((uint32_t *)&garbege_datas[i])) { - if (errors < 512) - printf("READ32_ODD: Garbege data mismatch at $%.6X: %.8X should be %.8X.\n", i, c, *((uint32_t *)&garbege_datas[i])); - errors++; - } + + printf("Reading back garbege datas, read32(), odd addresses...\n"); + for (uint32_t i = 1; i < (512 * 1024) - 4; i += 2) { + uint32_t c = read8(i); + c |= (be16toh(read16(i + 1)) << 8); + c |= (read8(i + 3) << 24); + //c = be32toh(c); + if (c != *((uint32_t *)&garbege_datas[i])) { + if (errors < 512) + printf("READ32_ODD: Garbege data mismatch at $%.6X: %.8X should be %.8X.\n", i, c, *((uint32_t *)&garbege_datas[i])); + errors++; + } + } + printf("read32 odd errors total: %d.\n", errors); + errors = 0; + sleep (1); + + printf("Clearing 512KB of Chip again\n"); + for (uint32_t i = 0; i < 512 * 1024; i++) { + write8(i, (uint32_t)0x0); + } + + printf("[WORD] Writing garbege datas to Chip, unaligned...\n"); + for (uint32_t i = 1; i < (512 * 1024) - 2; i += 2) { + uint16_t v = *((uint16_t *)&garbege_datas[i]); + write8(i, (v & 0x00FF)); + write8(i + 1, (v >> 8)); + //write16(i, *((uint16_t *)&garbege_datas[i])); + } + + sleep (1); + printf("Reading back garbege datas, read16(), odd addresses...\n"); + for (uint32_t i = 1; i < (512 * 1024) - 2; i += 2) { + //uint32_t c = be16toh(read16(i)); + uint32_t c = be16toh((read8(i) << 8) | read8(i + 1)); + if (c != *((uint16_t *)&garbege_datas[i])) { + if (errors < 512) + printf("READ16_EVEN: Garbege data mismatch at $%.6X: %.4X should be %.4X.\n", i, c, *((uint16_t *)&garbege_datas[i])); + errors++; } - printf("read32 odd loop %d errors total: %d.\n", x+1, errors); - errors = 0; } + printf("read16 even errors total: %d.\n", errors); + errors = 0; + + printf("Clearing 512KB of Chip again\n"); + for (uint32_t i = 0; i < 512 * 1024; i++) { + write8(i, (uint32_t)0x0); + } + + printf("[LONG] Writing garbege datas to Chip, unaligned...\n"); + for (uint32_t i = 1; i < (512 * 1024) - 4; i += 4) { + uint32_t v = *((uint32_t *)&garbege_datas[i]); + write8(i , v & 0x0000FF); + write16(i + 1, htobe16(((v & 0x00FFFF00) >> 8))); + write8(i + 3 , (v & 0xFF000000) >> 24); + //write32(i, v); + } + sleep (1); + printf("Reading back garbege datas, read32(), even addresses...\n"); + for (uint32_t i = 1; i < (512 * 1024) - 4; i += 4) { + uint32_t c = read8(i); + c |= (be16toh(read16(i + 1)) << 8); + c |= (read8(i + 3) << 24); + //uint32_t c = be32toh(read32(i)); + if (c != *((uint32_t *)&garbege_datas[i])) { + if (errors < 512) + printf("READ32_EVEN: Garbege data mismatch at $%.6X: %.8X should be %.8X.\n", i, c, *((uint32_t *)&garbege_datas[i])); + errors++; + } + } + printf("read32 even errors total: %d.\n", errors); + errors = 0; return 0; } diff --git a/emulator.c b/emulator.c index 2718f1d..75338a4 100644 --- a/emulator.c +++ b/emulator.c @@ -359,6 +359,11 @@ 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; \ @@ -384,6 +389,15 @@ static uint8_t send_keypress = 0; unsigned int m68k_read_memory_8(unsigned int address) { PLATFORM_CHECK_READ(OP_TYPE_BYTE); + 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 (mouse_hook_enabled) { if (address == CIAAPRA) { unsigned char result = (unsigned int)read8((uint32_t)address); @@ -430,6 +444,15 @@ unsigned int m68k_read_memory_8(unsigned int address) { unsigned int m68k_read_memory_16(unsigned int address) { PLATFORM_CHECK_READ(OP_TYPE_WORD); + 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. @@ -466,6 +489,15 @@ unsigned int m68k_read_memory_16(unsigned int address) { unsigned int m68k_read_memory_32(unsigned int address) { PLATFORM_CHECK_READ(OP_TYPE_LONGWORD); + 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; @@ -505,6 +537,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)); @@ -522,9 +562,20 @@ 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); + 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 & 0xFF000000) return; + if (address & 0x01) + printf("Unaligned WORD write!\n"); + write16((uint32_t)address, value); return; } @@ -532,9 +583,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); + 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; diff --git a/platforms/amiga/cdtv-dmac.c b/platforms/amiga/cdtv-dmac.c new file mode 100644 index 0000000..cfe25cd --- /dev/null +++ b/platforms/amiga/cdtv-dmac.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include "../../config_file/config_file.h" + +uint8_t dmac_reg_idx = 0; +uint8_t dmac_reg_values[0xFFFF]; + +uint8_t cdtv_dmac_reg_idx_read() { + return dmac_reg_idx; +} + +/* DMAC Registers +R 0x06 [B] - Something + + 0x40 [W] - ISTR +RW 0x42 [W] - CNTR + + 0x80 [L] - WTC + 0x84 [L] - ACR + + 0x8E [B] - SASR +W 0x8F [B] - Something + 0x90 - SCMD + 0x91 [B] - Something + 0x92 [B] - Something? +RW 0x93 [B] - Something + +R 0xA2?[W?] - Some status thing? +W 0xA4?[W?] - Something +W 0xA6?[W?] - Something +W 0xA8?[W?] - Something + + 0xDE [W] - ST_DMA + 0xE0 [W] - SP_DMA + 0xE2 [W] - CINT + 0xE4 [W] - Something + 0xE4-0xE5 - Nothing + 0xE6 [W] - Flush +*/ + +void cdtv_dmac_reg_idx_write(uint8_t value) { + dmac_reg_idx = value; +} + +uint32_t cdtv_dmac_read(uint32_t address, uint8_t type) { + uint32_t ret = 0; + + switch (type) { + case OP_TYPE_BYTE: + return dmac_reg_values[address]; + case OP_TYPE_WORD: + return be16toh(*((uint16_t *)&dmac_reg_values[address])); + default: + break; + } + + return ret; +} + +void cdtv_dmac_write(uint32_t address, uint32_t value, uint8_t type) { + switch (type) { + case OP_TYPE_BYTE: + dmac_reg_values[address] = (uint8_t)value; + return ; + case OP_TYPE_WORD: + printf("Help, it's a scary word write.\n"); + *((uint16_t *)&dmac_reg_values[address]) = htobe16(value); + return; + } +} diff --git a/platforms/amiga/gayle-ide/ide.c b/platforms/amiga/gayle-ide/ide.c index 765bb13..64ddf44 100644 --- a/platforms/amiga/gayle-ide/ide.c +++ b/platforms/amiga/gayle-ide/ide.c @@ -793,16 +793,16 @@ int ide_attach_hdf(struct ide_controller *c, int drive, int fd) uint64_t file_size = lseek(fd, 0, SEEK_END); lseek(fd, 1024, SEEK_SET); - if (file_size < 500 * SIZE_MEGA) { + if (file_size < 504 * SIZE_MEGA) { d->heads = 16; } - else if (file_size < 1000 * SIZE_MEGA) { + else if (file_size < 1008 * SIZE_MEGA) { d->heads = 32; } - else if (file_size < 2000 * SIZE_MEGA) { + else if (file_size < 2016 * SIZE_MEGA) { d->heads = 64; } - else if (file_size < (uint64_t)4000 * SIZE_MEGA) { + else if (file_size < (uint64_t)4032 * SIZE_MEGA) { d->heads = 128; } -- 2.39.2