feat(cpu): implement like 1 THUMB instruction
This commit is contained in:
parent
01385ee46b
commit
5ed5c5d52d
17
src/cpu.zig
17
src/cpu.zig
|
@ -7,6 +7,7 @@ const Bit = @import("bitfield").Bit;
|
||||||
const Bitfield = @import("bitfield").Bitfield;
|
const Bitfield = @import("bitfield").Bitfield;
|
||||||
const Scheduler = @import("scheduler.zig").Scheduler;
|
const Scheduler = @import("scheduler.zig").Scheduler;
|
||||||
|
|
||||||
|
// ARM Instruction Groups
|
||||||
const dataProcessing = @import("cpu/arm/data_processing.zig").dataProcessing;
|
const dataProcessing = @import("cpu/arm/data_processing.zig").dataProcessing;
|
||||||
const psrTransfer = @import("cpu/arm/psr_transfer.zig").psrTransfer;
|
const psrTransfer = @import("cpu/arm/psr_transfer.zig").psrTransfer;
|
||||||
const singleDataTransfer = @import("cpu/arm/single_data_transfer.zig").singleDataTransfer;
|
const singleDataTransfer = @import("cpu/arm/single_data_transfer.zig").singleDataTransfer;
|
||||||
|
@ -15,6 +16,9 @@ const blockDataTransfer = @import("cpu/arm/block_data_transfer.zig").blockDataTr
|
||||||
const branch = @import("cpu/arm/branch.zig").branch;
|
const branch = @import("cpu/arm/branch.zig").branch;
|
||||||
const branchAndExchange = @import("cpu/arm/branch.zig").branchAndExchange;
|
const branchAndExchange = @import("cpu/arm/branch.zig").branchAndExchange;
|
||||||
|
|
||||||
|
// THUMB Instruction Groups
|
||||||
|
const format3 = @import("cpu/thumb/format3.zig").format3;
|
||||||
|
|
||||||
pub const ArmInstrFn = fn (*Arm7tdmi, *Bus, u32) void;
|
pub const ArmInstrFn = fn (*Arm7tdmi, *Bus, u32) void;
|
||||||
pub const ThumbInstrFn = fn (*Arm7tdmi, *Bus, u16) void;
|
pub const ThumbInstrFn = fn (*Arm7tdmi, *Bus, u16) void;
|
||||||
const arm_lut: [0x1000]ArmInstrFn = armPopulate();
|
const arm_lut: [0x1000]ArmInstrFn = armPopulate();
|
||||||
|
@ -141,12 +145,17 @@ fn checkCond(cpsr: PSR, cond: u4) bool {
|
||||||
|
|
||||||
fn thumbPopulate() [0x400]ThumbInstrFn {
|
fn thumbPopulate() [0x400]ThumbInstrFn {
|
||||||
return comptime {
|
return comptime {
|
||||||
@setEvalBranchQuota(0x800);
|
@setEvalBranchQuota(0xC00);
|
||||||
var lut = [_]ThumbInstrFn{thumbUndefined} ** 0x400;
|
var lut = [_]ThumbInstrFn{thumbUndefined} ** 0x400;
|
||||||
|
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < lut.len) : (i += 1) {
|
while (i < lut.len) : (i += 1) {
|
||||||
lut[i] = thumbUndefined;
|
if (i >> 7 & 0x7 == 0b001) {
|
||||||
|
const op = i >> 5 & 0x3;
|
||||||
|
const rd = i >> 2 & 0x7;
|
||||||
|
|
||||||
|
lut[i] = format3(op, rd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lut;
|
return lut;
|
||||||
|
@ -245,10 +254,10 @@ const Mode = enum(u5) {
|
||||||
|
|
||||||
fn armUndefined(_: *Arm7tdmi, _: *Bus, opcode: u32) void {
|
fn armUndefined(_: *Arm7tdmi, _: *Bus, opcode: u32) void {
|
||||||
const id = armIdx(opcode);
|
const id = armIdx(opcode);
|
||||||
std.debug.panic("[CPU:ARM] {{0x{X:}}} 0x{X:} is an illegal opcode", .{ id, opcode });
|
std.debug.panic("[CPU:ARM] ID: 0x{X:0>3} 0x{X:0>8} is an illegal opcode", .{ id, opcode });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn thumbUndefined(_: *Arm7tdmi, _: *Bus, opcode: u16) void {
|
fn thumbUndefined(_: *Arm7tdmi, _: *Bus, opcode: u16) void {
|
||||||
const id = thumbIdx(opcode);
|
const id = thumbIdx(opcode);
|
||||||
std.debug.panic("[CPU:THUMB] {{0x{X:}}} 0x{X:} is an illegal opcode", .{ id, opcode });
|
std.debug.panic("[CPU:THUMB] ID: 0b{b:0>10} 0x{X:0>2} is an illegal opcode", .{ id, opcode });
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Bus = @import("../../Bus.zig");
|
||||||
|
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
|
||||||
|
const InstrFn = @import("../../cpu.zig").ThumbInstrFn;
|
||||||
|
|
||||||
|
pub fn format3(comptime op: u2, comptime rd: u3) InstrFn {
|
||||||
|
return struct {
|
||||||
|
fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void {
|
||||||
|
const offset = @truncate(u8, opcode);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
0b00 => {
|
||||||
|
cpu.r[rd] = offset;
|
||||||
|
|
||||||
|
cpu.cpsr.n.unset();
|
||||||
|
cpu.cpsr.z.write(offset == 0);
|
||||||
|
},
|
||||||
|
0b01 => {
|
||||||
|
std.debug.panic("TODO: Implement cmp R{}, #0x{X:0>2}", .{ rd, offset });
|
||||||
|
},
|
||||||
|
0b10 => {
|
||||||
|
std.debug.panic("TODO: Implement add R{}, #0x{X:0>2}", .{ rd, offset });
|
||||||
|
},
|
||||||
|
0b11 => {
|
||||||
|
std.debug.panic("TODO: Implement sub R{}, #0x{X:0>2}", .{ rd, offset });
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.inner;
|
||||||
|
}
|
Loading…
Reference in New Issue