1use crate::superfx::gsu::GraphicsSupportUnit; 2use crate::superfx::gsu::instructions::{ 3 MemoryType, clear_prefix_flags, read_register, write_register, 4}; 5use jgenesis_common::num::{GetBit, SignBit}; 6 7pub(super) fn from( 8 opcode: u8, 9 memory_type: MemoryType, 10 gsu: &mut GraphicsSupportUnit, 11 rom: &[u8], 12 ram: &[u8], 13) -> u8 { 14 // FROM: Set source register 15 // If B flag is set, this executes a MOVE that also sets flags (MOVES) 16 let cycles = if !gsu.b { 17 gsu.sreg = opcode & 0x0F; 18 0 19 } else { 20 let register = opcode & 0x0F; 21 let value = read_register(gsu, register); 22 let cycles = write_register(gsu, gsu.dreg, value, rom, ram); 23 24 gsu.zero_flag = value == 0; 25 gsu.overflow_flag = value.bit(7); 26 gsu.sign_flag = value.sign_bit(); 27 28 clear_prefix_flags(gsu); 29 cycles 30 }; 31 32 cycles + memory_type.access_cycles(gsu.clock_speed) 33} 34 35pub(super) fn to( 36 opcode: u8, 37 memory_type: MemoryType, 38 gsu: &mut GraphicsSupportUnit, 39 rom: &[u8], 40 ram: &[u8], 41) -> u8 { 42 // TO: Set destination register 43 // If B flag is set, this executes a MOVE 44 let cycles = if !gsu.b { 45 gsu.dreg = opcode & 0x0F; 46 0 47 } else { 48 let register = opcode & 0xF; 49 let value = read_register(gsu, gsu.sreg); 50 let cycles = write_register(gsu, register, value, rom, ram); 51 52 clear_prefix_flags(gsu); 53 cycles 54 }; 55 56 cycles + memory_type.access_cycles(gsu.clock_speed) 57} 58 59pub(super) fn with(opcode: u8, memory_type: MemoryType, gsu: &mut GraphicsSupportUnit) -> u8 { 60 // WITH: Set source and destination registers 61 let register = opcode & 0x0F; 62 gsu.sreg = register; 63 gsu.dreg = register; 64 gsu.b = true; 65 66 memory_type.access_cycles(gsu.clock_speed) 67} 68 69pub(super) fn alt1(memory_type: MemoryType, gsu: &mut GraphicsSupportUnit) -> u8 { 70 // ALT1: Set ALT1 flag (modifies instructions) 71 gsu.alt1 = true; 72 memory_type.access_cycles(gsu.clock_speed) 73} 74 75pub(super) fn alt2(memory_type: MemoryType, gsu: &mut GraphicsSupportUnit) -> u8 { 76 // ALT2: Set ALT2 flag (modifies instructions) 77 gsu.alt2 = true; 78 memory_type.access_cycles(gsu.clock_speed) 79} 80 81pub(super) fn alt3(memory_type: MemoryType, gsu: &mut GraphicsSupportUnit) -> u8 { 82 // ALT3: Set both ALT1 and ALT2 flags (modifies instructions) 83 gsu.alt1 = true; 84 gsu.alt2 = true; 85 memory_type.access_cycles(gsu.clock_speed) 86}