zba/src/cpu/data_processing.zig

76 lines
2.6 KiB
Zig
Raw Normal View History

2021-12-29 21:09:00 +00:00
const std = @import("std");
const arm = @import("../cpu.zig");
2021-12-29 21:09:00 +00:00
const BarrelShifter = @import("barrel_shifter.zig");
2021-12-29 21:09:00 +00:00
const Bus = @import("../bus.zig").Bus;
const Arm7tdmi = arm.Arm7tdmi;
const InstrFn = arm.InstrFn;
2021-12-29 21:09:00 +00:00
pub fn comptimeDataProcessing(comptime I: bool, comptime S: bool, comptime instrKind: u4) InstrFn {
return struct {
2022-01-02 03:08:36 +00:00
fn dataProcessing(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void {
2021-12-29 21:09:00 +00:00
const rd = opcode >> 12 & 0xF;
const op1 = opcode >> 16 & 0xF;
var op2: u32 = undefined;
if (I) {
op2 = std.math.rotr(u32, opcode & 0xFF, (opcode >> 8 & 0xF) << 1);
} else {
op2 = BarrelShifter.exec(cpu, opcode);
2021-12-29 21:09:00 +00:00
}
switch (instrKind) {
0x4 => {
// ADD
2021-12-29 21:09:00 +00:00
cpu.r[rd] = cpu.r[op1] + op2;
if (S) std.debug.panic("[CPU] TODO: implement ADD condition codes", .{});
2021-12-29 21:09:00 +00:00
},
2022-01-04 10:06:04 +00:00
0x8 => {
// TST
std.debug.panic("[CPU] TODO: implement TST, also figure out barrel shifter flags\n", .{});
},
2021-12-29 21:09:00 +00:00
0xD => {
// MOV
2021-12-29 21:09:00 +00:00
cpu.r[rd] = op2;
if (S) std.debug.panic("[CPU] implement MOV condition codes", .{});
2021-12-29 21:09:00 +00:00
},
0xA => {
// CMP
2022-01-02 03:08:36 +00:00
const op1_val = cpu.r[op1];
2022-01-04 10:06:04 +00:00
const v_ctx = (op1_val >> 31 == 1) or (op2 >> 31 == 1);
2022-01-02 03:08:36 +00:00
const result = op1_val -% op2;
2022-01-02 03:08:36 +00:00
2022-01-04 10:06:04 +00:00
cpu.cpsr.n.write(result >> 31 & 1 == 1);
cpu.cpsr.z.write(result == 0);
cpu.cpsr.c.write(op2 <= op1_val);
cpu.cpsr.v.write(v_ctx and (result >> 31 & 1 == 1));
},
else => std.debug.panic("[CPU] TODO: implement data processing type {}", .{instrKind}),
2021-12-29 21:09:00 +00:00
}
}
}.dataProcessing;
}
// fn registerOp2(cpu: *const Arm7tdmi, opcode: u32) u32 {
// var amount: u32 = undefined;
// if (opcode >> 4 & 0x01 == 0x01) {
// amount = cpu.r[opcode >> 8 & 0xF] & 0xFF;
// } else {
// amount = opcode >> 7 & 0x1F;
// }
2021-12-29 21:09:00 +00:00
// const rm = opcode & 0xF;
// const r_val = cpu.r[rm];
2021-12-29 21:09:00 +00:00
// return switch (opcode >> 5 & 0x03) {
// 0b00 => r_val << @truncate(u5, amount),
// 0b01 => r_val >> @truncate(u5, amount),
// 0b10 => @bitCast(u32, @bitCast(i32, r_val) >> @truncate(u5, amount)),
// 0b11 => std.math.rotr(u32, r_val, amount),
// else => unreachable,
// };
// }