From 563a41af36ed16a7a61de9e35ac82ff405bc318b Mon Sep 17 00:00:00 2001
From: notaz <notasas@gmail.com>
Date: Thu, 5 Nov 2020 12:46:45 +0200
Subject: [PATCH] adapter mappers

---
 flashkit.c | 150 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 122 insertions(+), 28 deletions(-)

diff --git a/flashkit.c b/flashkit.c
index 75f348e..023d2d2 100644
--- a/flashkit.c
+++ b/flashkit.c
@@ -135,16 +135,6 @@ static void set_addr16(int fd, uint32_t addr)
 	set_addr8(fd, addr >> 1);
 }
 
-static uint32_t lorom_addr(uint32_t a)
-{
-	return ((a & 0x7f8000) << 1) | 0x8000 | (a & 0x7fff);
-}
-
-static void set_addr8l(int fd, uint32_t addr)
-{
-	set_addr8(fd, lorom_addr(addr));
-}
-
 static uint16_t read_bus8(int fd, uint32_t addr)
 {
 	uint8_t cmd[7] = {
@@ -175,11 +165,6 @@ static uint16_t read_bus16(int fd, uint32_t addr)
 	return ntohs(r);
 }
 
-static uint16_t read_bus8l(int fd, uint32_t addr)
-{
-	return read_bus8(fd, lorom_addr(addr));
-}
-
 static void write_bus8(int fd, uint32_t addr, uint16_t d)
 {
 	uint8_t cmd[8] = {
@@ -206,11 +191,6 @@ static void write_bus16(int fd, uint32_t addr, uint16_t d)
 	write_serial(fd, cmd, sizeof(cmd));
 }
 
-static void write_bus8l(int fd, uint32_t addr, uint16_t d)
-{
-	write_bus8(fd, lorom_addr(addr), d);
-}
-
 static void read_block8(int fd, void *dst, uint32_t size)
 {
 	// PAR_MODE8 does not work, so read as 16bit and throw away MSB
@@ -303,9 +283,31 @@ static void flash_seq_write16(int fd, uint32_t addr, const uint8_t *d)
 	write_serial(fd, cmd, sizeof(cmd));
 }
 
-static void flash_seq_write8l(int fd, uint32_t addr, const uint8_t *d)
+// -- 8bit+LoROM --
+
+static uint32_t lorom_rom_addr(uint32_t a)
 {
-	addr = lorom_addr(addr);
+	return ((a & 0x7f8000) << 1) | 0x8000 | (a & 0x7fff);
+}
+
+static void set_addr8l(int fd, uint32_t a)
+{
+	set_addr8(fd, lorom_rom_addr(a));
+}
+
+static uint16_t read_bus8l(int fd, uint32_t a)
+{
+	return read_bus8(fd, lorom_rom_addr(a));
+}
+
+static void write_bus8l(int fd, uint32_t a, uint16_t d)
+{
+	write_bus8(fd, lorom_rom_addr(a), d);
+}
+
+static void flash_seq_write8l(int fd, uint32_t a, const uint8_t *d)
+{
+	a = lorom_rom_addr(a);
 	uint8_t cmd[] = {
 		// unlock
 		CMD_ADDR, 0,
@@ -322,9 +324,9 @@ static void flash_seq_write8l(int fd, uint32_t addr, const uint8_t *d)
 		CMD_ADDR, 0xaa,
 		CMD_WR | PAR_SINGE | PAR_MODE8, 0xa0,
 		// program data
-		CMD_ADDR, addr >> 16,
-		CMD_ADDR, addr >> 8,
-		CMD_ADDR, addr >> 0,
+		CMD_ADDR, a >> 16,
+		CMD_ADDR, a >> 8,
+		CMD_ADDR, a >> 0,
 		CMD_WR | PAR_SINGE | PAR_MODE8, *d,
 		CMD_RY
 	};
@@ -332,10 +334,100 @@ static void flash_seq_write8l(int fd, uint32_t addr, const uint8_t *d)
 	write_serial(fd, cmd, sizeof(cmd));
 }
 
+// -- 8bit+LoROM+adapter --
+
+static uint32_t do_flipflops(int fd, uint32_t a)
+{
+	static uint32_t abits_now = ~0u; // A23, A22, A21
+	uint32_t abits = (a >> 21) & 7;
+
+	if (abits != abits_now) {
+		// printf("flipflops: %x->%x\n", abits_now, abits);
+		write_bus16(fd, 0xa13000, abits);
+		abits_now = abits;
+	}
+	return a & 0x1fffff;
+}
+
+static void set_addr8la(int fd, uint32_t a)
+{
+	set_addr8(fd, do_flipflops(fd, lorom_rom_addr(a)));
+}
+
+static uint16_t read_bus8la(int fd, uint32_t a)
+{
+	return read_bus8(fd, do_flipflops(fd, lorom_rom_addr(a)));
+}
+
+static void write_bus8la(int fd, uint32_t a, uint16_t d)
+{
+	write_bus8(fd, do_flipflops(fd, lorom_rom_addr(a)), d);
+}
+
+static void flash_seq_write8la(int fd, uint32_t a, const uint8_t *d)
+{
+	// we should clear flipflops for the flash commands, but this
+	// doesn't seem to be necessary as the flash chip seems to
+	// ignore the upper bits when looking for commands, and this
+	// extra clearing would slow things down
+	a = do_flipflops(fd, lorom_rom_addr(a));
+	uint8_t cmd[] = {
+		// unlock
+		CMD_ADDR, 0,
+		CMD_ADDR, 0x8a,
+		CMD_ADDR, 0xaa,
+		CMD_WR | PAR_SINGE | PAR_MODE8, 0xaa,
+		CMD_ADDR, 0,
+		CMD_ADDR, 0x85,
+		CMD_ADDR, 0x55,
+		CMD_WR | PAR_SINGE | PAR_MODE8, 0x55,
+		// program setup
+		CMD_ADDR, 0,
+		CMD_ADDR, 0x8a,
+		CMD_ADDR, 0xaa,
+		CMD_WR | PAR_SINGE | PAR_MODE8, 0xa0,
+		// program data
+		CMD_ADDR, a >> 16,
+		CMD_ADDR, a >> 8,
+		CMD_ADDR, a >> 0,
+		CMD_WR | PAR_SINGE | PAR_MODE8, *d,
+		CMD_RY
+	};
+
+	write_serial(fd, cmd, sizeof(cmd));
+}
+
+// -- 8bit+LoROM+adapter+sram --
+
+static uint32_t lorom_sram_addr(uint32_t a)
+{
+	return a | 0x600000;
+}
+
+static void set_addr8las(int fd, uint32_t a)
+{
+	set_addr8(fd, do_flipflops(fd, lorom_sram_addr(a)));
+}
+
+static uint16_t read_bus8las(int fd, uint32_t a)
+{
+	return read_bus8(fd, do_flipflops(fd, lorom_sram_addr(a)));
+}
+
+static void write_bus8las(int fd, uint32_t a, uint16_t d)
+{
+	write_bus8(fd, do_flipflops(fd, lorom_sram_addr(a)), d);
+}
+
+static void flash_seq_write8las(int fd, uint32_t a, const uint8_t *d)
+{
+}
+
 #define N0 ""
 #define N1 "8bit"
 #define N2 "8bit+LoROM"
 #define N3 "8bit+LoROM+adapter"
+#define N4 "8bit+LoROM+adapter+sram"
 static const struct iof
 {
 	const char *name;
@@ -348,9 +440,11 @@ static const struct iof
 }
 io_ops[] =
 {
-	{ N0, 0, set_addr16, read_bus16, write_bus16, read_block16, flash_seq_write16 },
-	{ N1, 0, set_addr8,  read_bus8,  write_bus8,  read_block8,  flash_seq_write8  },
-	{ N2, 1, set_addr8l, read_bus8l, write_bus8l, read_block8,  flash_seq_write8l },
+	{ N0, 0, set_addr16,   read_bus16,   write_bus16,   read_block16, flash_seq_write16   },
+	{ N1, 0, set_addr8,    read_bus8,    write_bus8,    read_block8,  flash_seq_write8    },
+	{ N2, 1, set_addr8l,   read_bus8l,   write_bus8l,   read_block8,  flash_seq_write8l   },
+	{ N3, 1, set_addr8la,  read_bus8la,  write_bus8la,  read_block8,  flash_seq_write8la  },
+	{ N4, 0, set_addr8las, read_bus8las, write_bus8las, read_block8,  flash_seq_write8las },
 };
 
 static const struct iof *io = &io_ops[0];
-- 
2.39.5