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] = {
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] = {
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
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,
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
};
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;
}
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];