c64_assembler/memory/
address_mode.rs1use crate::{validator::AssemblerResult, Application};
2
3use super::{label::AddressReference, Address, ZeroPage};
4
5#[derive(Clone, Debug, Default, PartialEq)]
6pub enum AddressMode {
7 #[default]
8 Implied,
9 Accumulator,
10 Immediate(Immediate),
11 Absolute(AddressReference),
12 AbsoluteX(AddressReference),
13 AbsoluteY(AddressReference),
14 Relative(AddressReference),
15 Indirect(AddressReference),
16 IndexedIndirect(AddressReference),
17 IndirectIndexed(AddressReference),
18}
19
20fn is_zeropage(application: &Application, address_reference: &AddressReference) -> AssemblerResult<bool> {
21 Ok(application.lookup_address(&address_reference.name)?.is_zeropage())
22}
23
24impl AddressMode {
25 pub fn byte_size(&self, application: &Application) -> AssemblerResult<Address> {
29 match &self {
30 AddressMode::Implied | AddressMode::Accumulator => Ok(1),
31 AddressMode::Relative(_) | AddressMode::Immediate(_) => Ok(2),
32 AddressMode::Absolute(address_reference)
33 | AddressMode::AbsoluteX(address_reference)
34 | AddressMode::AbsoluteY(address_reference) => {
35 if is_zeropage(application, address_reference)? {
36 Ok(2)
37 } else {
38 Ok(3)
39 }
40 }
41 AddressMode::Indirect(_address_reference) => Ok(3),
42 AddressMode::IndexedIndirect(_address_reference) | AddressMode::IndirectIndexed(_address_reference) => {
43 Ok(2)
44 }
45 }
46 }
47}
48
49#[derive(Clone, Debug, PartialEq)]
50pub enum Immediate {
51 Byte(u8),
52 Low(AddressReference),
53 High(AddressReference),
54}