Compare commits
	
		
			17 Commits
		
	
	
		
			23f5d676d4
			...
			acdb270793
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| acdb270793 | |||
| 4ceed382ed | |||
| 52ce4f3d20 | |||
| c1c8cac6e4 | |||
| be7a34f719 | |||
| f7a94634f9 | |||
| 7d4ab6db2c | |||
| 0a78587d8e | |||
| b753ceef8e | |||
| 8963fe205b | |||
| e906506e16 | |||
| 3195a45e3d | |||
| 6aad911985 | |||
| e3b45ef794 | |||
| 8e1a539e70 | |||
| 63fa972afa | |||
| bf95eee3f1 | 
 Submodule lib/SDL.zig updated: 00b4356885...2fbd4b2285
									
								
							 Submodule lib/zig-clap updated: a1b01ffeab...8a38c14266
									
								
							| @@ -197,8 +197,29 @@ fn fillTableExternalMemory(bus: *Self, addr: usize) ?*anyopaque { | ||||
|     return &bus.pak.buf[masked_addr]; | ||||
| } | ||||
|  | ||||
| // TODO: Take advantage of fastmem here too? | ||||
| pub fn dbgRead(self: *const Self, comptime T: type, unaligned_address: u32) T { | ||||
|     const bits = @typeInfo(std.math.IntFittingRange(0, page_size - 1)).Int.bits; | ||||
|     const page = unaligned_address >> bits; | ||||
|     const offset = unaligned_address & (page_size - 1); | ||||
|  | ||||
|     // We're doing some serious out-of-bounds open-bus reads | ||||
|     if (page >= table_len) return self.openBus(T, unaligned_address); | ||||
|  | ||||
|     if (self.read_table[page]) |some_ptr| { | ||||
|         // We have a pointer to a page, cast the pointer to it's underlying type | ||||
|         const Ptr = [*]const T; | ||||
|         const alignment = @alignOf(std.meta.Child(Ptr)); | ||||
|         const ptr = @ptrCast(Ptr, @alignCast(alignment, some_ptr)); | ||||
|  | ||||
|         // Note: We don't check array length, since we force align the | ||||
|         // lower bits of the address as the GBA would | ||||
|         return ptr[forceAlign(T, offset) / @sizeOf(T)]; | ||||
|     } | ||||
|  | ||||
|     return self.dbgSlowRead(T, unaligned_address); | ||||
| } | ||||
|  | ||||
| fn dbgSlowRead(self: *const Self, comptime T: type, unaligned_address: u32) T { | ||||
|     const page = @truncate(u8, unaligned_address >> 24); | ||||
|     const address = forceAlign(T, unaligned_address); | ||||
|  | ||||
| @@ -210,29 +231,18 @@ pub fn dbgRead(self: *const Self, comptime T: type, unaligned_address: u32) T { | ||||
|  | ||||
|             break :blk self.openBus(T, address); | ||||
|         }, | ||||
|         0x02 => self.ewram.read(T, address), | ||||
|         0x03 => self.iwram.read(T, address), | ||||
|         0x02 => unreachable, // handled by fastmem | ||||
|         0x03 => unreachable, // handled by fastmem | ||||
|         0x04 => self.readIo(T, address), | ||||
|  | ||||
|         // Internal Display Memory | ||||
|         0x05 => self.ppu.palette.read(T, address), | ||||
|         0x06 => self.ppu.vram.read(T, address), | ||||
|         0x07 => self.ppu.oam.read(T, address), | ||||
|         0x05 => unreachable, // handled by fastmem | ||||
|         0x06 => unreachable, // handled by fastmem | ||||
|         0x07 => unreachable, // handled by fastmem | ||||
|  | ||||
|         // External Memory (Game Pak) | ||||
|         0x08...0x0D => self.pak.dbgRead(T, address), | ||||
|         0x0E...0x0F => blk: { | ||||
|             const value = self.pak.backup.read(unaligned_address); | ||||
|  | ||||
|             const multiplier = switch (T) { | ||||
|                 u32 => 0x01010101, | ||||
|                 u16 => 0x0101, | ||||
|                 u8 => 1, | ||||
|                 else => @compileError("Backup: Unsupported read width"), | ||||
|             }; | ||||
|  | ||||
|             break :blk @as(T, value) * multiplier; | ||||
|         }, | ||||
|         0x0E...0x0F => self.readBackup(T, unaligned_address), | ||||
|         else => self.openBus(T, address), | ||||
|     }; | ||||
| } | ||||
| @@ -352,22 +362,24 @@ fn slowRead(self: *Self, comptime T: type, unaligned_address: u32) T { | ||||
|  | ||||
|         // External Memory (Game Pak) | ||||
|         0x08...0x0D => self.pak.read(T, address), | ||||
|         0x0E...0x0F => blk: { | ||||
|             const value = self.pak.backup.read(unaligned_address); | ||||
|  | ||||
|             const multiplier = switch (T) { | ||||
|                 u32 => 0x01010101, | ||||
|                 u16 => 0x0101, | ||||
|                 u8 => 1, | ||||
|                 else => @compileError("Backup: Unsupported read width"), | ||||
|             }; | ||||
|  | ||||
|             break :blk @as(T, value) * multiplier; | ||||
|         }, | ||||
|         0x0E...0x0F => self.readBackup(T, unaligned_address), | ||||
|         else => self.openBus(T, address), | ||||
|     }; | ||||
| } | ||||
|  | ||||
| fn readBackup(self: *const Self, comptime T: type, unaligned_address: u32) T { | ||||
|     const value = self.pak.backup.read(unaligned_address); | ||||
|  | ||||
|     const multiplier = switch (T) { | ||||
|         u32 => 0x01010101, | ||||
|         u16 => 0x0101, | ||||
|         u8 => 1, | ||||
|         else => @compileError("Backup: Unsupported read width"), | ||||
|     }; | ||||
|  | ||||
|     return @as(T, value) * multiplier; | ||||
| } | ||||
|  | ||||
| pub fn write(self: *Self, comptime T: type, unaligned_address: u32, value: T) void { | ||||
|     const bits = @typeInfo(std.math.IntFittingRange(0, page_size - 1)).Int.bits; | ||||
|     const page = unaligned_address >> bits; | ||||
|   | ||||
| @@ -94,10 +94,9 @@ pub fn sound1CntL(self: *const Self) u8 { | ||||
| pub fn setSound1CntL(self: *Self, value: u8) void { | ||||
|     const new = io.Sweep{ .raw = value }; | ||||
|  | ||||
|     if (self.sweep.direction.read() and !new.direction.read()) { | ||||
|         // Sweep Negate bit has been cleared | ||||
|         // If At least 1 Sweep Calculation has been made since | ||||
|         // the last trigger, the channel is immediately disabled | ||||
|     if (!new.direction.read()) { | ||||
|         // If at least one (1) sweep calculation has been made with | ||||
|         // the negate bit set (since last trigger), disable the channel | ||||
|  | ||||
|         if (self.sweep_dev.calc_performed) self.enabled = false; | ||||
|     } | ||||
|   | ||||
| @@ -31,7 +31,6 @@ pub fn tick(self: *Self, ch1: *ToneSweep) void { | ||||
|     if (self.timer == 0) { | ||||
|         const period = ch1.sweep.period.read(); | ||||
|         self.timer = if (period == 0) 8 else period; | ||||
|         if (!self.calc_performed) self.calc_performed = true; | ||||
|  | ||||
|         if (self.enabled and period != 0) { | ||||
|             const new_freq = self.calculate(ch1.sweep, &ch1.enabled); | ||||
| @@ -52,7 +51,10 @@ pub fn calculate(self: *Self, sweep: io.Sweep, ch_enable: *bool) u12 { | ||||
|     const shadow_shifted = shadow >> sweep.shift.read(); | ||||
|     const decrease = sweep.direction.read(); | ||||
|  | ||||
|     const freq = if (decrease) shadow - shadow_shifted else shadow + shadow_shifted; | ||||
|     const freq = if (decrease) blk: { | ||||
|         self.calc_performed = true; | ||||
|         break :blk shadow - shadow_shifted; | ||||
|     } else shadow + shadow_shifted; | ||||
|     if (freq > 0x7FF) ch_enable.* = false; | ||||
|  | ||||
|     return freq; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user