+ uint8_t cmd[] = {
+ // unlock
+ CMD_ADDR, info.prog_addr >> 16,
+ CMD_ADDR, info.prog_addr >> 8,
+ CMD_ADDR, info.prog_addr >> 0,
+ CMD_WR | PAR_SINGE | PAR_MODE8, 0xaa,
+ CMD_ADDR, info.prog_addr >> 17,
+ CMD_ADDR, info.prog_addr >> 9,
+ CMD_ADDR, info.prog_addr >> 1,
+ CMD_WR | PAR_SINGE | PAR_MODE8, 0x55,
+ // program setup
+ CMD_ADDR, info.prog_addr >> 16,
+ CMD_ADDR, info.prog_addr >> 8,
+ CMD_ADDR, info.prog_addr >> 0,
+ CMD_WR | PAR_SINGE | PAR_MODE8, 0xa0,
+ // program data
+ CMD_ADDR, addr >> 16,
+ CMD_ADDR, addr >> 8,
+ CMD_ADDR, addr >> 0,
+ CMD_WR | PAR_SINGE | PAR_MODE8, *d,
+ CMD_RY
+ };
+
+ assert(info.prog_addr);
+ write_serial(fd, cmd, sizeof(cmd));
+}
+
+static void flash_seq_write16(int fd, uint32_t addr, const uint8_t *d)
+{
+ uint8_t cmd[] = {
+ // unlock
+ CMD_ADDR, info.prog_addr >> 17,
+ CMD_ADDR, info.prog_addr >> 9,
+ CMD_ADDR, info.prog_addr >> 1,
+ CMD_WR | PAR_SINGE | PAR_MODE8, 0xaa,
+ CMD_ADDR, info.prog_addr >> 18,
+ CMD_ADDR, info.prog_addr >> 10,
+ CMD_ADDR, info.prog_addr >> 2,
+ CMD_WR | PAR_SINGE | PAR_MODE8, 0x55,
+ // program setup
+ CMD_ADDR, info.prog_addr >> 17,
+ CMD_ADDR, info.prog_addr >> 9,
+ CMD_ADDR, info.prog_addr >> 1,
+ CMD_WR | PAR_SINGE | PAR_MODE8, 0xa0,
+ // program data
+ CMD_ADDR, addr >> 17,
+ CMD_ADDR, addr >> 9,
+ CMD_ADDR, addr >> 1,
+ CMD_WR | PAR_SINGE, d[0], d[1],
+ CMD_RY
+ };
+
+ assert(info.prog_addr);
+ write_serial(fd, cmd, sizeof(cmd));
+}
+
+// -- 8bit+LoROM --
+
+static uint32_t lorom_rom_addr(uint32_t a)
+{
+ 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);