From 66db2e6049ddf6498c15344e4cd565cc97644cf0 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Sun, 20 Nov 2022 21:46:40 -0400 Subject: [PATCH] Revert "chore: refactor flash impl" This reverts commit 96a9ae2ca5b0137f50a2f1130326ad1657c719b9. --- src/core/bus/backup.zig | 57 +++++++++++++++++++++---- src/core/bus/backup/Flash.zig | 79 +++++++++-------------------------- 2 files changed, 69 insertions(+), 67 deletions(-) diff --git a/src/core/bus/backup.zig b/src/core/bus/backup.zig index 5bb6547..fb96f73 100644 --- a/src/core/bus/backup.zig +++ b/src/core/bus/backup.zig @@ -40,18 +40,61 @@ pub const Backup = struct { None, }; - pub fn read(self: *const Self, address: u32) u8 { + pub fn read(self: *const Self, address: usize) u8 { + const addr = address & 0xFFFF; + switch (self.kind) { - .Flash, .Flash1M => return self.flash.read(self.buf, address), - .Sram => return self.buf[address & 0x7FFF], // 32K SRAM chip is mirrored + .Flash => { + switch (addr) { + 0x0000 => if (self.flash.id_mode) return 0x32, // Panasonic manufacturer ID + 0x0001 => if (self.flash.id_mode) return 0x1B, // Panasonic device ID + else => {}, + } + + return self.flash.read(self.buf, addr); + }, + .Flash1M => { + switch (addr) { + 0x0000 => if (self.flash.id_mode) return 0x62, // Sanyo manufacturer ID + 0x0001 => if (self.flash.id_mode) return 0x13, // Sanyo device ID + else => {}, + } + + return self.flash.read(self.buf, addr); + }, + .Sram => return self.buf[addr & 0x7FFF], // 32K SRAM chip is mirrored .None, .Eeprom => return 0xFF, } } - pub fn write(self: *Self, address: u32, value: u8) void { + pub fn write(self: *Self, address: usize, byte: u8) void { + const addr = address & 0xFFFF; + switch (self.kind) { - .Flash, .Flash1M => self.flash.write(self.buf, address, value), - .Sram => self.buf[address & 0x7FFF] = value, + .Flash, .Flash1M => { + if (self.flash.prep_write) return self.flash.write(self.buf, addr, byte); + if (self.flash.shouldEraseSector(addr, byte)) return self.flash.erase(self.buf, addr); + + switch (addr) { + 0x0000 => if (self.kind == .Flash1M and self.flash.set_bank) { + self.flash.bank = @truncate(u1, byte); + }, + 0x5555 => { + if (self.flash.state == .Command) { + self.flash.handleCommand(self.buf, byte); + } else if (byte == 0xAA and self.flash.state == .Ready) { + self.flash.state = .Set; + } else if (byte == 0xF0) { + self.flash.state = .Ready; + } + }, + 0x2AAA => if (byte == 0x55 and self.flash.state == .Set) { + self.flash.state = .Command; + }, + else => {}, + } + }, + .Sram => self.buf[addr & 0x7FFF] = byte, .None, .Eeprom => {}, } } @@ -75,7 +118,7 @@ pub const Backup = struct { .kind = kind, .title = title, .save_path = path, - .flash = try Flash.create(if (kind == .Flash1M) .Flash1M else .Flash), + .flash = Flash.create(), .eeprom = Eeprom.create(allocator), }; diff --git a/src/core/bus/backup/Flash.zig b/src/core/bus/backup/Flash.zig index b9af071..b665b82 100644 --- a/src/core/bus/backup/Flash.zig +++ b/src/core/bus/backup/Flash.zig @@ -3,83 +3,42 @@ const std = @import("std"); const Self = @This(); state: State, -kind: Kind, -bank: u1, id_mode: bool, set_bank: bool, prep_erase: bool, prep_write: bool, -const Kind = enum { Flash, Flash1M }; -const State = enum { Ready, Set, Command }; +bank: u1, -pub fn read(self: *const Self, buf: []u8, address: u32) u8 { - const addr = address & 0xFFFF; +const State = enum { + Ready, + Set, + Command, +}; - if (self.kind == .Flash1M) { - switch (addr) { - 0x0000 => if (self.id_mode) return 0x32, // Panasonic manufacturer ID - 0x0001 => if (self.id_mode) return 0x1B, // Panasonic device ID - else => {}, - } - } else { - switch (addr) { - 0x0000 => if (self.id_mode) return 0x62, // Sanyo manufacturer ID - 0x0001 => if (self.id_mode) return 0x13, // Sanyo device ID - else => {}, - } - } - - return buf[self.baseAddress() + addr]; +pub fn read(self: *const Self, buf: []u8, idx: usize) u8 { + return buf[self.address() + idx]; } -pub fn write(self: *Self, buf: []u8, address: u32, value: u8) void { - const addr = address & 0xFFFF; - - if (self.prep_write) return self._write(buf, addr, value); - if (self.shouldEraseSector(addr, value)) return self.erase(buf, addr); - - switch (addr) { - 0x0000 => if (self.kind == .Flash1M and self.set_bank) { - self.bank = @truncate(u1, value); - }, - 0x5555 => { - if (self.state == .Command) { - self.handleCommand(buf, value); - } else if (value == 0xAA and self.state == .Ready) { - self.state = .Set; - } else if (value == 0xF0) { - self.state = .Ready; - } - }, - 0x2AAA => if (value == 0x55 and self.state == .Set) { - self.state = .Command; - }, - else => {}, - } -} - -fn _write(self: *Self, buf: []u8, idx: usize, byte: u8) void { - buf[self.baseAddress() + idx] = byte; +pub fn write(self: *Self, buf: []u8, idx: usize, byte: u8) void { + buf[self.address() + idx] = byte; self.prep_write = false; } -pub fn create(kind: Kind) !Self { +pub fn create() Self { return .{ .state = .Ready, - .kind = kind, - .bank = 0, - .id_mode = false, .set_bank = false, .prep_erase = false, .prep_write = false, + .bank = 0, }; } -fn handleCommand(self: *Self, buf: []u8, value: u8) void { - switch (value) { +pub fn handleCommand(self: *Self, buf: []u8, byte: u8) void { + switch (byte) { 0x90 => self.id_mode = true, 0xF0 => self.id_mode = false, 0xB0 => self.set_bank = true, @@ -89,18 +48,18 @@ fn handleCommand(self: *Self, buf: []u8, value: u8) void { self.prep_erase = false; }, 0xA0 => self.prep_write = true, - else => std.debug.panic("Unhandled Flash Command: 0x{X:0>2}", .{value}), + else => std.debug.panic("Unhandled Flash Command: 0x{X:0>2}", .{byte}), } self.state = .Ready; } -fn shouldEraseSector(self: *const Self, addr: usize, byte: u8) bool { +pub fn shouldEraseSector(self: *const Self, addr: usize, byte: u8) bool { return self.state == .Command and self.prep_erase and byte == 0x30 and addr & 0xFFF == 0x000; } -fn erase(self: *Self, buf: []u8, sector: usize) void { - const start = self.baseAddress() + (sector & 0xF000); +pub fn erase(self: *Self, buf: []u8, sector: usize) void { + const start = self.address() + (sector & 0xF000); std.mem.set(u8, buf[start..][0..0x1000], 0xFF); self.prep_erase = false; @@ -108,6 +67,6 @@ fn erase(self: *Self, buf: []u8, sector: usize) void { } /// Base Address -inline fn baseAddress(self: *const Self) usize { +inline fn address(self: *const Self) usize { return if (self.bank == 1) 0x10000 else @as(usize, 0); }