Skip to content

Commit 2262289

Browse files
committed
Don't shoehorn Flash into MemorySpace interface
1 parent a482af9 commit 2262289

File tree

6 files changed

+13
-72
lines changed

6 files changed

+13
-72
lines changed

sim/aviron/src/lib/Cpu.zig

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ eeprom: EEPROM,
6565
io: IO,
6666
data: memory.MemorySpace,
6767
io_space: memory.MemorySpace,
68-
prog: memory.MemorySpace,
6968

7069
// State
7170
pc: u24 = 0,
@@ -283,14 +282,8 @@ fn shift_program_counter(cpu: *Cpu, by: i12) void {
283282
}
284283

285284
fn fetch_code(cpu: *Cpu) u16 {
286-
// Program space is byte-addressed; PC is word-addressed.
287-
const base: usize = @intCast(@as(u32, cpu.pc) << 1);
288-
const lo = cpu.prog.read8(base) catch @panic("fetch_code: unmapped program byte (lo)");
289-
const hi = cpu.prog.read8(base + 1) catch @panic("fetch_code: unmapped program byte (hi)");
290-
const value: u16 = switch (comptime builtin.cpu.arch.endian()) {
291-
.little => (@as(u16, hi) << 8) | lo,
292-
.big => (@as(u16, lo) << 8) | hi,
293-
};
285+
// Program memory is word-addressed; PC is in words.
286+
const value: u16 = cpu.flash.read(@intCast(cpu.pc));
294287
cpu.pc +%= 1; // increment with wraparound
295288
cpu.pc &= @intFromEnum(cpu.code_model); // then wrap to lower bit size
296289
return value;

sim/aviron/src/lib/io.zig

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,35 +62,33 @@ pub const Flash = struct {
6262
const Self = @This();
6363

6464
allocator: std.mem.Allocator,
65-
data_words: []u16,
6665
data: []align(2) u8,
6766

6867
pub fn init(allocator: std.mem.Allocator, size_bytes: usize) !Self {
6968
if ((size_bytes & 1) != 0) return error.InvalidFlashSize;
70-
const words = try allocator.alloc(u16, @divExact(size_bytes, 2));
71-
@memset(words, 0);
72-
const bytes: []align(2) u8 = std.mem.sliceAsBytes(words);
73-
return .{ .allocator = allocator, .data_words = words, .data = bytes };
69+
const bytes = try allocator.alignedAlloc(u8, std.mem.Alignment.fromByteUnits(2), size_bytes);
70+
@memset(bytes, 0);
71+
return .{ .allocator = allocator, .data = bytes };
7472
}
7573

7674
pub fn deinit(self: *Self) void {
77-
self.allocator.free(self.data_words);
75+
self.allocator.free(self.data);
7876
}
7977

8078
pub fn memory(self: *Self) Flash {
8179
return Flash{
8280
.ctx = self,
8381
.vtable = &vtable,
84-
.size = self.data_words.len,
82+
.size = @intCast(@divExact(self.data.len, 2)),
8583
};
8684
}
8785

8886
pub const vtable = VTable{ .readFn = mem_read };
8987

9088
fn mem_read(ctx: ?*anyopaque, addr: Address) u16 {
9189
const mem: *Self = @ptrCast(@alignCast(ctx.?));
92-
std.debug.assert(addr < @as(Address, @intCast(mem.data_words.len)));
93-
return mem.data_words[addr];
90+
std.debug.assert(addr < @as(Address, @intCast(@divExact(mem.data.len, 2))));
91+
return std.mem.bytesAsSlice(u16, &mem.data)[addr];
9492
}
9593
};
9694
}

sim/aviron/src/lib/mcu.zig

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,17 @@ pub const Config = struct {
4040
pub const Spaces = struct {
4141
data: memory.MemorySpace,
4242
io: memory.MemorySpace,
43-
prog: memory.MemorySpace,
4443

4544
pub fn deinit(self: *const Spaces, alloc: std.mem.Allocator) void {
4645
self.data.deinit(alloc);
4746
self.io.deinit(alloc);
48-
self.prog.deinit(alloc);
4947
}
5048
};
5149

5250
/// Build memory spaces (data, io, program) for the given MCU configuration.
5351
pub fn build_spaces(
5452
alloc: std.mem.Allocator,
5553
cfg: Config,
56-
flash: *const io_mod.Flash,
5754
ram: *io_mod.RAM,
5855
io_mem: *io_mod.IO,
5956
) !Spaces {
@@ -71,13 +68,7 @@ pub fn build_spaces(
7168
io_seg_buf[0] = .{ .at = 0, .size = io_size, .backend = memory.Backend.fromIO(io_mem) };
7269
const io_space = try memory.MemorySpace.init(alloc, io_seg_buf[0..]);
7370

74-
// Program space: byte-addressable view over Flash
75-
var prog_seg_buf: [1]memory.Segment = undefined;
76-
const prog_size: usize = flash.size * 2; // words → bytes
77-
prog_seg_buf[0] = .{ .at = 0, .size = prog_size, .backend = memory.Backend.fromFlash(flash) };
78-
const prog_space = try memory.MemorySpace.init(alloc, prog_seg_buf[0..]);
79-
80-
return .{ .data = data_space, .io = io_space, .prog = prog_space };
71+
return .{ .data = data_space, .io = io_space };
8172
}
8273

8374
pub const SpecialIoConfig = struct {

sim/aviron/src/lib/memory.zig

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
const std = @import("std");
22
const io = @import("io.zig");
33

4-
/// Unified byte-addressable backend interface for RAM, Flash, and IO.
4+
/// Unified byte-addressable backend interface for RAM and IO.
55
/// - RAM: read/write bytes by index
6-
/// - Flash: read-only; byte reads derived from word-addressed storage
76
/// - IO: read/write bytes with side effects; never exposes slices
87
pub const Backend = struct {
98
ctx: *anyopaque,
@@ -55,11 +54,6 @@ pub const Backend = struct {
5554
return .{ .ctx = ram, .vtable = &ram_vtable };
5655
}
5756

58-
/// Adapter for Flash backends (read-only, word-addressed internally)
59-
pub fn fromFlash(flash: *const io.Flash) Backend {
60-
return .{ .ctx = @constCast(flash), .vtable = &flash_vtable };
61-
}
62-
6357
/// Adapter for IO backends (read-write with side effects). Index is treated as IO address.
6458
pub fn fromIO(io_mem: *io.IO) Backend {
6559
return .{ .ctx = io_mem, .vtable = &io_vtable };
@@ -93,39 +87,6 @@ const ram_vtable = Backend.VTable{
9387
.slice_rw = &ram_slice_rw,
9488
};
9589

96-
fn flash_read8(ctx: *anyopaque, idx: usize) Backend.ReadError!u8 {
97-
const f: *const io.Flash = @ptrCast(@alignCast(ctx));
98-
const word_index: io.Flash.Address = @intCast(idx >> 1);
99-
const word: u16 = f.read(word_index);
100-
return if ((idx & 1) == 0)
101-
@as(u8, @intCast(word & 0x00FF))
102-
else
103-
@as(u8, @intCast((word >> 8) & 0x00FF));
104-
}
105-
106-
fn flash_write8(_: *anyopaque, _: usize, _: u8) Backend.WriteError!void {
107-
return error.ReadOnly;
108-
}
109-
110-
fn flash_write_masked(_: *anyopaque, _: usize, _: u8, _: u8) Backend.WriteError!void {
111-
return error.ReadOnly;
112-
}
113-
114-
fn flash_slice_ro(_: *anyopaque) ?[]const u8 {
115-
return null;
116-
}
117-
fn flash_slice_rw(_: *anyopaque) ?[]u8 {
118-
return null;
119-
}
120-
121-
const flash_vtable = Backend.VTable{
122-
.read8 = &flash_read8,
123-
.write8 = &flash_write8,
124-
.write_masked = &flash_write_masked,
125-
.slice_ro = &flash_slice_ro,
126-
.slice_rw = &flash_slice_rw,
127-
};
128-
12990
fn io_read8(ctx: *anyopaque, idx: usize) Backend.ReadError!u8 {
13091
const m: *io.IO = @ptrCast(@alignCast(ctx));
13192
return m.read(@intCast(idx));

sim/aviron/src/main.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn main() !u8 {
5151
var io_mem = io.memory();
5252

5353
// Build memory spaces via MCU helper
54-
const spaces = try aviron.mcu.build_spaces(allocator, mcu_config, &flash_mem, &sram_mem, &io_mem);
54+
const spaces = try aviron.mcu.build_spaces(allocator, mcu_config, &sram_mem, &io_mem);
5555
defer spaces.deinit(allocator);
5656

5757
var cpu = aviron.Cpu{
@@ -64,7 +64,6 @@ pub fn main() !u8 {
6464
.io = io_mem,
6565
.data = spaces.data,
6666
.io_space = spaces.io,
67-
.prog = spaces.prog,
6867

6968
.code_model = mcu_config.code_model,
7069
.instruction_set = mcu_config.instruction_set,

sim/aviron/src/testrunner.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn run_test(
7676
var io_mem = io.memory();
7777

7878
// Build memory spaces via MCU helper
79-
const spaces = try aviron.mcu.build_spaces(allocator, mcu_config, &flash_mem, &sram_mem, &io_mem);
79+
const spaces = try aviron.mcu.build_spaces(allocator, mcu_config, &sram_mem, &io_mem);
8080
defer spaces.deinit(allocator);
8181

8282
var cpu = aviron.Cpu{
@@ -89,7 +89,6 @@ fn run_test(
8989
.io = io_mem,
9090
.data = spaces.data,
9191
.io_space = spaces.io,
92-
.prog = spaces.prog,
9392
.code_model = mcu_config.code_model,
9493
.sio = .{
9594
.ramp_x = mcu_config.special_io.ramp_x,

0 commit comments

Comments
 (0)