diff options
author | Determinant <ted.sybil@gmail.com> | 2017-11-17 15:00:24 -0500 |
---|---|---|
committer | Determinant <ted.sybil@gmail.com> | 2017-11-17 15:00:24 -0500 |
commit | 2f4262c1273108abfcce00e897c520f5a7f4be41 (patch) | |
tree | 0915021d63092913de7cc88fe39088f936a4126d /src/disasm.rs | |
parent | e2ccf6053d58a2a478814f4a26018989f6fa0f26 (diff) |
rearrange the proj
Diffstat (limited to 'src/disasm.rs')
-rw-r--r-- | src/disasm.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/disasm.rs b/src/disasm.rs new file mode 100644 index 0000000..c9b3696 --- /dev/null +++ b/src/disasm.rs @@ -0,0 +1,97 @@ +use mos6502::{make_optable, make_addrtable}; + +mod disops { + make_optable!(OPS, &str); + ids2strs!(adc, and, asl, bcc, bcs, beq, bit, bmi, + bne, bpl, brk, bvc, bvs, clc, cld, cli, + clv, cmp, cpx, cpy, dec, dex, dey, eor, + inc, inx, iny, jmp, jsr, lda, ldx, ldy, + lsr, nop, ora, pha, php, pla, plp, rol, + ror, rti, rts, sbc, sec, sed, sei, sta, + stx, sty, tax, tay, tsx, txa, txs, tya, nil); +} + +mod disaddr { + pub type T<'a, 'b> = &'a mut Iterator<Item=&'b u8>; + make_addrtable!(ADDR_MODES, fn (T) -> String); + fn acc(_code: T) -> String { + "a".to_string() + } + fn imm(code: T) -> String { + format!("#${:02x}", code.next().unwrap()) + } + fn zpg(code: T) -> String { + format!("${:02x}", code.next().unwrap()) + } + fn zpx(code: T) -> String { + format!("${:02x}, x", code.next().unwrap()) + } + fn zpy(code: T) -> String { + format!("${:02x}, y", code.next().unwrap()) + } + fn rel(code: T) -> String { + let b = *code.next().unwrap() as i8 as i16; + if b >= 0 { + format!("+${:02x}, x", b) + } else { + format!("-${:02x}, x", -b) + } + } + fn abs(code: T) -> String { + let low = *code.next().unwrap() as u16; + let high = *code.next().unwrap() as u16; + format!("${:04x}", (high << 8) | low) + } + fn abx(code: T) -> String { + let low = *code.next().unwrap() as u16; + let high = *code.next().unwrap() as u16; + format!("${:04x}, x", (high << 8) | low) + } + fn aby(code: T) -> String { + let low = *code.next().unwrap() as u16; + let high = *code.next().unwrap() as u16; + format!("${:04x}, y", (high << 8) | low) + } + fn ind(code: T) -> String { + let low = *code.next().unwrap() as u16; + let high = *code.next().unwrap() as u16; + format!("(${:04x})", (high << 8) | low) + } + fn xin(code: T) -> String { + format!("(${:02x}, x)", code.next().unwrap()) + } + fn iny(code: T) -> String { + format!("(${:02x}), y", code.next().unwrap()) + } + fn nil(_code: T) -> String { + "".to_string() + } +} + +pub struct Disassembler<'a, T> where T: Iterator<Item=&'a u8> { + raw_code: T +} + +impl<'a, T> Disassembler<'a, T> where T: Iterator<Item=&'a u8> { + pub fn new(raw_code: T) -> Self { + Disassembler{raw_code} + } + fn parse(opcode: u8, code: &mut T) -> String { + format!("{} {}", disops::OPS[opcode as usize], + disaddr::ADDR_MODES[opcode as usize](code)) + } +} + +impl<'a, T> Iterator for Disassembler<'a, T> where T: Iterator<Item=&'a u8> { + type Item = String; + fn next(&mut self) -> Option<Self::Item> { + match self.raw_code.next() { + Some(opcode) => Some(Disassembler::parse(*opcode, &mut self.raw_code)), + None => None + } + } +} + +pub fn parse(opcode: u8, code: &[u8]) -> String { + Disassembler::parse(opcode, &mut code.iter()) +} |