summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-03-20 03:14:43 -0700
committeriximeow <me@iximeow.net>2020-01-12 17:14:56 -0800
commit1da9ec09b3208aaf2e23ecd746bef3bc9076320b (patch)
tree2cdca857c48d88cd874c67b94ba3e9e34dc9f0bc
parent09435a4fdbeb97df837c0e9050dbaa7330c15b56 (diff)
update and impl new display-related triats
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs175
2 files changed, 175 insertions, 1 deletions
diff --git a/Cargo.toml b/Cargo.toml
index e1ecdf4..6885dee 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,7 @@ A rust pic17 decoder
[dependencies]
yaxpeax-arch = { path = "../../yaxpeax-arch" }
+"termion" = "1.4.0"
[[test]]
name = "test"
diff --git a/src/lib.rs b/src/lib.rs
index caa152d..1bc0c6f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,9 +1,12 @@
extern crate yaxpeax_arch;
+extern crate termion;
-use yaxpeax_arch::{Arch, Decodable, LengthedInstruction};
+use yaxpeax_arch::{Arch, ColorSettings, Colorize, Decodable, LengthedInstruction, ShowContextual};
use std::fmt::{Display, Formatter};
+use termion::color;
+
#[derive(Debug, Copy, Clone)]
pub struct Instruction {
pub opcode: Opcode,
@@ -452,3 +455,173 @@ impl Decodable for Instruction {
}
}
+pub fn opcode_color(opcode: Opcode) -> &'static color::Fg<&'static color::Color> {
+ match opcode {
+ Opcode::Invalid(_, _) => &color::Fg(&color::Red),
+ Opcode::NOP => &color::Fg(&color::Blue),
+ Opcode::CPFSLT |
+ Opcode::CPFSEQ |
+ Opcode::CPFSGT |
+ Opcode::TSTFSZ |
+ Opcode::BTFSS |
+ Opcode::BTFSC |
+ Opcode::RETLW |
+ Opcode::LCALL |
+ Opcode::GOTO |
+ Opcode::CALL |
+ Opcode::RETURN => &color::Fg(&color::Green),
+ Opcode::SLEEP |
+ Opcode::CLRWDT |
+ Opcode::RETFIE => &color::Fg(&color::Cyan),
+ Opcode::MOVWF |
+ Opcode::MOVFP |
+ Opcode::MOVPF |
+ Opcode::MOVLW |
+ Opcode::MOVLB |
+ Opcode::MOVLR => &color::Fg(&color::LightMagenta),
+ Opcode::BSF |
+ Opcode::BCF |
+ Opcode::IORWF |
+ Opcode::ANDWF |
+ Opcode::XORWF |
+ Opcode::IORLW |
+ Opcode::XORLW |
+ Opcode::ANDLW |
+ Opcode::CLRF |
+ Opcode::SETF |
+ Opcode::BTG |
+ Opcode::COMF |
+ Opcode::RRCF |
+ Opcode::RLCF |
+ Opcode::RRNCF |
+ Opcode::RLNCF |
+ Opcode::SWAPF => &color::Fg(&color::LightYellow),
+
+ Opcode::INFSNZ |
+ Opcode::DCFSNZ |
+ Opcode::DECFSZ |
+ Opcode::INCFSZ |
+ Opcode::SUBWFB |
+ Opcode::SUBWF |
+ Opcode::DECF |
+ Opcode::ADDWF |
+ Opcode::ADDWFC |
+ Opcode::INCF |
+ Opcode::MULWF |
+ Opcode::NEGW |
+ Opcode::DAW |
+ Opcode::ADDLW |
+ Opcode::SUBLW |
+ Opcode::MULLW => &color::Fg(&color::Yellow),
+
+ Opcode::TLRDL |
+ Opcode::TLRDH |
+ Opcode::TLWTL |
+ Opcode::TLWTH |
+ Opcode::TABLRDL |
+ Opcode::TABLRDLI |
+ Opcode::TABLRDH |
+ Opcode::TABLRDHI |
+ Opcode::TABLWTL |
+ Opcode::TABLWTLI |
+ Opcode::TABLWTH |
+ Opcode::TABLWTHI => &color::Fg(&color::Magenta),
+ }
+}
+
+impl <T: std::fmt::Write> Colorize<T> for Operand {
+ fn colorize(&self, colors: Option<&ColorSettings>, out: &mut T) -> std::fmt::Result {
+ match self {
+ Operand::ImmediateU8(i) => {
+ write!(out, "#{:02x}", i)
+ },
+ Operand::ImmediateU32(i) => {
+ write!(out, "#{:08x}", i)
+ },
+ Operand::File(f) => {
+ if *f < 0x10 {
+ write!(out, "{}0x{:02x}{}", color::Fg(color::Yellow), f, color::Fg(color::Reset))
+ } else {
+ write!(out, "{}[banked 0x{:02x}]{}", color::Fg(color::Yellow), f, color::Fg(color::Reset))
+ }
+ },
+ Operand::W => {
+ write!(out, "{}W{}", color::Fg(color::Yellow), color::Fg(color::Reset))
+ },
+ _ => {
+ Ok(())
+ }
+ }
+ }
+}
+
+impl <T: std::fmt::Write> ShowContextual<<PIC17 as Arch>::Address, [Option<String>], T> for Instruction {
+ fn contextualize(&self, colors: Option<&ColorSettings>, address: <PIC17 as Arch>::Address, context: Option<&[Option<String>]>, out: &mut T) -> std::fmt::Result {
+ write!(out, "{}{}{}", opcode_color(self.opcode), self.opcode, color::Fg(color::Reset))?;
+
+ match self.opcode {
+ Opcode::LCALL => {
+ write!(out, " ")?;
+ match context.and_then(|c| c.get(0)) {
+ Some(Some(text)) => {
+ write!(out, "{}", text)
+ },
+ _ => {
+ match self.operands[0] {
+ Operand::ImmediateU8(i) => {
+ write!(out, "+#{:08x}", (i as u16) * 2)
+ }
+ _ => { unreachable!(); }
+ }
+ }
+ }
+ },
+ Opcode::CALL |
+ Opcode::GOTO => {
+ match context.and_then(|c| c.get(0)) {
+ Some(Some(text)) => { write!(out, "{}", text) }
+ _ => {
+ match self.operands[0] {
+ Operand::ImmediateU32(i) => {
+ write!(out, " #{:08x}", (i as u16) * 2)
+ },
+ _ => { unreachable!() }
+ }
+ }
+ }
+ },
+ _ => {
+ match context.and_then(|c| c.get(0)) {
+ Some(Some(text)) => { write!(out, " {}", text)?; },
+ _ => {
+ match &self.operands[0] {
+ Operand::Nothing => {
+ return Ok(());
+ },
+ x @ _ => {
+ write!(out, " ")?;
+ x.colorize(colors, out)?;
+ }
+ };
+ }
+ };
+
+ match context.and_then(|c| c.get(1)) {
+ Some(Some(text)) => { write!(out, ", {}", text)?; },
+ _ => {
+ match &self.operands[1] {
+ Operand::Nothing => {
+ return Ok(());
+ },
+ x @ _ => {
+ write!(out, ", ")?;
+ x.colorize(colors, out)?;
+ }
+ };
+ }
+ };
+ Ok(())
+ }
+ }
+ }
+}