Fix PC displacement being treated as unsigned
This commit is contained in:
parent
70f5905e67
commit
bf21b98498
@ -889,7 +889,10 @@ impl<T> Disasm<'_, T> {
|
|||||||
match misc_mode {
|
match misc_mode {
|
||||||
MiscMode::PcDisplacement => {
|
MiscMode::PcDisplacement => {
|
||||||
let pc = self.pc;
|
let pc = self.pc;
|
||||||
Ok(EffectiveAddress::PcDisplacement(pc, self.read_prog_word()?))
|
Ok(EffectiveAddress::PcDisplacement(
|
||||||
|
pc,
|
||||||
|
self.read_prog_word()? as i16,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
MiscMode::PcIndex => {
|
MiscMode::PcIndex => {
|
||||||
let pc = self.pc;
|
let pc = self.pc;
|
||||||
|
@ -43,7 +43,7 @@ pub enum EffectiveAddress {
|
|||||||
idx: RegisterEffective,
|
idx: RegisterEffective,
|
||||||
idx_size: Size,
|
idx_size: Size,
|
||||||
},
|
},
|
||||||
PcDisplacement(u32, u16),
|
PcDisplacement(u32, i16),
|
||||||
PcIndex(u32, u8, RegisterEffective, Size),
|
PcIndex(u32, u8, RegisterEffective, Size),
|
||||||
AbsoluteShort(u16),
|
AbsoluteShort(u16),
|
||||||
AbsoluteLong(u32),
|
AbsoluteLong(u32),
|
||||||
|
36
src/m68k.rs
36
src/m68k.rs
@ -1381,7 +1381,11 @@ impl M68K {
|
|||||||
self.read_address(address, size)
|
self.read_address(address, size)
|
||||||
}
|
}
|
||||||
EffectiveAddress::PcDisplacement(pc, d) => {
|
EffectiveAddress::PcDisplacement(pc, d) => {
|
||||||
let address = pc.wrapping_add(d.into());
|
let address = if d > 0 {
|
||||||
|
pc.wrapping_add((d as u16).into())
|
||||||
|
} else {
|
||||||
|
pc.wrapping_sub((-d as u16).into())
|
||||||
|
};
|
||||||
self.read_address(address, size)
|
self.read_address(address, size)
|
||||||
}
|
}
|
||||||
EffectiveAddress::PcIndex(pc, displacement, idx, idx_size) => {
|
EffectiveAddress::PcIndex(pc, displacement, idx, idx_size) => {
|
||||||
@ -1518,10 +1522,13 @@ impl M68K {
|
|||||||
self.store_mem_cycles = true;
|
self.store_mem_cycles = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let result = self.bus.read_byte(address, self.is_supervisor()).map_err(|_| DetailedBusError {
|
let result = self
|
||||||
address,
|
.bus
|
||||||
cause: BusErrorCause::ReadingByte,
|
.read_byte(address, self.is_supervisor())
|
||||||
});
|
.map_err(|_| DetailedBusError {
|
||||||
|
address,
|
||||||
|
cause: BusErrorCause::ReadingByte,
|
||||||
|
});
|
||||||
if self.store_mem_cycles {
|
if self.store_mem_cycles {
|
||||||
self.stored_mem_cycles
|
self.stored_mem_cycles
|
||||||
.push(MemCycleInfo::ReadByte { address, result });
|
.push(MemCycleInfo::ReadByte { address, result });
|
||||||
@ -1588,10 +1595,13 @@ impl M68K {
|
|||||||
self.store_mem_cycles = true;
|
self.store_mem_cycles = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let result = self.bus.read_word(address, self.is_supervisor()).map_err(|_| DetailedBusError {
|
let result = self
|
||||||
address,
|
.bus
|
||||||
cause: BusErrorCause::ReadingWord,
|
.read_word(address, self.is_supervisor())
|
||||||
});
|
.map_err(|_| DetailedBusError {
|
||||||
|
address,
|
||||||
|
cause: BusErrorCause::ReadingWord,
|
||||||
|
});
|
||||||
if self.store_mem_cycles {
|
if self.store_mem_cycles {
|
||||||
self.stored_mem_cycles
|
self.stored_mem_cycles
|
||||||
.push(MemCycleInfo::ReadWord { address, result });
|
.push(MemCycleInfo::ReadWord { address, result });
|
||||||
@ -1674,7 +1684,13 @@ impl M68K {
|
|||||||
.wrapping_sub((-d as u16).into()))
|
.wrapping_sub((-d as u16).into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EffectiveAddress::PcDisplacement(pc, d) => Ok(pc.wrapping_add(d.into())),
|
EffectiveAddress::PcDisplacement(pc, d) => {
|
||||||
|
if d > 0 {
|
||||||
|
Ok(pc.wrapping_add((d as u16).into()))
|
||||||
|
} else {
|
||||||
|
Ok(pc.wrapping_sub((-d as u16).into()))
|
||||||
|
}
|
||||||
|
},
|
||||||
EffectiveAddress::AbsoluteShort(x) => Ok(u32::from(x)),
|
EffectiveAddress::AbsoluteShort(x) => Ok(u32::from(x)),
|
||||||
EffectiveAddress::AbsoluteLong(x) => Ok(x),
|
EffectiveAddress::AbsoluteLong(x) => Ok(x),
|
||||||
EffectiveAddress::DataReg(_)
|
EffectiveAddress::DataReg(_)
|
||||||
|
@ -40,14 +40,13 @@ impl Symbol {
|
|||||||
impl Display for Symbol {
|
impl Display for Symbol {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
if self.size == 0 {
|
if self.size == 0 {
|
||||||
f.write_fmt(format_args!(
|
f.write_fmt(format_args!("{:#010x} ({})", self.value, self.sect_name))
|
||||||
"{:#010x} ({})",
|
|
||||||
self.value, self.sect_name
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
f.write_fmt(format_args!(
|
f.write_fmt(format_args!(
|
||||||
"{:#010x}..{:#010x} ({})",
|
"{:#010x}..{:#010x} ({})",
|
||||||
self.value, self.value+self.size, self.sect_name
|
self.value,
|
||||||
|
self.value + self.size,
|
||||||
|
self.sect_name
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,10 @@ impl SymbolTable {
|
|||||||
let mut file = ElfStream::<AnyEndian, _>::open_stream(File::open(path)?)?;
|
let mut file = ElfStream::<AnyEndian, _>::open_stream(File::open(path)?)?;
|
||||||
let (sect_headers, shstrtab) = file.section_headers_with_strtab()?;
|
let (sect_headers, shstrtab) = file.section_headers_with_strtab()?;
|
||||||
let shstrtab = shstrtab.unwrap();
|
let shstrtab = shstrtab.unwrap();
|
||||||
let sect_names = sect_headers.iter().map(|sect| shstrtab.get(sect.sh_name as usize).unwrap().to_string()).collect::<Vec<_>>();
|
let sect_names = sect_headers
|
||||||
|
.iter()
|
||||||
|
.map(|sect| shstrtab.get(sect.sh_name as usize).unwrap().to_string())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let (symtab, symstrtab) = file
|
let (symtab, symstrtab) = file
|
||||||
.symbol_table()?
|
.symbol_table()?
|
||||||
.ok_or_else(|| anyhow!("No symbol table in {}", path))?;
|
.ok_or_else(|| anyhow!("No symbol table in {}", path))?;
|
||||||
@ -73,7 +76,12 @@ impl SymbolTable {
|
|||||||
.map(|sym| {
|
.map(|sym| {
|
||||||
(
|
(
|
||||||
symstrtab.get(sym.st_name as usize).unwrap().to_string(),
|
symstrtab.get(sym.st_name as usize).unwrap().to_string(),
|
||||||
Symbol::new(&sym, sect_names.get(sym.st_shndx as usize).map_or_else(|| "UNKNOWN".to_string(), |x| x.to_string())),
|
Symbol::new(
|
||||||
|
&sym,
|
||||||
|
sect_names
|
||||||
|
.get(sym.st_shndx as usize)
|
||||||
|
.map_or_else(|| "UNKNOWN".to_string(), |x| x.to_string()),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<HashMap<_, _>>();
|
.collect::<HashMap<_, _>>();
|
||||||
|
Loading…
Reference in New Issue
Block a user