diff options
| -rw-r--r-- | CHANGELOG | 5 | ||||
| -rw-r--r-- | Cargo.toml | 5 | ||||
| -rw-r--r-- | src/lib.rs | 93 | ||||
| -rw-r--r-- | test/test.rs | 11 | 
4 files changed, 42 insertions, 72 deletions
@@ -1,2 +1,7 @@ +## 0.2.0 + +* update yaxpeax-arch to 0.2.3, fix API changes +* update crate to rust 2018 +  ## 0.1.0  * wrote a decoder @@ -1,15 +1,16 @@  [package]  name = "yaxpeax-sm83" -version = "0.1.0" +version = "0.2.0"  authors = [ "iximeow <me@iximeow.net>" ]  license = "0BSD"  repository = "http://git.iximeow.net/yaxpeax-sm83/"  description = "sm83 decoder for the yaxpeax project"  keywords = ["diassembler", "gameboy", "gbc", "sm83", "lr35902"] +edition = "2018"  [dependencies] -yaxpeax-arch = { version = "0.0.4", default-features = false, features = [] } +yaxpeax-arch = { version = "0.2.3", default-features = false, features = [] }  "serde" = { version = "1.0", optional = true }  "serde_derive" = { version = "1.0", optional = true }  "num_enum" = { version = "0.2", default-features = false } @@ -1,10 +1,3 @@ -#[cfg(feature="use-serde")] -#[macro_use] extern crate serde_derive; -#[cfg(feature="use-serde")] -extern crate serde; - -extern crate yaxpeax_arch; -  extern crate core;  use core::fmt; @@ -13,19 +6,18 @@ use yaxpeax_arch::AddressDiff;  use yaxpeax_arch::Arch;  use yaxpeax_arch::Decoder;  use yaxpeax_arch::LengthedInstruction; +use yaxpeax_arch::Reader; +use yaxpeax_arch::StandardDecodeError; -#[cfg(feature="use-serde")] -#[derive(Debug, Serialize, Deserialize)] -pub struct SM83; - -#[cfg(not(feature="use-serde"))] +#[cfg_attr(feature="use-serde", derive(Serialize, Deserialize))]  #[derive(Debug)]  pub struct SM83;  impl Arch for SM83 {      type Address = u16; +    type Word = u8;      type Instruction = Instruction; -    type DecodeError = DecodeError; +    type DecodeError = StandardDecodeError;      type Decoder = InstDecoder;      type Operand = Operand;  } @@ -85,29 +77,6 @@ impl LengthedInstruction for Instruction {      }  } -#[derive(Debug, PartialEq)] -pub enum DecodeError { -    ExhaustedInput, -    InvalidOpcode, -    Incomplete, -} - -impl yaxpeax_arch::DecodeError for DecodeError { -    fn data_exhausted(&self) -> bool { self == &DecodeError::ExhaustedInput } -    fn bad_opcode(&self) -> bool { self == &DecodeError::InvalidOpcode } -    fn bad_operand(&self) -> bool { false } -} - -impl fmt::Display for DecodeError { -    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -        match self { -            DecodeError::ExhaustedInput => { write!(f, "exhausted input") } -            DecodeError::InvalidOpcode => { write!(f, "invalid opcode") } -            DecodeError::Incomplete => { write!(f, "incomplete") } -        } -    } -} -  impl yaxpeax_arch::Instruction for Instruction {      // only decode well-formed instructions (for now???)      fn well_defined(&self) -> bool { true } @@ -470,13 +439,9 @@ const UPPER_INSTRUCTIONS: [(Option<Opcode>, [OperandSpec; 2]); 64] = [      (Some(Opcode::RST), [OperandSpec::Imm(0x38), OperandSpec::Nothing]),  ]; -impl Decoder<Instruction> for InstDecoder { -    type Error = DecodeError; - -    fn decode_into<T: IntoIterator<Item=u8>>(&self, inst: &mut Instruction, bytes: T) -> Result<(), Self::Error> { -        let mut iter = bytes.into_iter(); - -        let opc: u8 = iter.next().ok_or(DecodeError::ExhaustedInput)?; +impl Decoder<SM83> for InstDecoder { +    fn decode_into<T: Reader<<SM83 as Arch>::Address, <SM83 as Arch>::Word>>(&self, inst: &mut Instruction, words: &mut T) -> Result<(), <SM83 as Arch>::DecodeError> { +        let opc: u8 = words.next()?;          inst.length = 1;          let high = ((opc >> 3) & 0b111) as usize; @@ -621,7 +586,7 @@ impl Decoder<Instruction> for InstDecoder {                  }              };              inst.opcode = opcode; -            interpret_operands(iter, inst, operands)?; +            interpret_operands(words, inst, operands)?;              return Ok(());          } else if opc < 0x80 {              if opc == 0x76 { @@ -630,7 +595,7 @@ impl Decoder<Instruction> for InstDecoder {                  return Ok(());              } else {                  inst.opcode = Opcode::LD; -                interpret_operands(iter, inst, [OPMAP[high], OPMAP[low]])?; +                interpret_operands(words, inst, [OPMAP[high], OPMAP[low]])?;                  return Ok(());              }          } else if opc < 0xc0 { @@ -646,12 +611,12 @@ impl Decoder<Instruction> for InstDecoder {              ];              inst.opcode = OPCODES[high];              let operands = [OPMAP[low], OperandSpec::Nothing]; -            interpret_operands(iter, inst, operands)?; +            interpret_operands(words, inst, operands)?;              return Ok(());          } else {              if opc == 0xcb {                  // sm83 special CB-prefixed instructions -                let opc: u8 = iter.next().ok_or(DecodeError::ExhaustedInput)?; +                let opc: u8 = words.next()?;                  inst.length += 1;                  if opc < 0x40 {                      let high = (opc >> 3) & 0b111; @@ -678,7 +643,7 @@ impl Decoder<Instruction> for InstDecoder {                          Opcode::SRL,                      ];                      inst.opcode = OPCODES[high as usize]; -                    interpret_operands(iter, inst, operands)?; +                    interpret_operands(words, inst, operands)?;                      return Ok(());                  } else {                      let bit = (opc >> 3) & 0b111; @@ -700,7 +665,7 @@ impl Decoder<Instruction> for InstDecoder {                          Opcode::SET,                      ];                      inst.opcode = OPCODES[(opc >> 6) as usize - 1]; -                    interpret_operands(iter, inst, operands)?; +                    interpret_operands(words, inst, operands)?;                      return Ok(());                  }              } else { @@ -708,23 +673,23 @@ impl Decoder<Instruction> for InstDecoder {                  let (maybe_opcode, operands) = UPPER_INSTRUCTIONS[opc as usize - 0xc0];                  if let Some(opcode) = maybe_opcode {                      inst.opcode = opcode; -                    interpret_operands(iter, inst, operands)?; +                    interpret_operands(words, inst, operands)?;                      return Ok(());                  } else { -                    return Err(DecodeError::InvalidOpcode); +                    return Err(StandardDecodeError::InvalidOpcode);                  }              }          }      }  } -fn interpret_operands<I: Iterator<Item=u8>>(mut iter: I, inst: &mut Instruction, operands: [OperandSpec; 2]) -> Result<(), DecodeError> { -    inst.operands[0] = interpret_operand(&mut iter, inst, operands[0])?; -    inst.operands[1] = interpret_operand(&mut iter, inst, operands[1])?; +fn interpret_operands<T: Reader<<SM83 as Arch>::Address, <SM83 as Arch>::Word>>(words: &mut T, inst: &mut Instruction, operands: [OperandSpec; 2]) -> Result<(), <SM83 as Arch>::DecodeError> { +    inst.operands[0] = interpret_operand(words, inst, operands[0])?; +    inst.operands[1] = interpret_operand(words, inst, operands[1])?;      Ok(())  } -fn interpret_operand<I: Iterator<Item=u8>>(iter: &mut I, inst: &mut Instruction, operand: OperandSpec) -> Result<Operand, DecodeError> { +fn interpret_operand<T: Reader<<SM83 as Arch>::Address, <SM83 as Arch>::Word>>(words: &mut T, inst: &mut Instruction, operand: OperandSpec) -> Result<Operand, <SM83 as Arch>::DecodeError> {      let operand = match operand {          OperandSpec::A => Operand::A,          OperandSpec::B => Operand::B, @@ -744,7 +709,7 @@ fn interpret_operand<I: Iterator<Item=u8>>(iter: &mut I, inst: &mut Instruction,          OperandSpec::DerefDecHL => Operand::DerefDecHL,          OperandSpec::DerefIncHL => Operand::DerefIncHL,          OperandSpec::D8 => { -            let imm = iter.next().ok_or(DecodeError::ExhaustedInput)?; +            let imm = words.next()?;              inst.length += 1;              Operand::D8(imm)          } @@ -752,36 +717,36 @@ fn interpret_operand<I: Iterator<Item=u8>>(iter: &mut I, inst: &mut Instruction,              Operand::DerefHighC          }          OperandSpec::DerefHighD8 => { -            let imm = iter.next().ok_or(DecodeError::ExhaustedInput)?; +            let imm = words.next()?;              inst.length += 1;              Operand::DerefHighD8(imm)          }          OperandSpec::R8 => { -            let imm = iter.next().ok_or(DecodeError::ExhaustedInput)?; +            let imm = words.next()?;              inst.length += 1;              Operand::R8(imm as i8)          }          OperandSpec::I8 => { -            let imm = iter.next().ok_or(DecodeError::ExhaustedInput)?; +            let imm = words.next()?;              inst.length += 1;              Operand::I8(imm as i8)          }          OperandSpec::A16 => {              let imm = -                 (iter.next().ok_or(DecodeError::ExhaustedInput)? as u16) | -                ((iter.next().ok_or(DecodeError::ExhaustedInput)? as u16) << 8); +                 (words.next()? as u16) | +                ((words.next()? as u16) << 8);              inst.length += 2;              Operand::A16(imm as u16)          }          OperandSpec::D16 => {              let imm = -                 (iter.next().ok_or(DecodeError::ExhaustedInput)? as u16) | -                ((iter.next().ok_or(DecodeError::ExhaustedInput)? as u16) << 8); +                 (words.next()? as u16) | +                ((words.next()? as u16) << 8);              inst.length += 2;              Operand::D16(imm as u16)          }          OperandSpec::SPWithOffset => { -            let imm = iter.next().ok_or(DecodeError::ExhaustedInput)?; +            let imm = words.next()?;              inst.length += 1;              Operand::SPWithOffset(imm as i8)          } diff --git a/test/test.rs b/test/test.rs index 856db45..613dc54 100644 --- a/test/test.rs +++ b/test/test.rs @@ -1,9 +1,6 @@  use std::fmt::Write; -extern crate yaxpeax_arch; -extern crate yaxpeax_sm83; - -use yaxpeax_arch::{AddressBase, Decoder, LengthedInstruction}; +use yaxpeax_arch::{AddressBase, Decoder, LengthedInstruction, U8Reader};  use yaxpeax_sm83::InstDecoder;  fn test_invalid(data: &[u8]) { @@ -11,7 +8,8 @@ fn test_invalid(data: &[u8]) {  }  fn test_invalid_under(decoder: &InstDecoder, data: &[u8]) { -    if let Ok(inst) = decoder.decode(data.into_iter().cloned()) { +    let mut reader = U8Reader::new(data); +    if let Ok(inst) = decoder.decode(&mut reader) {          panic!("decoded {:?} from {:02x?}", inst.opcode(), data);      } else {          // this is fine @@ -27,7 +25,8 @@ fn test_display_under(decoder: &InstDecoder, data: &[u8], expected: &'static str      for b in data {          write!(hex, "{:02x}", b).unwrap();      } -    match decoder.decode(data.into_iter().map(|x| *x)) { +    let mut reader = U8Reader::new(data); +    match decoder.decode(&mut reader) {          Ok(instr) => {              let text = format!("{}", instr);              assert!(  | 
