concept opcode in category rust

This is an excerpt from Manning's book Rust in Action MEAP V14.
an opcode is a number that maps to an operation. On the CHIP-8 platform, opcodes include both the operation and the operands' registers.
Listing 5.23. Extract from Listing 5.26, “Implementing the beginnings of CHIP-8 emulator (ch5/ch5-cpu1/src/main.rs)” that shows the first functionality being added to the emulator.
impl CPU { fn read_opcode(&self) -> u16 { #1 self.current_operation #2 } #3 fn run(&mut self) { // loop { #4 let opcode = self.read_opcode(); let c = ((opcode & 0xF000) >> 12) as u8; #5 let x = ((opcode & 0x0F00) >> 8) as u8; #6 let y = ((opcode & 0x00F0) >> 4) as u8; #7 let d = ((opcode & 0x000F) >> 0) as u8; #8 match (c, x, y, d) { (0x8, _, _, 0x4) => self.add_xy(x, y), #9 _ => todo!("opcode {:04x}", opcode), #10 } // } #11 } fn add_xy(&mut self, x: u8, y: u8) { self.registers[x as usize] += self.registers[y as usize]; } }
There are three main form of opcodes, as illustrated by Figure 5.4, “CHIP-8 opcodes are decoded in multiple ways. The approach to use depends on the value of the left-most nibble.”. The decoding process involves matching on the high nibble of the first byte and then applying one of three strategies.
Figure 5.4. CHIP-8 opcodes are decoded in multiple ways. The approach to use depends on the value of the left-most nibble.
![]()
To extract nibbles from bytes, we’ll need to use the right shift (
>>
) and logical AND (&
) bitwise operations. These operations were introduced during the section called “About Floating Point”. Listing 5.24, “Extracting variables from an opcode using the right shift and logical AND bitwise operations.” demonstrates applying them to the current problem.Listing 5.24. Extracting variables from an opcode using the right shift and logical AND bitwise operations.
fn main() { let opcode: u16 = 0x71E4; #1 let c = (opcode & 0xF000) >> 12; #2 let x = (opcode & 0x0F00) >> 8; #3 let y = (opcode & 0x00F0) >> 4; #4 let d = (opcode & 0x000F) >> 0; #5 assert_eq!(c, 0x7); #6 assert_eq!(x, 0x1); #7 assert_eq!(y, 0xE); #8 assert_eq!(d, 0x4); #9 let nnn = opcode & 0x0FFF; #10 let kk = opcode & 0x00FF; #11 assert_eq!(nnn, 0x1E4); assert_eq!(kk, 0xE4); }