Compare commits
No commits in common. "d34893ba727513d3a676449126ca685d13c899c4" and "505b1b9608be6341ff9dcb4c11f03523a13b23ad" have entirely different histories.
d34893ba72
...
505b1b9608
|
@ -88,8 +88,8 @@ pub fn init(self: *Self, allocator: Allocator, sched: *Scheduler, cpu: *Arm7tdmi
|
||||||
|
|
||||||
// Internal Display Memory behavious unusually on 8-bit reads
|
// Internal Display Memory behavious unusually on 8-bit reads
|
||||||
// so we have two different tables depending on whether there's an 8-bit read or not
|
// so we have two different tables depending on whether there's an 8-bit read or not
|
||||||
fillWriteTable(u32, self, left_write);
|
fillWriteTable(u8, self, left_write);
|
||||||
fillWriteTable(u8, self, right_write);
|
fillWriteTable(u32, self, right_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
|
@ -379,7 +379,7 @@ pub fn write(self: *Self, comptime T: type, unaligned_address: u32, value: T) vo
|
||||||
// We're doing some serious out-of-bounds open-bus writes, they do nothing though
|
// We're doing some serious out-of-bounds open-bus writes, they do nothing though
|
||||||
if (page > table_len) return;
|
if (page > table_len) return;
|
||||||
|
|
||||||
if (self.write_tables[@boolToInt(T == u8)][page]) |some_ptr| {
|
if (self.write_tables[@boolToInt(T == u32)][page]) |some_ptr| {
|
||||||
// We have a pointer to a page, cast the pointer to it's underlying type
|
// We have a pointer to a page, cast the pointer to it's underlying type
|
||||||
const Ptr = [*]T;
|
const Ptr = [*]T;
|
||||||
const alignment = @alignOf(std.meta.Child(Ptr));
|
const alignment = @alignOf(std.meta.Child(Ptr));
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub const Io = struct {
|
||||||
.ie = .{ .raw = 0x0000 },
|
.ie = .{ .raw = 0x0000 },
|
||||||
.irq = .{ .raw = 0x0000 },
|
.irq = .{ .raw = 0x0000 },
|
||||||
.keyinput = .{ .raw = 0x03FF },
|
.keyinput = .{ .raw = 0x03FF },
|
||||||
.waitcnt = .{ .raw = 0x0000_0000 }, // Bit 15 == 0 for GBA
|
.waitcnt = .{ .raw = 0x0000_0000 },
|
||||||
.postflg = .FirstBoot,
|
.postflg = .FirstBoot,
|
||||||
.haltcnt = .Execute,
|
.haltcnt = .Execute,
|
||||||
};
|
};
|
||||||
|
@ -192,7 +192,7 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
||||||
|
|
||||||
// Interrupts
|
// Interrupts
|
||||||
0x0400_0200 => bus.io.setIrqs(value),
|
0x0400_0200 => bus.io.setIrqs(value),
|
||||||
0x0400_0204 => bus.io.waitcnt.set(@truncate(u16, value)),
|
0x0400_0204 => bus.io.waitcnt.raw = @truncate(u16, value),
|
||||||
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
||||||
0x0400_0300 => {
|
0x0400_0300 => {
|
||||||
bus.io.postflg = @intToEnum(PostFlag, value & 1);
|
bus.io.postflg = @intToEnum(PostFlag, value & 1);
|
||||||
|
@ -237,7 +237,7 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
||||||
// Interrupts
|
// Interrupts
|
||||||
0x0400_0200 => bus.io.ie.raw = value,
|
0x0400_0200 => bus.io.ie.raw = value,
|
||||||
0x0400_0202 => bus.io.irq.raw &= ~value,
|
0x0400_0202 => bus.io.irq.raw &= ~value,
|
||||||
0x0400_0204 => bus.io.waitcnt.set(value),
|
0x0400_0204 => bus.io.waitcnt.raw = value,
|
||||||
0x0400_0206 => {},
|
0x0400_0206 => {},
|
||||||
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
||||||
0x0400_020A => {},
|
0x0400_020A => {},
|
||||||
|
@ -272,7 +272,7 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
||||||
0x0400_0200, 0x0400_0201 => bus.io.ie.raw = setHalf(u16, bus.io.ie.raw, @truncate(u8, address), value),
|
0x0400_0200, 0x0400_0201 => bus.io.ie.raw = setHalf(u16, bus.io.ie.raw, @truncate(u8, address), value),
|
||||||
0x0400_0202 => bus.io.irq.raw &= ~@as(u16, value),
|
0x0400_0202 => bus.io.irq.raw &= ~@as(u16, value),
|
||||||
0x0400_0203 => bus.io.irq.raw &= ~@as(u16, value) << 8, // TODO: Is this good?
|
0x0400_0203 => bus.io.irq.raw &= ~@as(u16, value) << 8, // TODO: Is this good?
|
||||||
0x0400_0204, 0x0400_0205 => bus.io.waitcnt.set(setHalf(u16, @truncate(u16, bus.io.waitcnt.raw), @truncate(u8, address), value)),
|
0x0400_0204, 0x0400_0205 => bus.io.waitcnt.raw = setHalf(u16, @truncate(u16, bus.io.waitcnt.raw), @truncate(u8, address), value),
|
||||||
0x0400_0206, 0x0400_0207 => {},
|
0x0400_0206, 0x0400_0207 => {},
|
||||||
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
||||||
0x0400_0209 => {},
|
0x0400_0209 => {},
|
||||||
|
@ -317,22 +317,14 @@ pub const DisplayControl = extern union {
|
||||||
|
|
||||||
/// Read / Write
|
/// Read / Write
|
||||||
pub const DisplayStatus = extern union {
|
pub const DisplayStatus = extern union {
|
||||||
/// read-only
|
|
||||||
vblank: Bit(u16, 0),
|
vblank: Bit(u16, 0),
|
||||||
/// read-only
|
|
||||||
hblank: Bit(u16, 1),
|
hblank: Bit(u16, 1),
|
||||||
// read-only
|
|
||||||
coincidence: Bit(u16, 2),
|
coincidence: Bit(u16, 2),
|
||||||
vblank_irq: Bit(u16, 3),
|
vblank_irq: Bit(u16, 3),
|
||||||
hblank_irq: Bit(u16, 4),
|
hblank_irq: Bit(u16, 4),
|
||||||
vcount_irq: Bit(u16, 5),
|
vcount_irq: Bit(u16, 5),
|
||||||
vcount_trigger: Bitfield(u16, 8, 8),
|
vcount_trigger: Bitfield(u16, 8, 8),
|
||||||
raw: u16,
|
raw: u16,
|
||||||
|
|
||||||
pub fn set(self: *DisplayStatus, value: u16) void {
|
|
||||||
const mask: u16 = 0x00C7; // set bits are read-only
|
|
||||||
self.raw = (self.raw & mask) | (value & ~mask);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Read Only
|
/// Read Only
|
||||||
|
@ -638,9 +630,4 @@ pub const WaitControl = extern union {
|
||||||
prefetch_enable: Bit(u16, 14),
|
prefetch_enable: Bit(u16, 14),
|
||||||
pak_kind: Bit(u16, 15),
|
pak_kind: Bit(u16, 15),
|
||||||
raw: u16,
|
raw: u16,
|
||||||
|
|
||||||
pub fn set(self: *WaitControl, value: u16) void {
|
|
||||||
const mask: u16 = 0x8000; // set bits are read-only
|
|
||||||
self.raw = (self.raw & mask) | (value & ~mask);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -94,7 +94,7 @@ pub fn write(comptime T: type, ppu: *Ppu, addr: u32, value: T) void {
|
||||||
u32 => switch (byte_addr) {
|
u32 => switch (byte_addr) {
|
||||||
0x00 => ppu.dispcnt.raw = @truncate(u16, value),
|
0x00 => ppu.dispcnt.raw = @truncate(u16, value),
|
||||||
0x04 => {
|
0x04 => {
|
||||||
ppu.dispstat.set(@truncate(u16, value));
|
ppu.dispstat.raw = @truncate(u16, value);
|
||||||
ppu.vcount.raw = @truncate(u16, value >> 16);
|
ppu.vcount.raw = @truncate(u16, value >> 16);
|
||||||
},
|
},
|
||||||
0x08 => ppu.setAdjCnts(0, value),
|
0x08 => ppu.setAdjCnts(0, value),
|
||||||
|
@ -130,7 +130,7 @@ pub fn write(comptime T: type, ppu: *Ppu, addr: u32, value: T) void {
|
||||||
u16 => switch (byte_addr) {
|
u16 => switch (byte_addr) {
|
||||||
0x00 => ppu.dispcnt.raw = value,
|
0x00 => ppu.dispcnt.raw = value,
|
||||||
0x02 => {}, // Green Swap
|
0x02 => {}, // Green Swap
|
||||||
0x04 => ppu.dispstat.set(value),
|
0x04 => ppu.dispstat.raw = value,
|
||||||
0x06 => {}, // VCOUNT
|
0x06 => {}, // VCOUNT
|
||||||
|
|
||||||
0x08 => ppu.bg[0].cnt.raw = value,
|
0x08 => ppu.bg[0].cnt.raw = value,
|
||||||
|
@ -178,7 +178,7 @@ pub fn write(comptime T: type, ppu: *Ppu, addr: u32, value: T) void {
|
||||||
u8 => switch (byte_addr) {
|
u8 => switch (byte_addr) {
|
||||||
0x00, 0x01 => ppu.dispcnt.raw = setHalf(u16, ppu.dispcnt.raw, byte_addr, value),
|
0x00, 0x01 => ppu.dispcnt.raw = setHalf(u16, ppu.dispcnt.raw, byte_addr, value),
|
||||||
0x02, 0x03 => {}, // Green Swap
|
0x02, 0x03 => {}, // Green Swap
|
||||||
0x04, 0x05 => ppu.dispstat.set(setHalf(u16, ppu.dispstat.raw, byte_addr, value)),
|
0x04, 0x05 => ppu.dispstat.raw = setHalf(u16, ppu.dispstat.raw, byte_addr, value),
|
||||||
0x06, 0x07 => {}, // VCOUNT
|
0x06, 0x07 => {}, // VCOUNT
|
||||||
|
|
||||||
// BGXCNT
|
// BGXCNT
|
||||||
|
|
Loading…
Reference in New Issue