codegen_instruction_test/
codegen_instruction_test.rs

1use c64_assembler_6502::{
2    isa_6502,
3    opcodes::{
4        NO_ABSOLUTE, NO_ABSOLUTE_X, NO_ABSOLUTE_Y, NO_ACCUMULATOR, NO_IMMEDIATE, NO_IMPLIED, NO_INDIRECT, NO_RELATIVE,
5        NO_ZEROPAGE, NO_ZEROPAGE_X, NO_ZEROPAGE_Y,
6    },
7};
8
9fn main() {
10    let mut lines = Vec::<String>::default();
11
12    for def in isa_6502() {
13        if def.implied != NO_IMPLIED {
14            lines.push(format!(
15                "
16                #[test]
17                fn {0}() {{
18                    test_first(instructions!({0}), Operation::{1}, AddressMode::Implied);
19                }}
20                ",
21                def.instruction.to_string(),
22                def.instruction.to_uppercase()
23            ));
24            continue;
25        }
26        lines.push(format!(
27            "
28            mod {0} {{
29                use c64_assembler::{{
30                    instruction::operation::Operation,
31                    memory::{{address_mode::*, label::AddressReference}},
32        }};
33                use c64_assembler_macro::instructions;
34
35                use crate::test_first;
36                const OP: Operation = Operation::{1};
37            ",
38            def.instruction,
39            def.instruction.to_string().to_uppercase()
40        ));
41
42        if def.immediate != NO_IMMEDIATE {
43            lines.push(format!(
44                "
45                #[test]
46                fn imm() {{
47                    test_first(
48                        instructions!({0} #99),
49                        OP,
50                        AddressMode::Immediate(Immediate::Byte(99)),
51                    );
52                    test_first(
53                        instructions!({0} #$99),
54                        OP,
55                        AddressMode::Immediate(Immediate::Byte(153)),
56                    )
57                }}
58
59                #[test]
60                fn imm_low() {{
61                    test_first(
62                        instructions!({0} #<test),
63                        OP,
64                        AddressMode::Immediate(Immediate::Low(AddressReference::new(\"test\"))),
65                    );
66                }}
67
68                #[test]
69                fn imm_high() {{
70                    test_first(
71                        instructions!({0} #>test),
72                        OP,
73                        AddressMode::Immediate(Immediate::High(AddressReference::new(\"test\"))),
74                    );
75                }}
76                ",
77                def.instruction.to_string()
78            ));
79        }
80
81        if def.accumulator != NO_ACCUMULATOR {
82            lines.push(format!(
83                "
84                #[test]
85                fn acc() {{
86                    test_first(
87                        instructions!({0} a),
88                        OP,
89                        AddressMode::Accumulator,
90                    );
91                }}
92                ",
93                def.instruction
94            ));
95        }
96
97        if def.absolute != NO_ABSOLUTE || def.zeropage != NO_ZEROPAGE {
98            lines.push(format!(
99                "
100                #[test]
101                fn addr() {{
102                    test_first(
103                        instructions!({0} test),
104                        OP,
105                        AddressMode::Absolute(AddressReference::new(\"test\")),
106                    );
107                }}
108
109                #[test]
110                fn addr_offs() {{
111                    test_first(
112                        instructions!({0} test+1),
113                        OP,
114                        AddressMode::Absolute(AddressReference::with_offset(\"test\", 1)),
115                    );
116                }}
117                ",
118                def.instruction.to_string()
119            ));
120        }
121        if def.relative != NO_RELATIVE {
122            lines.push(format!(
123                "
124                #[test]
125                fn addr() {{
126                    test_first(
127                        instructions!({0} test),
128                        OP,
129                        AddressMode::Relative(AddressReference::new(\"test\")),
130                    );
131                }}
132
133                #[test]
134                fn addr_offs() {{
135                    test_first(
136                        instructions!({0} test+1),
137                        OP,
138                        AddressMode::Relative(AddressReference::with_offset(\"test\", 1)),
139                    );
140                }}
141                ",
142                def.instruction.to_string()
143            ));
144        }
145
146        if def.absolute_x != NO_ABSOLUTE_X || def.zeropage_x != NO_ZEROPAGE_X {
147            lines.push(format!(
148                "
149                #[test]
150                fn addr_x() {{
151                    test_first(
152                        instructions!({0} test,x),
153                        OP,
154                        AddressMode::AbsoluteX(AddressReference::new(\"test\")),
155                    );
156                }}
157                ",
158                def.instruction
159            ));
160        }
161        if def.absolute_y != NO_ABSOLUTE_Y || def.zeropage_y != NO_ZEROPAGE_Y {
162            lines.push(format!(
163                "
164                #[test]
165                fn addr_y() {{
166                    test_first(
167                        instructions!({0} test,y),
168                        OP,
169                        AddressMode::AbsoluteY(AddressReference::new(\"test\")),
170                    );
171                }}
172                ",
173                def.instruction
174            ));
175        }
176
177        if def.indirect != NO_INDIRECT {
178            lines.push(format!(
179                "
180                #[test]
181                fn ind() {{
182                    test_first(
183                        instructions!({0} (test)),
184                        OP,
185                        AddressMode::Indirect(AddressReference::new(\"test\")),
186                        );
187                        }}
188                        ",
189                def.instruction.to_string()
190            ));
191        }
192        if def.indexed_indirect != NO_INDIRECT {
193            lines.push(format!(
194                "
195                #[test]
196                fn ind_x() {{
197                    test_first(
198                        instructions!({0} (test,x)),
199                        OP,
200                        AddressMode::IndexedIndirect(AddressReference::new(\"test\")),
201                    );
202                }}
203                ",
204                def.instruction.to_string()
205            ));
206        }
207        if def.indirect_indexed != NO_INDIRECT {
208            lines.push(format!(
209                "
210                #[test]
211                fn ind_y() {{
212                    test_first(
213                        instructions!({0} (test),y),
214                        OP,
215                        AddressMode::IndirectIndexed(AddressReference::new(\"test\")),
216                    );
217                }}
218                ",
219                def.instruction.to_string()
220            ));
221        }
222
223        // Close module
224        lines.push(
225            "
226            }
227            "
228            .to_string(),
229        );
230    }
231
232    print!("{}", lines.join("\n"));
233}