52 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
			
		
		
	
	
			52 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
| const std = @import("std");
 | |
| 
 | |
| const Bus = @import("../../Bus.zig");
 | |
| const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
 | |
| const InstrFn = @import("../../cpu.zig").ThumbInstrFn;
 | |
| const shifter = @import("../barrel_shifter.zig");
 | |
| 
 | |
| const setLogicOpFlags = @import("../arm/data_processing.zig").setLogicOpFlags;
 | |
| 
 | |
| pub fn format1(comptime op: u2, comptime offset: u5) InstrFn {
 | |
|     return struct {
 | |
|         fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void {
 | |
|             const rs = opcode >> 3 & 0x7;
 | |
|             const rd = opcode & 0x7;
 | |
| 
 | |
|             const result = switch (op) {
 | |
|                 0b00 => blk: {
 | |
|                     // LSL
 | |
|                     if (offset == 0) {
 | |
|                         break :blk cpu.r[rs];
 | |
|                     } else {
 | |
|                         break :blk shifter.logicalLeft(true, &cpu.cpsr, cpu.r[rs], offset);
 | |
|                     }
 | |
|                 },
 | |
|                 0b01 => blk: {
 | |
|                     // LSR
 | |
|                     if (offset == 0) {
 | |
|                         cpu.cpsr.c.write(cpu.r[rs] >> 31 & 1 == 1);
 | |
|                         break :blk @as(u32, 0);
 | |
|                     } else {
 | |
|                         break :blk shifter.logicalRight(true, &cpu.cpsr, cpu.r[rs], offset);
 | |
|                     }
 | |
|                 },
 | |
|                 0b10 => blk: {
 | |
|                     // ASR
 | |
|                     if (offset == 0) {
 | |
|                         cpu.cpsr.c.write(cpu.r[rs] >> 31 & 1 == 1);
 | |
|                         break :blk @bitCast(u32, @bitCast(i32, cpu.r[rs]) >> 31);
 | |
|                     } else {
 | |
|                         break :blk shifter.arithmeticRight(true, &cpu.cpsr, cpu.r[rs], offset);
 | |
|                     }
 | |
|                 },
 | |
|                 else => cpu.panic("[CPU|THUMB|Fmt1] {} is an invalid op", .{op}),
 | |
|             };
 | |
| 
 | |
|             // Equivalent to an ARM MOVS
 | |
|             cpu.r[rd] = result;
 | |
|             setLogicOpFlags(true, cpu, result);
 | |
|         }
 | |
|     }.inner;
 | |
| }
 |