#Read from []u8 as i8

1 messages · Page 1 of 1 (latest)

subtle widget
#

Hi there, I'm writing a Z80 emulator as a learning experience and there is one particular instruction JR n that reads a byte from memory as a two's complement.

I was wondering how I could read it. I tried this:

            0x18 => {
                // JR n
                const offset = self.fetchByteAsI8();
                if (offset > 0) {
                    self.pc +%= @as(u8, @intCast(offset));
                } else {
                    self.pc -%= @as(u8, @intCast(-offset));
                }
                self.cycles += 12;
            },

And:

    fn fetchByte(self: *Z80) u8 {
        const byte = self.memory[self.pc];
        self.pc +%= 1;
        return byte;
    }

    fn fetchByteAsI8(self: *Z80) i8 {
        return @intCast(self.fetchByte());
    }

But I'm getting:

thread 22682547 panic: integer cast truncated bits
/Users/fcoury/code/zig80/src/cpu.zig:710:16: 0x100b52f5f in fetchByteAsI8 (zig80)
        return @intCast(self.fetchByte());

I am obviously doing this wrong, so any pointers on how to properly do this?

modern condor
#

You want @bitCast instead of @intCast in fetchByteAsI8.

vocal inlet
#

intCast guarantees the value is preserved, you probably want bitCast to just reinterpret those bits

subtle widget
modern condor
#

Also note that's there's potentially a small bug in self.pc -%= @as(u8, @intCast(-offset));:

If there's ever a JR -128 instruction, it will overflow. Eg:

const std = @import("std");

pub fn main() void {
    const a: i8 = -128;
    const b: i8 = -a;
    std.debug.print("a: {d}, b: {d}\n", .{a,b});
}

outputs this:

negative.zig:5:16: error: overflow of integer type 'i8' with value '128'
 const b: i8 = -a;