Compare commits
12 Commits
61a869f0c5
...
2c8e3cb726
Author | SHA1 | Date |
---|---|---|
Rekai Nyangadzayi Musuka | 2c8e3cb726 | |
Rekai Nyangadzayi Musuka | f2d021a829 | |
Rekai Nyangadzayi Musuka | 826fa4524d | |
Rekai Nyangadzayi Musuka | e3776e65ed | |
Rekai Nyangadzayi Musuka | 28217dd37e | |
Rekai Nyangadzayi Musuka | f3d86f3fa0 | |
Rekai Nyangadzayi Musuka | 59b7d4f04b | |
Rekai Nyangadzayi Musuka | a12f09cd8d | |
Rekai Nyangadzayi Musuka | 2baa3c83e9 | |
Rekai Nyangadzayi Musuka | 2607b1ecb6 | |
Rekai Nyangadzayi Musuka | 0669c9917b | |
Rekai Nyangadzayi Musuka | 8722f56f14 |
|
@ -14,8 +14,7 @@ jobs:
|
|||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
# os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: goto-bus-stop/setup-zig@v2
|
||||
|
@ -40,7 +39,7 @@ jobs:
|
|||
with:
|
||||
submodules: true
|
||||
- name: build
|
||||
run: zig build -Doptimize=ReleaseSafe -Dcpu=baseline
|
||||
run: zig build -Doptimize=ReleaseSafe
|
||||
- name: upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
|
|
@ -77,7 +77,7 @@ arm7wrestler GBA Fixed | [destoer](https://github.com/destoer)
|
|||
|
||||
## Compiling
|
||||
|
||||
Most recently built on Zig [v0.11.0-dev.1580+a5b34a61a](https://github.com/ziglang/zig/tree/a5b34a61a)
|
||||
Most recently built on Zig [v0.11.0-dev.1557+03cdb4fb5](https://github.com/ziglang/zig/tree/03cdb4fb5)
|
||||
|
||||
### Dependencies
|
||||
|
||||
|
@ -98,7 +98,7 @@ Use `git submodule update --init` from the project root to pull the git relevant
|
|||
Be sure to provide SDL2 using:
|
||||
|
||||
- Linux: Your distro's package manager
|
||||
- macOS: ¯\\\_(ツ)_/¯ (try [this formula](https://formulae.brew.sh/formula/sdl2)?)
|
||||
- MacOS: `brew` (install [this formula](https://formulae.brew.sh/formula/sdl2))
|
||||
- Windows: [`vcpkg`](https://github.com/Microsoft/vcpkg) (install `sdl2:x64-windows`)
|
||||
|
||||
`SDL.zig` will provide a helpful compile error if the zig compiler is unable to find SDL2.
|
||||
|
|
|
@ -7,7 +7,7 @@ const nfd = @import("lib/nfd-zig/build.zig");
|
|||
|
||||
pub fn build(b: *std.build.Builder) void {
|
||||
// Minimum Zig Version
|
||||
const min_ver = std.SemanticVersion.parse("0.11.0-dev.1580+a5b34a61a") catch return; // https://github.com/ziglang/zig/commit/a5b34a61a
|
||||
const min_ver = std.SemanticVersion.parse("0.11.0-dev.1557+03cdb4fb5") catch return; // https://github.com/ziglang/zig/commit/03cdb4fb5
|
||||
if (builtin.zig_version.order(min_ver).compare(.lt)) {
|
||||
std.log.err("{s}", .{b.fmt("Zig v{} does not meet the minimum version requirement. (Zig v{})", .{ builtin.zig_version, min_ver })});
|
||||
std.os.exit(1);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 59c90e8ea2135384410817ccfdcc15ce5f7a245e
|
||||
Subproject commit 6b33f1f4299ec8814e9fb3b206cda37791ced574
|
|
@ -1 +1 @@
|
|||
Subproject commit 861de651f3e1314973b1273ac7856e96b2625ff3
|
||||
Subproject commit 272d8e2088b2cae037349fb260dc05ec46bba422
|
|
@ -1 +1 @@
|
|||
Subproject commit bf0ae0c27cfe92fdd9a92c8f1ac6d1939ae60c77
|
||||
Subproject commit 932d2845210644ca736faf35f5bea31eb1a15465
|
|
@ -105,7 +105,7 @@ pub fn deinit(self: *Self) void {
|
|||
fn fillReadTable(self: *Self, table: *[table_len]?*const anyopaque) void {
|
||||
const vramMirror = @import("ppu/Vram.zig").mirror;
|
||||
|
||||
for (table, 0..) |*ptr, i| {
|
||||
for (table) |*ptr, i| {
|
||||
const addr = @intCast(u32, page_size * i);
|
||||
|
||||
ptr.* = switch (addr) {
|
||||
|
@ -132,7 +132,7 @@ fn fillWriteTable(self: *Self, comptime T: type, table: *[table_len]?*const anyo
|
|||
comptime std.debug.assert(T == u32 or T == u16 or T == u8);
|
||||
const vramMirror = @import("ppu/Vram.zig").mirror;
|
||||
|
||||
for (table, 0..) |*ptr, i| {
|
||||
for (table) |*ptr, i| {
|
||||
const addr = @intCast(u32, page_size * i);
|
||||
|
||||
ptr.* = switch (addr) {
|
||||
|
|
|
@ -213,7 +213,6 @@ fn guessDevice(buf: []const u8) Gpio.Device.Kind {
|
|||
// Try to Guess if ROM uses RTC
|
||||
const needle = "RTC_V"; // I was told SIIRTC_V, though Pokemen Firered (USA) is a false negative
|
||||
|
||||
// TODO: Use new for loop syntax?
|
||||
var i: usize = 0;
|
||||
while ((i + needle.len) < buf.len) : (i += 1) {
|
||||
if (std.mem.eql(u8, needle, buf[i..(i + needle.len)])) return .Rtc;
|
||||
|
|
|
@ -137,7 +137,6 @@ pub const Backup = struct {
|
|||
for (backup_kinds) |needle| {
|
||||
const needle_len = needle.str.len;
|
||||
|
||||
// TODO: Use new for loop syntax?
|
||||
var i: usize = 0;
|
||||
while ((i + needle_len) < rom.len) : (i += 1) {
|
||||
if (std.mem.eql(u8, needle.str, rom[i..][0..needle_len])) return needle.kind;
|
||||
|
|
|
@ -339,7 +339,10 @@ fn DmaController(comptime id: u2) type {
|
|||
}
|
||||
|
||||
pub fn onBlanking(bus: *Bus, comptime kind: DmaKind) void {
|
||||
inline for (0..4) |i| bus.dma[i].poll(kind);
|
||||
comptime var i: usize = 0;
|
||||
inline while (i < 4) : (i += 1) {
|
||||
bus.dma[i].poll(kind);
|
||||
}
|
||||
}
|
||||
|
||||
const Adjustment = enum(u2) {
|
||||
|
|
|
@ -293,13 +293,13 @@ pub const Clock = struct {
|
|||
self.cpu.sched.push(.RealTimeClock, (1 << 24) -| late); // Reschedule
|
||||
|
||||
const now = DateTime.now();
|
||||
self.year = bcd(@intCast(u8, now.date.year - 2000));
|
||||
self.month = @truncate(u5, bcd(now.date.month));
|
||||
self.day = @truncate(u6, bcd(now.date.day));
|
||||
self.weekday = @truncate(u3, bcd((now.date.weekday() + 1) % 7)); // API is Monday = 0, Sunday = 6. We want Sunday = 0, Saturday = 6
|
||||
self.hour = @truncate(u6, bcd(now.time.hour));
|
||||
self.minute = @truncate(u7, bcd(now.time.minute));
|
||||
self.second = @truncate(u7, bcd(now.time.second));
|
||||
self.year = bcd(u8, @intCast(u8, now.date.year - 2000));
|
||||
self.month = bcd(u5, now.date.month);
|
||||
self.day = bcd(u6, now.date.day);
|
||||
self.weekday = bcd(u3, (now.date.weekday() + 1) % 7); // API is Monday = 0, Sunday = 6. We want Sunday = 0, Saturday = 6
|
||||
self.hour = bcd(u6, now.time.hour);
|
||||
self.minute = bcd(u7, now.time.minute);
|
||||
self.second = bcd(u7, now.time.second);
|
||||
}
|
||||
|
||||
fn step(self: *Self, value: Data) u4 {
|
||||
|
@ -449,8 +449,16 @@ pub const Clock = struct {
|
|||
}
|
||||
};
|
||||
|
||||
/// Converts an 8-bit unsigned integer to its BCD representation.
|
||||
/// Note: Algorithm only works for values between 0 and 99 inclusive.
|
||||
fn bcd(value: u8) u8 {
|
||||
return ((value / 10) << 4) + (value % 10);
|
||||
fn bcd(comptime T: type, value: u8) T {
|
||||
var input = value;
|
||||
var ret: u8 = 0;
|
||||
var shift: u3 = 0;
|
||||
|
||||
while (input > 0) {
|
||||
ret |= (input % 10) << (shift << 2);
|
||||
shift += 1;
|
||||
input /= 10;
|
||||
}
|
||||
|
||||
return @truncate(T, ret);
|
||||
}
|
||||
|
|
|
@ -39,12 +39,13 @@ pub const arm = struct {
|
|||
}
|
||||
|
||||
fn populate() [0x1000]InstrFn {
|
||||
comptime {
|
||||
return comptime {
|
||||
@setEvalBranchQuota(0xE000);
|
||||
var table = [_]InstrFn{und} ** 0x1000;
|
||||
var ret = [_]InstrFn{und} ** 0x1000;
|
||||
|
||||
for (&table, 0..) |*handler, i| {
|
||||
handler.* = switch (@as(u2, i >> 10)) {
|
||||
var i: usize = 0;
|
||||
while (i < ret.len) : (i += 1) {
|
||||
ret[i] = switch (@as(u2, i >> 10)) {
|
||||
0b00 => if (i == 0x121) blk: {
|
||||
break :blk branchExchange;
|
||||
} else if (i & 0xFCF == 0x009) blk: {
|
||||
|
@ -106,8 +107,8 @@ pub const arm = struct {
|
|||
};
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -135,12 +136,13 @@ pub const thumb = struct {
|
|||
}
|
||||
|
||||
fn populate() [0x400]InstrFn {
|
||||
comptime {
|
||||
return comptime {
|
||||
@setEvalBranchQuota(5025); // This is exact
|
||||
var table = [_]InstrFn{und} ** 0x400;
|
||||
var ret = [_]InstrFn{und} ** 0x400;
|
||||
|
||||
for (&table, 0..) |*handler, i| {
|
||||
handler.* = switch (@as(u3, i >> 7 & 0x7)) {
|
||||
var i: usize = 0;
|
||||
while (i < ret.len) : (i += 1) {
|
||||
ret[i] = switch (@as(u3, i >> 7 & 0x7)) {
|
||||
0b000 => if (i >> 5 & 0x3 == 0b11) blk: {
|
||||
const I = i >> 4 & 1 == 1;
|
||||
const is_sub = i >> 3 & 1 == 1;
|
||||
|
@ -228,8 +230,8 @@ pub const thumb = struct {
|
|||
};
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -383,7 +385,8 @@ pub const Arm7tdmi = struct {
|
|||
const now = getModeChecked(self, self.cpsr.mode.read());
|
||||
|
||||
// Bank R8 -> r12
|
||||
for (0..5) |i| {
|
||||
var i: usize = 0;
|
||||
while (i < 5) : (i += 1) {
|
||||
self.bank.fiq[Bank.fiqIdx(i, now)] = self.r[8 + i];
|
||||
}
|
||||
|
||||
|
@ -401,7 +404,8 @@ pub const Arm7tdmi = struct {
|
|||
}
|
||||
|
||||
// Grab R8 -> R12
|
||||
for (0..5) |i| {
|
||||
i = 0;
|
||||
while (i < 5) : (i += 1) {
|
||||
self.r[8 + i] = self.bank.fiq[Bank.fiqIdx(i, next)];
|
||||
}
|
||||
|
||||
|
@ -466,7 +470,8 @@ pub const Arm7tdmi = struct {
|
|||
}
|
||||
|
||||
pub fn stepDmaTransfer(self: *Self) bool {
|
||||
inline for (0..4) |i| {
|
||||
comptime var i: usize = 0;
|
||||
inline while (i < 4) : (i += 1) {
|
||||
if (self.bus.dma[i].in_progress) {
|
||||
self.bus.dma[i].step(self);
|
||||
return true;
|
||||
|
|
|
@ -92,7 +92,8 @@ pub fn fmt15(comptime L: bool, comptime rb: u3) InstrFn {
|
|||
inline fn countRlist(opcode: u16) u32 {
|
||||
var count: u32 = 0;
|
||||
|
||||
inline for (0..8) |i| {
|
||||
comptime var i: u4 = 0;
|
||||
inline while (i < 8) : (i += 1) {
|
||||
if (opcode >> (7 - i) & 1 == 1) count += 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,8 +150,9 @@ fn sleep(timer: *Timer, wake_time: u64) ?u64 {
|
|||
|
||||
const step = 2 * std.time.ns_per_ms; // Granularity of 2ms
|
||||
const times = sleep_for / step;
|
||||
var i: usize = 0;
|
||||
|
||||
for (0..times) |_| {
|
||||
while (i < times) : (i += 1) {
|
||||
std.time.sleep(step);
|
||||
|
||||
// Upon wakeup, check to see if this particular sleep was longer than expected
|
||||
|
|
|
@ -625,7 +625,8 @@ pub const Ppu = struct {
|
|||
const framebuf_base = width * @as(usize, scanline);
|
||||
if (obj_enable) self.fetchSprites();
|
||||
|
||||
for (0..4) |layer| {
|
||||
var layer: usize = 0;
|
||||
while (layer < 4) : (layer += 1) {
|
||||
self.drawSprites(@truncate(u2, layer));
|
||||
if (layer == self.bg[0].cnt.priority.read() and bg_enable & 1 == 1) self.drawBackground(0);
|
||||
if (layer == self.bg[1].cnt.priority.read() and bg_enable >> 1 & 1 == 1) self.drawBackground(1);
|
||||
|
@ -639,7 +640,8 @@ pub const Ppu = struct {
|
|||
const framebuf_base = width * @as(usize, scanline);
|
||||
if (obj_enable) self.fetchSprites();
|
||||
|
||||
for (0..4) |layer| {
|
||||
var layer: usize = 0;
|
||||
while (layer < 4) : (layer += 1) {
|
||||
self.drawSprites(@truncate(u2, layer));
|
||||
if (layer == self.bg[0].cnt.priority.read() and bg_enable & 1 == 1) self.drawBackground(0);
|
||||
if (layer == self.bg[1].cnt.priority.read() and bg_enable >> 1 & 1 == 1) self.drawBackground(1);
|
||||
|
@ -652,7 +654,8 @@ pub const Ppu = struct {
|
|||
const framebuf_base = width * @as(usize, scanline);
|
||||
if (obj_enable) self.fetchSprites();
|
||||
|
||||
for (0..4) |layer| {
|
||||
var layer: usize = 0;
|
||||
while (layer < 4) : (layer += 1) {
|
||||
self.drawSprites(@truncate(u2, layer));
|
||||
if (layer == self.bg[2].cnt.priority.read() and bg_enable >> 2 & 1 == 1) self.drawAffineBackground(2);
|
||||
if (layer == self.bg[3].cnt.priority.read() and bg_enable >> 3 & 1 == 1) self.drawAffineBackground(3);
|
||||
|
@ -668,7 +671,7 @@ pub const Ppu = struct {
|
|||
const vram_buf = @ptrCast([*]const u16, @alignCast(@alignOf(u16), self.vram.buf));
|
||||
const framebuf = @ptrCast([*]u32, @alignCast(@alignOf(u32), self.framebuf.get(.Emulator)));
|
||||
|
||||
for (vram_buf[vram_base .. vram_base + width], 0..) |bgr555, i| {
|
||||
for (vram_buf[vram_base .. vram_base + width]) |bgr555, i| {
|
||||
framebuf[framebuf_base + i] = rgba888(bgr555);
|
||||
}
|
||||
},
|
||||
|
@ -682,7 +685,7 @@ pub const Ppu = struct {
|
|||
const pal_buf = @ptrCast([*]const u16, @alignCast(@alignOf(u16), self.palette.buf));
|
||||
const framebuf = @ptrCast([*]u32, @alignCast(@alignOf(u32), self.framebuf.get(.Emulator)));
|
||||
|
||||
for (self.vram.buf[vram_base .. vram_base + width], 0..) |pal_id, i| {
|
||||
for (self.vram.buf[vram_base .. vram_base + width]) |pal_id, i| {
|
||||
framebuf[framebuf_base + i] = rgba888(pal_buf[pal_id]);
|
||||
}
|
||||
},
|
||||
|
@ -698,7 +701,8 @@ pub const Ppu = struct {
|
|||
const vram_buf = @ptrCast([*]const u16, @alignCast(@alignOf(u16), self.vram.buf));
|
||||
const framebuf = @ptrCast([*]u32, @alignCast(@alignOf(u32), self.framebuf.get(.Emulator)));
|
||||
|
||||
for (0..width) |i| {
|
||||
var i: usize = 0;
|
||||
while (i < width) : (i += 1) {
|
||||
const bgr555 = if (scanline < m5_height and i < m5_width) vram_buf[vram_base + i] else self.palette.backdrop();
|
||||
framebuf[framebuf_base + i] = rgba888(bgr555);
|
||||
}
|
||||
|
@ -714,7 +718,7 @@ pub const Ppu = struct {
|
|||
// FIXME: @ptrCast between slices changing the length isn't implemented yet
|
||||
const framebuf = @ptrCast([*]u32, @alignCast(@alignOf(u32), self.framebuf.get(.Emulator)));
|
||||
|
||||
for (self.scanline.top(), 0..) |maybe_top, i| {
|
||||
for (self.scanline.top()) |maybe_top, i| {
|
||||
const maybe_btm = self.scanline.btm()[i];
|
||||
|
||||
const bgr555 = self.getBgr555(maybe_top, maybe_btm);
|
||||
|
|
|
@ -73,7 +73,7 @@ pub const Scheduler = struct {
|
|||
|
||||
/// Removes the **first** scheduled event of type `needle`
|
||||
pub fn removeScheduledEvent(self: *Self, needle: EventKind) void {
|
||||
for (self.queue.items, 0..) |event, i| {
|
||||
for (self.queue.items) |event, i| {
|
||||
if (std.meta.eql(event.kind, needle)) {
|
||||
|
||||
// invalidates the slice we're iterating over
|
||||
|
|
|
@ -92,7 +92,7 @@ pub fn main() void {
|
|||
gui.run(&cpu, &scheduler) catch |e| exitln("failed to run gui thread: {}", .{e});
|
||||
}
|
||||
|
||||
fn handleArguments(allocator: Allocator, data_path: []const u8, result: *const clap.Result(clap.Help, ¶ms, clap.parsers.default)) !FilePaths {
|
||||
pub fn handleArguments(allocator: Allocator, data_path: []const u8, result: *const clap.Result(clap.Help, ¶ms, clap.parsers.default)) !FilePaths {
|
||||
const rom_path = romPath(result);
|
||||
log.info("ROM path: {s}", .{rom_path});
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ pub fn RingBuffer(comptime T: type) type {
|
|||
const count = std.math.min(self.len(), cpy.len);
|
||||
var start: Index = self.read;
|
||||
|
||||
for (cpy, 0..) |*v, i| {
|
||||
for (cpy) |*v, i| {
|
||||
if (i >= count) break;
|
||||
|
||||
v.* = self.buf[self.mask(start)];
|
||||
|
|
Loading…
Reference in New Issue