machine_check_avr/
system.rs

1#[allow(non_snake_case)]
2#[allow(clippy::if_same_then_else)]
3#[machine_check::machine_description]
4pub mod machine_module {
5    use ::machine_check::{Bitvector, BitvectorArray, Ext, Signed, Unsigned};
6    use ::std::{
7        clone::Clone,
8        cmp::{Eq, PartialEq},
9        convert::Into,
10        fmt::Debug,
11        hash::Hash,
12        panic, unimplemented,
13    };
14
15    /// ATmega328P system input.
16    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
17    pub struct Input {
18        // --- Uninitialized Registers and Memory ---
19        /// Uninitialized general-purpose working registers.
20        pub uninit_R: BitvectorArray<5, 8>,
21        /// Uninitialized SRAM.
22        pub uninit_SRAM: BitvectorArray<11, 8>,
23
24        // --- General Purpose I/O ---
25        /// I/O address 0x3: pin read.
26        pub PINB: Bitvector<8>,
27
28        /// I/O address 0x6: pin read.
29        ///
30        /// Only low 7 bits are read, the high bit is always zero.
31        pub PINC: Bitvector<7>,
32
33        /// I/O address 0x9: pin read.
34        pub PIND: Bitvector<8>,
35    }
36
37    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
38    pub struct Param {}
39
40    /// ATmega328P system state.
41    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
42    pub struct State {
43        // --- Program Counter ---
44        /// Program counter.
45        pub PC: Bitvector<14>,
46
47        // --- Working Registers ---
48        // Data addresses 0x00..0x20
49        /// General-purpose working registers.
50        ///
51        /// 32 (2<sup>5</sup>) 8-bit registers.
52        pub R: BitvectorArray<5, 8>,
53
54        // --- I/O Registers ---
55        // 64 addresses, only some are true registers
56        // Data addresses 0x20..0x40
57
58        // Port B
59        // I/O address 0x3: reads pins, write XORs output/pullup register.
60        // ---
61        /// I/O address 0x4: data direction register.
62        pub DDRB: Bitvector<8>,
63        /// I/O address 0x5: output/pullup register.
64        pub PORTB: Bitvector<8>,
65
66        // Port C: lacks the highest bit
67        // I/O address 0x6: reads pins, write XORs output/pullup register.
68        // ---
69        /// I/O address 0x7: data direction register.
70        pub DDRC: Bitvector<7>,
71        /// I/O address 0x8: output/pullup register.
72        pub PORTC: Bitvector<7>,
73
74        // Port D
75        // I/O address 0x9: reads pins, write XORs output/pullup register.
76        // ---
77        /// I/O address 0xA: data direction register.
78        pub DDRD: Bitvector<8>,
79        /// I/O address 0xB: output/pullup register.
80        pub PORTD: Bitvector<8>,
81
82        // General Purpose I/O registers
83        /// I/O address 0x1E: General Purpose I/O register 0.
84        pub GPIOR0: Bitvector<8>,
85        /// I/O address 0x2A: General Purpose I/O register 1.
86        pub GPIOR1: Bitvector<8>,
87        /// I/O address 0x2B: General Purpose I/O register 2.
88        pub GPIOR2: Bitvector<8>,
89
90        /// I/O address 0x3D: Stack Pointer Low.
91        pub SPL: Bitvector<8>,
92
93        /// I/O address 0x3E: Stack Pointer High.
94        pub SPH: Bitvector<8>,
95
96        /// I/O address 0x3F: Status Register.
97        pub SREG: Bitvector<8>,
98
99        // TODO: other I/O registers
100
101        // --- Extended I/O Registers ---
102        // TODO: extended I/O registers
103
104        // --- SRAM ---
105        /// Static RAM.
106        ///
107        /// Contains 2K (2<sup>11</sup>) 8-bit cells.
108        pub SRAM: BitvectorArray<11, 8>,
109        // --- EEPROM ---
110        // unchangeable as SPM instruction is not supported
111    }
112
113    /// ATmega328P system.
114    ///
115    /// Program memory is treated as unchanging as the SPM instruction is not implemented.
116    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
117    pub struct ATmega328P {
118        /// Program memory.
119        ///
120        /// ATmega328P program memory is 32 KB, i.e. 16K (2<sup>14</sup>) 16-bit words.
121        pub PROGMEM: BitvectorArray<14, 16>,
122    }
123
124    impl ATmega328P {
125        fn instruction_skip(&self, pc: Bitvector<14>) -> Bitvector<14> {
126            // PC is already incremented to point to the next instruction
127            let mut result_pc = pc;
128            let instruction = self.PROGMEM[result_pc];
129            ::machine_check::bitmask_switch!(instruction {
130                // LDS or STS (two-word)
131                // STS (two-word)
132                "1001_00-d_dddd_0000" => {
133                    result_pc = result_pc + Bitvector::<14>::new(2);
134                }
135                // JMP
136                "1001_010k_kkkk_110k" => {
137                    result_pc = result_pc + Bitvector::<14>::new(2);
138                }
139                // CALL
140                "1001_010k_kkkk_111k" => {
141                    result_pc = result_pc + Bitvector::<14>::new(2);
142                }
143                // otherwise, we are skipping a one-word instruction
144                _ => {
145                    result_pc = result_pc + Bitvector::<14>::new(1);
146                }
147            });
148            result_pc
149        }
150
151        #[allow(unreachable_code)]
152        fn read_io_reg(state: &State, input: &Input, io_index: Bitvector<6>) -> Bitvector<8> {
153            let result;
154            if io_index == Bitvector::<6>::new(0x03) {
155                result = input.PINB;
156            } else if io_index == Bitvector::<6>::new(0x04) {
157                result = state.DDRB;
158            } else if io_index == Bitvector::<6>::new(0x05) {
159                result = state.PORTB;
160            } else if io_index == Bitvector::<6>::new(0x06) {
161                // port C has only 7 bits, zero-extend
162                result = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<7>>::into(
163                    input.PINC,
164                )));
165            } else if io_index == Bitvector::<6>::new(0x07) {
166                // port C has only 7 bits, zero-extend
167                result = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<7>>::into(
168                    state.DDRC,
169                )));
170            } else if io_index == Bitvector::<6>::new(0x08) {
171                // port C has only 7 bits, zero-extend
172                result = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<7>>::into(
173                    state.PORTC,
174                )));
175            } else if io_index == Bitvector::<6>::new(0x09) {
176                result = input.PIND;
177            } else if io_index == Bitvector::<6>::new(0x0A) {
178                result = state.DDRD;
179            } else if io_index == Bitvector::<6>::new(0x0B) {
180                result = state.PORTD;
181            } else if io_index == Bitvector::<6>::new(0x1E) {
182                result = state.GPIOR0;
183            } else if io_index == Bitvector::<6>::new(0x2A) {
184                result = state.GPIOR1;
185            } else if io_index == Bitvector::<6>::new(0x2B) {
186                result = state.GPIOR2;
187            } else if io_index == Bitvector::<6>::new(0x3D) {
188                result = state.SPL;
189            } else if io_index == Bitvector::<6>::new(0x3E) {
190                result = state.SPH;
191            } else if io_index == Bitvector::<6>::new(0x3F) {
192                result = state.SREG;
193            } else {
194                panic!("Unimplemented or invalid read from I/O register");
195                // TODO: discover that panic diverges and no assignment is necessary
196                result = Bitvector::<8>::new(0);
197            }
198
199            result
200        }
201
202        fn write_io_reg(state: &State, io_index: Bitvector<6>, value: Bitvector<8>) -> State {
203            let PC = state.PC;
204            let R = Clone::clone(&state.R);
205            let mut DDRB = state.DDRB;
206            let mut PORTB = state.PORTB;
207            let mut DDRC = state.DDRC;
208            let mut PORTC = state.PORTC;
209            let mut DDRD = state.DDRD;
210            let mut PORTD = state.PORTD;
211            let mut GPIOR0 = state.GPIOR0;
212            let mut GPIOR1 = state.GPIOR1;
213            let mut GPIOR2 = state.GPIOR2;
214            let mut SPL = state.SPL;
215            let mut SPH = state.SPH;
216            let mut SREG = state.SREG;
217            let SRAM = Clone::clone(&state.SRAM);
218
219            if io_index == Bitvector::<6>::new(0x03) {
220                // instead of writing to PINB, exclusive-or PORTB
221                PORTB = PORTB ^ value;
222            } else if io_index == Bitvector::<6>::new(0x04) {
223                DDRB = value;
224            } else if io_index == Bitvector::<6>::new(0x05) {
225                PORTB = value;
226            } else if (io_index == Bitvector::<6>::new(0x06))
227                | (io_index == Bitvector::<6>::new(0x07))
228                | (io_index == Bitvector::<6>::new(0x08))
229            {
230                // port C has only 7 bits
231                // ensure written bit 8 is zero
232                let bit_8_mask = Bitvector::<8>::new(0b1000_0000);
233                let bit_8_masked = value & bit_8_mask;
234                if bit_8_masked != Bitvector::<8>::new(0) {
235                    panic!("Port C bit 8 should not have 1 written to it");
236                };
237                //  drop bit 8
238                let value_ext =
239                    Into::<Bitvector<7>>::into(Ext::<7>::ext(Into::<Unsigned<8>>::into(value)));
240                if io_index == Bitvector::<6>::new(0x06) {
241                    // instead of writing to PINC, exclusive-or PORTC
242                    PORTC = PORTC ^ value_ext;
243                } else if io_index == Bitvector::<6>::new(0x07) {
244                    DDRC = value_ext;
245                } else if io_index == Bitvector::<6>::new(0x08) {
246                    PORTC = value_ext;
247                };
248            } else if io_index == Bitvector::<6>::new(0x09) {
249                // instead of writing to PIND, exclusive-or PORTD
250                PORTD = PORTD ^ value;
251            } else if io_index == Bitvector::<6>::new(0x0A) {
252                DDRD = value;
253            } else if io_index == Bitvector::<6>::new(0x0B) {
254                PORTD = value;
255            } else if io_index == Bitvector::<6>::new(0x1E) {
256                GPIOR0 = value;
257            } else if io_index == Bitvector::<6>::new(0x2A) {
258                GPIOR1 = value;
259            } else if io_index == Bitvector::<6>::new(0x2B) {
260                GPIOR2 = value;
261            } else if io_index == Bitvector::<6>::new(0x3D) {
262                SPL = value;
263            } else if io_index == Bitvector::<6>::new(0x3E) {
264                SPH = value;
265            } else if io_index == Bitvector::<6>::new(0x3F) {
266                SREG = value;
267            } else {
268                panic!("Unimplemented or invalid write to I/O register");
269            }
270
271            State {
272                PC,
273                R,
274                DDRB,
275                PORTB,
276                DDRC,
277                PORTC,
278                DDRD,
279                PORTD,
280                GPIOR0,
281                GPIOR1,
282                GPIOR2,
283                SPL,
284                SPH,
285                SREG,
286                SRAM,
287            }
288        }
289
290        #[allow(unreachable_code)]
291        fn read_data_mem(state: &State, input: &Input, data_index: Bitvector<16>) -> Bitvector<8> {
292            let unsigned_data_index = Into::<Unsigned<16>>::into(data_index);
293            let result;
294            if unsigned_data_index < Unsigned::<16>::new(0x0020) {
295                // working registers
296                let reg_index = Into::<Bitvector<5>>::into(Ext::<5>::ext(unsigned_data_index));
297                result = state.R[reg_index];
298            } else if unsigned_data_index < Unsigned::<16>::new(0x0060) {
299                // I/O registers
300                let io_reg_index = Into::<Bitvector<6>>::into(Ext::<6>::ext(
301                    unsigned_data_index - Unsigned::<16>::new(0x0020),
302                ));
303                result = Self::read_io_reg(state, input, io_reg_index);
304            } else if unsigned_data_index < Unsigned::<16>::new(0x100) {
305                // extended I/O registers, none implemented yet
306                panic!("Unimplemented or invalid read from extended I/O register");
307                // TODO: discover that panic diverges and no assignment is necessary
308                result = Bitvector::<8>::new(0);
309            } else {
310                let sram_full_index = unsigned_data_index - Unsigned::<16>::new(0x0100);
311                let sram_index = Ext::<11>::ext(sram_full_index);
312                if sram_full_index == Ext::<16>::ext(sram_index) {
313                    // inside SRAM
314                    result = state.SRAM[Into::<Bitvector<11>>::into(sram_index)];
315                } else {
316                    // outside SRAM
317                    panic!("Illegal read after data memory end");
318                    // TODO: discover that panic diverges and no assignment is necessary
319                    result = Bitvector::<8>::new(0);
320                };
321            }
322            result
323        }
324
325        #[allow(unreachable_code)]
326        fn write_data_mem(state: &State, data_index: Bitvector<16>, value: Bitvector<8>) -> State {
327            let PC = state.PC;
328            let DDRB = state.DDRB;
329            let PORTB = state.PORTB;
330            let DDRC = state.DDRC;
331            let PORTC = state.PORTC;
332            let DDRD = state.DDRD;
333            let PORTD = state.PORTD;
334            let GPIOR0 = state.GPIOR0;
335            let GPIOR1 = state.GPIOR1;
336            let GPIOR2 = state.GPIOR2;
337            let SPL = state.SPL;
338            let SPH = state.SPH;
339            let SREG = state.SREG;
340
341            let result;
342            let unsigned_data_index = Into::<Unsigned<16>>::into(data_index);
343            if unsigned_data_index < Unsigned::<16>::new(0x0020) {
344                // working registers
345                let reg_index = Into::<Bitvector<5>>::into(Ext::<5>::ext(unsigned_data_index));
346
347                let mut R = Clone::clone(&state.R);
348                let SRAM = Clone::clone(&state.SRAM);
349                R[reg_index] = value;
350
351                result = State {
352                    PC,
353                    R,
354                    DDRB,
355                    PORTB,
356                    DDRC,
357                    PORTC,
358                    DDRD,
359                    PORTD,
360                    GPIOR0,
361                    GPIOR1,
362                    GPIOR2,
363                    SPL,
364                    SPH,
365                    SREG,
366                    SRAM,
367                };
368            } else if unsigned_data_index < Unsigned::<16>::new(0x0060) {
369                // I/O registers
370                let io_reg_index = Into::<Bitvector<6>>::into(Ext::<6>::ext(
371                    unsigned_data_index - Unsigned::<16>::new(0x0020),
372                ));
373                result = Self::write_io_reg(state, io_reg_index, value);
374            } else if unsigned_data_index < Unsigned::<16>::new(0x100) {
375                // extended I/O registers, none implemented yet
376                panic!("Unimplemented or invalid read from extended I/O register");
377                // TODO: discover that panic diverges and no assignment is necessary
378                result = Clone::clone(state);
379            } else {
380                let sram_full_index = unsigned_data_index - Unsigned::<16>::new(0x0100);
381                let sram_index = Ext::<11>::ext(sram_full_index);
382                if sram_full_index != Ext::<16>::ext(sram_index) {
383                    // outside SRAM
384                    panic!("Illegal write after data memory end");
385                }
386                // inside SRAM
387                let R = Clone::clone(&state.R);
388                let mut SRAM = Clone::clone(&state.SRAM);
389                SRAM[Into::<Bitvector<11>>::into(sram_index)] = value;
390
391                result = State {
392                    PC,
393                    R,
394                    DDRB,
395                    PORTB,
396                    DDRC,
397                    PORTC,
398                    DDRD,
399                    PORTD,
400                    GPIOR0,
401                    GPIOR1,
402                    GPIOR2,
403                    SPL,
404                    SPH,
405                    SREG,
406                    SRAM,
407                };
408            }
409            result
410        }
411
412        // for instructions AND, EOR, OR
413        // Ru: destination register after being set
414        fn compute_status_logical(sreg: Bitvector<8>, Ru: Bitvector<8>) -> Bitvector<8> {
415            let retained_flags = Unsigned::<8>::new(0b1110_0001);
416            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
417
418            let Ru_unsigned = Into::<Unsigned<8>>::into(Ru);
419
420            let Ru7 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(7));
421
422            // Z - zero flag, bit 1
423            if Ru == Bitvector::<8>::new(0) {
424                result = result | Unsigned::<8>::new(0b0000_0010);
425            };
426
427            // N - negative flag, bit 2
428            // the sign is in bit 7 of scrutinee
429            // move into lowest bit first
430            let flag_N = Ru7;
431
432            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(2));
433
434            // V - two's complement overflow flag, bit 3
435            // just constant zero here, already taken care of by not retaining flag
436
437            // S - sign flag, bit 4
438            // equal to N ^ V, but V is constant zero, so just use N
439            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(4));
440
441            Into::<Bitvector<8>>::into(result)
442        }
443
444        // for instructions: ADD, ADC
445        // Rd: destination register before being set
446        // Rr: other register
447        // Ru: destination register after being set
448        fn compute_status_add(
449            sreg: Bitvector<8>,
450            Rd: Bitvector<8>,
451            Rr: Bitvector<8>,
452            Ru: Bitvector<8>,
453        ) -> Bitvector<8> {
454            let retained_flags = Unsigned::<8>::new(0b1100_0000);
455            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
456
457            let Rd_unsigned = Into::<Unsigned<8>>::into(Rd);
458            let Rr_unsigned = Into::<Unsigned<8>>::into(Rr);
459            let Ru_unsigned = Into::<Unsigned<8>>::into(Ru);
460
461            let Rd7 = Ext::<1>::ext(Rd_unsigned >> Unsigned::<8>::new(7));
462            let Rr7 = Ext::<1>::ext(Rr_unsigned >> Unsigned::<8>::new(7));
463            let Ru7 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(7));
464
465            // C - carry flag, bit 0
466            let flag_C = (Rd7 & Rr7) | (Rr7 & !Ru7) | (!Ru7 & Rd7);
467            result = result | Ext::<8>::ext(flag_C);
468
469            // Z - zero flag, bit 1
470            if Ru == Bitvector::<8>::new(0) {
471                result = result | Unsigned::<8>::new(0b0000_0010);
472            };
473
474            // N - negative flag, bit 2
475            let flag_N = Ru7;
476            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(2));
477
478            // V - two's complement overflow flag, bit 3
479            let flag_V = (Rd7 & Rr7 & !Ru7) | (!Rd7 & !Rr7 & Ru7);
480            result = result | (Ext::<8>::ext(flag_V) << Unsigned::<8>::new(3));
481
482            // S - sign flag (N ^ V), bit 4
483            let flag_S = flag_N ^ flag_V;
484            result = result | (Ext::<8>::ext(flag_S) << Unsigned::<8>::new(4));
485
486            let Rd3 = Ext::<1>::ext(Rd_unsigned >> Unsigned::<8>::new(3));
487            let Rr3 = Ext::<1>::ext(Rr_unsigned >> Unsigned::<8>::new(3));
488            let Ru3 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(3));
489
490            // H - half carry flag, bit 5
491            let flag_H = (Rd3 & Rr3) | (Rr3 & !Ru3) | (!Ru3 & Rd3);
492            result = result | (Ext::<8>::ext(flag_H) << Unsigned::<8>::new(4));
493
494            Into::<Bitvector<8>>::into(result)
495        }
496
497        // for instructions ASR, LSR, ROR
498        // Rd: register before being shifted
499        // Ru: register after being shifted
500        // LSR has N flag always zero, but that
501        // will also happen due to zero Ru[[7]]
502        fn compute_status_right_shift(
503            sreg: Bitvector<8>,
504            Rd: Bitvector<8>,
505            Ru: Bitvector<8>,
506        ) -> Bitvector<8> {
507            // first, set like logical
508            let logical_status: Bitvector<8> = Self::compute_status_logical(sreg, Ru);
509            let mut result = Into::<Unsigned<8>>::into(logical_status);
510
511            let retained_flags = Unsigned::<8>::new(0b1111_0110);
512            result = result & retained_flags;
513
514            // C - carry flag, bit 0
515            // set to shifted-out bit
516            let shifted_out = Into::<Unsigned<8>>::into(Rd) & Unsigned::<8>::new(0b0000_0001);
517            let flag_C = Ext::<1>::ext(shifted_out);
518            result = result | shifted_out;
519
520            // V - two's complement overflow flag, bit 3
521            // set to N ^ C after shift
522            // N is in bit 2
523            let flag_N = Ext::<1>::ext(result >> Unsigned::<8>::new(2));
524            let flag_V = flag_N ^ flag_C;
525            result = result | (Ext::<8>::ext(flag_V) << Unsigned::<8>::new(3));
526
527            Into::<Bitvector<8>>::into(result)
528        }
529
530        // for instruction COM
531        // Ru: destination register after being set
532        fn compute_status_com(sreg: Bitvector<8>, Ru: Bitvector<8>) -> Bitvector<8> {
533            // C - carry flag, bit 0
534            // is set to one
535            let mut result = sreg | Bitvector::<8>::new(0b0000_0001);
536
537            // others are set like logical, which retains carry
538            result = Self::compute_status_logical(result, Ru);
539            result
540        }
541
542        // for instructions SUB, SUBI, CP, CPI
543        // Rd: destination register before being set
544        // Rr: other register
545        // Ru: destination register after being set
546        fn compute_status_sub(
547            sreg: Bitvector<8>,
548            Rd: Bitvector<8>,
549            Rr: Bitvector<8>,
550            Ru: Bitvector<8>,
551        ) -> Bitvector<8> {
552            // like compute_status_add, but with different negations in C, V, H flags
553
554            let retained_flags = Unsigned::<8>::new(0b1100_0000);
555            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
556
557            let Rd_unsigned = Into::<Unsigned<8>>::into(Rd);
558            let Rr_unsigned = Into::<Unsigned<8>>::into(Rr);
559            let Ru_unsigned = Into::<Unsigned<8>>::into(Ru);
560
561            let Rd7 = Ext::<1>::ext(Rd_unsigned >> Unsigned::<8>::new(7));
562            let Rr7 = Ext::<1>::ext(Rr_unsigned >> Unsigned::<8>::new(7));
563            let Ru7 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(7));
564
565            // C - carry flag, bit 0
566            let flag_C = (!Rd7 & Rr7) | (Rr7 & Ru7) | (Ru7 & !Rd7);
567            result = result | Ext::<8>::ext(flag_C);
568
569            // Z - zero flag, bit 1
570            if Ru == Bitvector::<8>::new(0) {
571                result = result | Unsigned::<8>::new(0b0000_0010);
572            };
573
574            // N - negative flag, bit 2
575            let flag_N = Ru7;
576            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(2));
577
578            // V - two's complement overflow flag, bit 3
579            let flag_V = (Rd7 & !Rr7 & !Ru7) | (!Rd7 & Rr7 & Ru7);
580            result = result | (Ext::<8>::ext(flag_V) << Unsigned::<8>::new(3));
581
582            // S - sign flag (N ^ V), bit 4
583            let flag_S = flag_N ^ flag_V;
584            result = result | (Ext::<8>::ext(flag_S) << Unsigned::<8>::new(4));
585
586            let Rd3 = Ext::<1>::ext(Rd_unsigned >> Unsigned::<8>::new(3));
587            let Rr3 = Ext::<1>::ext(Rr_unsigned >> Unsigned::<8>::new(3));
588            let Ru3 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(3));
589
590            // H - half carry flag, bit 5
591            let flag_H = (!Rd3 & Rr3) | (Rr3 & Ru3) | (Ru3 & !Rd3);
592            result = result | (Ext::<8>::ext(flag_H) << Unsigned::<8>::new(4));
593
594            Into::<Bitvector<8>>::into(result)
595        }
596
597        // for instructions SBC, SBCI, CPC
598        // differs from compute_status_sub in zero flag treatment
599        // Rd: destination register before being set
600        // Rr: other register
601        // Ru: destination register after being set
602        fn compute_status_sbc(
603            sreg: Bitvector<8>,
604            Rd: Bitvector<8>,
605            Rr: Bitvector<8>,
606            Ru: Bitvector<8>,
607        ) -> Bitvector<8> {
608            // remember previous zero flag (bit 1 of SREG)
609            let prev_sreg_zero_flag = sreg & Bitvector::<8>::new(0b0000_0010);
610
611            let mut result = Self::compute_status_sub(sreg, Rd, Rr, Ru);
612
613            // Z - zero flag, bit 1
614            // if result is zero, the flag must remain unchanged
615            // otherwise, it is cleared as normal
616            if Ru == Bitvector::<8>::new(0) {
617                // the zero flag is now wrongly cleared, set previous
618                result = result | prev_sreg_zero_flag;
619            }
620
621            result
622        }
623
624        // for instructions INC/DEC
625        // Ru: destination register after being decremented
626        // flag_V: whether the two's complement overflow flag is set
627        fn compute_status_inc_dec(
628            sreg: Bitvector<8>,
629            Ru: Bitvector<8>,
630            flag_V: Bitvector<1>,
631        ) -> Bitvector<8> {
632            let retained_flags = Unsigned::<8>::new(0b1110_0001);
633            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
634
635            let Ru_unsigned = Into::<Unsigned<8>>::into(Ru);
636            let Ru7 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(7));
637
638            // Z - zero flag, bit 1
639            if Ru == Bitvector::<8>::new(0) {
640                result = result | Unsigned::<8>::new(0b0000_0010);
641            };
642
643            // N - negative flag, bit 2
644            let flag_N = Ru7;
645            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(2));
646
647            // V - two's complement overflow flag, bit 3
648            // the only practical difference between INC and DEC status flags is given by V
649            // so we take it by parameter
650
651            let flag_V_unsigned = Into::<Unsigned<1>>::into(flag_V);
652            result = result | (Ext::<8>::ext(flag_V_unsigned) << Unsigned::<8>::new(3));
653
654            // S - sign flag (N ^ V), bit 4
655            let flag_S = flag_N ^ flag_V_unsigned;
656            result = result | (Ext::<8>::ext(flag_S) << Unsigned::<8>::new(4));
657
658            Into::<Bitvector<8>>::into(result)
659        }
660
661        // for instruction NEG
662        // Rd: register before being negated
663        // Ru: register after being negated
664        fn compute_status_neg(
665            sreg: Bitvector<8>,
666            Rd: Bitvector<8>,
667            Ru: Bitvector<8>,
668        ) -> Bitvector<8> {
669            // like compute_status_sub, but with Rd being the subtrahend from zero
670
671            let retained_flags = Unsigned::<8>::new(0b1100_0000);
672            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
673
674            let Rd_unsigned = Into::<Unsigned<8>>::into(Rd);
675            let Ru_unsigned = Into::<Unsigned<8>>::into(Ru);
676
677            let Ru7 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(7));
678
679            // C - carry flag, bit 0
680            // set if there is an implied borrow, i.e. exactly if Rd/Ru is not zero
681            // Z - zero flag, bit 1
682            // set either the Z or C flag depending on Ru being zero
683            if Ru == Bitvector::<8>::new(0) {
684                result = result | Unsigned::<8>::new(0b0000_0010);
685            } else {
686                result = result | Unsigned::<8>::new(0b0000_0001);
687            }
688
689            // N - negative flag, bit 2
690            let flag_N = Ru7;
691            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(2));
692
693            // V - two's complement overflow flag, bit 3
694            // set if and only if Ru is 0x80
695            let mut flag_V = Unsigned::<1>::new(0);
696            if Ru == Bitvector::<8>::new(0x80) {
697                flag_V = Unsigned::<1>::new(1);
698            }
699
700            // S - sign flag (N ^ V), bit 4
701            let flag_S = flag_N ^ flag_V;
702            result = result | (Ext::<8>::ext(flag_S) << Unsigned::<8>::new(4));
703
704            let Rd3 = Ext::<1>::ext(Rd_unsigned >> Unsigned::<8>::new(3));
705            let Ru3 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<8>::new(3));
706
707            // H - half carry flag, bit 5
708            // set exactly if there was a borrow from bit 3
709            let flag_H = Ru3 & !Rd3;
710            result = result | (Ext::<8>::ext(flag_H) << Unsigned::<8>::new(4));
711
712            Into::<Bitvector<8>>::into(result)
713        }
714
715        // for instruction ADIW
716        // Rd: register pair before addition
717        // R: register pair after addition
718        fn compute_status_adiw(
719            sreg: Bitvector<8>,
720            Rd: Bitvector<16>,
721            Ru: Bitvector<16>,
722        ) -> Bitvector<8> {
723            let retained_flags = Unsigned::<8>::new(0b1110_0000);
724            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
725
726            let Rd_unsigned = Into::<Unsigned<16>>::into(Rd);
727            let Ru_unsigned = Into::<Unsigned<16>>::into(Ru);
728
729            let Rd15 = Ext::<1>::ext(Rd_unsigned >> Unsigned::<16>::new(15));
730            let Ru15 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<16>::new(15));
731
732            // C - carry flag, bit 0
733            let flag_C = !Ru15 & Rd15;
734            result = result | Ext::<8>::ext(flag_C);
735
736            // Z - zero flag, bit 1
737            if Ru == Bitvector::<16>::new(0) {
738                result = result | Unsigned::<8>::new(0b0000_0010);
739            };
740
741            // N - negative flag, bit 2
742            let flag_N = Ru15;
743            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(2));
744
745            // V - two's complement overflow flag, bit 3
746            let flag_V = !Rd15 & Ru15;
747            result = result | (Ext::<8>::ext(flag_V) << Unsigned::<8>::new(3));
748
749            // S - sign flag (N ^ V), bit 4
750            let flag_S = flag_N ^ flag_V;
751            result = result | (Ext::<8>::ext(flag_S) << Unsigned::<8>::new(4));
752
753            Into::<Bitvector<8>>::into(result)
754        }
755
756        // for instruction SBIW
757        // Rd: register pair before subtraction
758        // R: register pair after subtraction
759        fn compute_status_sbiw(
760            sreg: Bitvector<8>,
761            Rd: Bitvector<16>,
762            Ru: Bitvector<16>,
763        ) -> Bitvector<8> {
764            let retained_flags = Unsigned::<8>::new(0b1110_0000);
765            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
766
767            let Rd_unsigned = Into::<Unsigned<16>>::into(Rd);
768            let Ru_unsigned = Into::<Unsigned<16>>::into(Ru);
769
770            let Rd15 = Ext::<1>::ext(Rd_unsigned >> Unsigned::<16>::new(15));
771            let Ru15 = Ext::<1>::ext(Ru_unsigned >> Unsigned::<16>::new(15));
772
773            // C - carry flag, bit 0
774            let flag_C = Ru15 & !Rd15;
775            result = result | Ext::<8>::ext(flag_C);
776
777            // Z - zero flag, bit 1
778            if Ru == Bitvector::<16>::new(0) {
779                result = result | Unsigned::<8>::new(0b0000_0010);
780            };
781
782            // N - negative flag, bit 2
783            let flag_N = Ru15;
784            result = result | (Ext::<8>::ext(flag_N) << Unsigned::<8>::new(2));
785
786            // V - two's complement overflow flag, bit 3
787            let flag_V = Ru15 & !Rd15;
788            result = result | (Ext::<8>::ext(flag_V) << Unsigned::<8>::new(3));
789
790            // S - sign flag (N ^ V), bit 4
791            let flag_S = flag_N ^ flag_V;
792            result = result | (Ext::<8>::ext(flag_S) << Unsigned::<8>::new(4));
793
794            Into::<Bitvector<8>>::into(result)
795        }
796
797        // for instructions: MUL, MULS, MULSU, FMUL, FMULS, FMULSU
798        // Rt: multiplication result (before shifting in fractional multiplies)
799        // Ru: final multiplication result
800        fn compute_status_mul(
801            sreg: Bitvector<8>,
802            Rt: Bitvector<16>,
803            Ru: Bitvector<16>,
804        ) -> Bitvector<8> {
805            let retained_flags = Unsigned::<8>::new(0b1111_1100);
806            let mut result = Into::<Unsigned<8>>::into(sreg) & retained_flags;
807
808            let Rt_unsigned = Into::<Unsigned<16>>::into(Rt);
809            let Rt15 = Ext::<1>::ext(Rt_unsigned >> Unsigned::<16>::new(15));
810
811            // C - carry flag, bit 0
812            // copies bit 15 of result (before shifting in fractional multiplies)
813            let flag_C = Rt15;
814            result = result | Ext::<8>::ext(flag_C);
815
816            // Z - zero flag, bit 1
817            // whether the final result is zero
818            if Ru == Bitvector::<16>::new(0) {
819                result = result | Unsigned::<8>::new(0b0000_0010);
820            };
821
822            Into::<Bitvector<8>>::into(result)
823        }
824
825        fn next_0000(state: &State, instruction: Bitvector<16>) -> State {
826            let PC = state.PC;
827            let mut R = Clone::clone(&state.R);
828            let DDRB = state.DDRB;
829            let PORTB = state.PORTB;
830            let DDRC = state.DDRC;
831            let PORTC = state.PORTC;
832            let DDRD = state.DDRD;
833            let PORTD = state.PORTD;
834            let GPIOR0 = state.GPIOR0;
835            let GPIOR1 = state.GPIOR1;
836            let GPIOR2 = state.GPIOR2;
837            let SPL = state.SPL;
838            let SPH = state.SPH;
839            let mut SREG = state.SREG;
840            let SRAM = Clone::clone(&state.SRAM);
841
842            ::machine_check::bitmask_switch!(instruction {
843                // NOP
844                "----_0000_0000_0000" => {
845                    // do nothing
846                },
847
848                // other 255 opcodes starting with 0000_0000 are reserved
849                "----_0000_0000_0001" => {
850                    panic!("Reserved opcode");
851                }
852                "----_0000_0000_001-" => {
853                    panic!("Reserved opcode");
854                }
855                "----_0000_0000_01--" => {
856                    panic!("Reserved opcode");
857                }
858                "----_0000_0000_1---" => {
859                    panic!("Reserved opcode");
860                }
861                "----_0000_0001_----" => {
862                    panic!("Reserved opcode");
863                }
864                "----_0000_001-_----" => {
865                    panic!("Reserved opcode");
866                }
867                "----_0000_01--_----" => {
868                    panic!("Reserved opcode");
869                }
870                "----_0000_1---_----" => {
871                    panic!("Reserved opcode");
872                }
873
874                // MOVW
875                "----_0001_dddd_rrrr" => {
876                    // copy register pair
877                    let d_unsigned = Into::<Unsigned<4>>::into(d);
878                    let d_ext_unsigned = Ext::<5>::ext(d_unsigned);
879                    let d_ext = Into::<Bitvector<5>>::into(d_ext_unsigned);
880
881                    let r_unsigned = Into::<Unsigned<4>>::into(r);
882                    let r_ext_unsigned = Ext::<5>::ext(r_unsigned);
883                    let r_ext = Into::<Bitvector<5>>::into(r_ext_unsigned);
884
885                    R[d_ext + d_ext] = R[r_ext + r_ext];
886
887                    let five_bit_one = Bitvector::<5>::new(1);
888                    R[d_ext + d_ext + five_bit_one] = R[r_ext + r_ext + five_bit_one];
889                }
890
891                // MULS
892                "----_0010_dddd_rrrr" => {
893                    // the operand registers are 16 to 31
894                    let reg_d = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<4>>::into(d))) + Bitvector::<5>::new(16);
895                    let reg_r = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<4>>::into(r))) + Bitvector::<5>::new(16);
896
897                    // multiply signed by signed
898                    let d_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Signed<8>>::into(state.R[reg_d])));
899                    let r_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Signed<8>>::into(state.R[reg_r])));
900
901                    let mul_result = d_ext * r_ext;
902                    let mul_result_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(mul_result)));
903                    let mul_result_hi = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(mul_result) >> Unsigned::<16>::new(8)));
904
905                    // store result low byte into register 0 and high byte into register 1
906                    R[Bitvector::<5>::new(0)] = mul_result_lo;
907                    R[Bitvector::<5>::new(1)] = mul_result_hi;
908
909                    // update status register
910                    SREG = Self::compute_status_mul(state.SREG, mul_result, mul_result);
911
912                }
913                // MULSU
914                "----_0011_0ddd_0rrr" => {
915                    // the operand registers are 16 to 23
916                    let reg_d = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(d))) + Bitvector::<5>::new(16);
917                    let reg_r = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(r))) + Bitvector::<5>::new(16);
918
919                    // multiply signed by unsigned
920                    let d_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Signed<8>>::into(state.R[reg_d])));
921                    let r_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[reg_r])));
922
923                    let mul_result = d_ext * r_ext;
924                    let mul_result_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(mul_result)));
925                    let mul_result_hi = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(mul_result) >> Unsigned::<16>::new(8)));
926
927                    // store result low byte into register 0 and high byte into register 1
928                    R[Bitvector::<5>::new(0)] = mul_result_lo;
929                    R[Bitvector::<5>::new(1)] = mul_result_hi;
930
931                    // update status register
932                    SREG = Self::compute_status_mul(state.SREG, mul_result, mul_result);
933                }
934
935                // FMUL
936                "----_0011_0ddd_1rrr" => {
937                    // the operand registers are 16 to 23
938                    let reg_d = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(d))) + Bitvector::<5>::new(16);
939                    let reg_r = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(r))) + Bitvector::<5>::new(16);
940
941                    // multiply unsigned by unsigned
942                    let d_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[reg_d])));
943                    let r_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[reg_r])));
944
945                    let mul_result = d_ext * r_ext;
946
947                    // shift multiplication result left by one position
948                    let fmul_result = mul_result << Bitvector::<16>::new(1);
949
950                    let fmul_result_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(fmul_result)));
951                    let fmul_result_hi = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(fmul_result) >> Unsigned::<16>::new(8)));
952
953                    // store fractional result low byte into register 0 and high byte into register 1
954                    R[Bitvector::<5>::new(0)] = fmul_result_lo;
955                    R[Bitvector::<5>::new(1)] = fmul_result_hi;
956
957                    // update status register
958                    SREG = Self::compute_status_mul(state.SREG, mul_result, fmul_result);
959                }
960
961                // FMULS
962                "----_0011_1ddd_0rrr" => {
963                    // the operand registers are 16 to 23
964                    let reg_d = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(d))) + Bitvector::<5>::new(16);
965                    let reg_r = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(r))) + Bitvector::<5>::new(16);
966
967                    // multiply signed by signed
968                    let d_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Signed<8>>::into(state.R[reg_d])));
969                    let r_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Signed<8>>::into(state.R[reg_r])));
970
971                    let mul_result = d_ext * r_ext;
972
973                    // shift multiplication result left by one position
974                    let fmul_result = mul_result << Bitvector::<16>::new(1);
975
976                    let fmul_result_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(fmul_result)));
977                    let fmul_result_hi = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(fmul_result) >> Unsigned::<16>::new(8)));
978
979                    // store fractional result low byte into register 0 and high byte into register 1
980                    R[Bitvector::<5>::new(0)] = fmul_result_lo;
981                    R[Bitvector::<5>::new(1)] = fmul_result_hi;
982
983                    // update status register
984                    SREG = Self::compute_status_mul(state.SREG, mul_result, fmul_result);
985                }
986
987                // FMULSU
988                "----_0011_1ddd_1rrr" => {
989                    // the operand registers are 16 to 23
990                    let reg_d = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(d))) + Bitvector::<5>::new(16);
991                    let reg_r = Into::<Bitvector<5>>::into(Ext::<5>::ext(Into::<Unsigned<3>>::into(r))) + Bitvector::<5>::new(16);
992
993                    // multiply signed by unsigned
994                    let d_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Signed<8>>::into(state.R[reg_d])));
995                    let r_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[reg_r])));
996
997                    let mul_result = d_ext * r_ext;
998
999                    // shift multiplication result left by one position
1000                    let fmul_result = mul_result << Bitvector::<16>::new(1);
1001
1002                    let fmul_result_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(fmul_result)));
1003                    let fmul_result_hi = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(fmul_result) >> Unsigned::<16>::new(8)));
1004
1005                    // store fractional result low byte into register 0 and high byte into register 1
1006                    R[Bitvector::<5>::new(0)] = fmul_result_lo;
1007                    R[Bitvector::<5>::new(1)] = fmul_result_hi;
1008
1009                    // update status register
1010                    SREG = Self::compute_status_mul(state.SREG, mul_result, fmul_result);
1011                }
1012
1013                // CPC
1014                "----_01rd_dddd_rrrr" => {
1015                    // compare with carry, same as SBC without actually saving the computed value
1016                    // carry is in bit 0
1017                    let carry = SREG & Bitvector::<8>::new(0b0000_0001);
1018                    let result = R[d] - R[r] - carry;
1019                    SREG = Self::compute_status_sbc(SREG, R[d], R[r], result);
1020                }
1021
1022                // SBC
1023                "----_10rd_dddd_rrrr" => {
1024                    // subtract with carry
1025                    let prev = R[d];
1026                    // carry is in bit 0
1027                    let carry = SREG & Bitvector::<8>::new(0b0000_0001);
1028                    R[d] = R[d] - R[r] - carry;
1029                    SREG = Self::compute_status_sbc(SREG, prev, R[r], R[d]);
1030                }
1031
1032                // ADD
1033                "----_11rd_dddd_rrrr" => {
1034                    let prev = R[d];
1035                    R[d] = R[d] + R[r];
1036                    SREG = Self::compute_status_add(SREG, prev, R[r], R[d]);
1037                }
1038            });
1039
1040            State {
1041                PC,
1042                R,
1043                DDRB,
1044                PORTB,
1045                DDRC,
1046                PORTC,
1047                DDRD,
1048                PORTD,
1049                GPIOR0,
1050                GPIOR1,
1051                GPIOR2,
1052                SPL,
1053                SPH,
1054                SREG,
1055                SRAM,
1056            }
1057        }
1058
1059        fn next_0001(&self, state: &State, instruction: Bitvector<16>) -> State {
1060            let mut PC = state.PC;
1061            let mut R = Clone::clone(&state.R);
1062            let DDRB = state.DDRB;
1063            let PORTB = state.PORTB;
1064            let DDRC = state.DDRC;
1065            let PORTC = state.PORTC;
1066            let DDRD = state.DDRD;
1067            let PORTD = state.PORTD;
1068            let GPIOR0 = state.GPIOR0;
1069            let GPIOR1 = state.GPIOR1;
1070            let GPIOR2 = state.GPIOR2;
1071            let SPL = state.SPL;
1072            let SPH = state.SPH;
1073            let mut SREG = state.SREG;
1074            let SRAM = Clone::clone(&state.SRAM);
1075
1076            ::machine_check::bitmask_switch!(instruction {
1077                // CPSE
1078                "----_00rd_dddd_rrrr" => {
1079                    // compare skip if equal
1080                    // similar to other skips, but with register comparison
1081                    if R[d] == R[r] {
1082                        // they are equal, skip next instruction
1083                        PC = Self::instruction_skip(self, PC);
1084                    } else {
1085                        // they are not equal, do nothing
1086                    };
1087                }
1088
1089                // CP
1090                "----_01rd_dddd_rrrr" => {
1091                    // compare, same as SUB without actually saving the computed value
1092                    let result = R[d] - R[r];
1093                    SREG = Self::compute_status_sub(SREG, R[d], R[r], result);
1094                }
1095
1096                // SUB
1097                "----_10rd_dddd_rrrr" => {
1098                    let prev = R[d];
1099                    R[d] = R[d] - R[r];
1100                    SREG = Self::compute_status_sub(SREG, prev, R[r], R[d]);
1101                }
1102
1103                // ADC
1104                "----_11rd_dddd_rrrr" => {
1105                    // add with carry
1106                    let prev = R[d];
1107                    // carry is in bit 0
1108                    let carry = SREG & Bitvector::<8>::new(0b0000_0001);
1109                    R[d] = R[d] + R[r] + carry;
1110                    SREG = Self::compute_status_add(SREG, prev, R[r], R[d]);
1111                }
1112            });
1113
1114            State {
1115                PC,
1116                R,
1117                DDRB,
1118                PORTB,
1119                DDRC,
1120                PORTC,
1121                DDRD,
1122                PORTD,
1123                GPIOR0,
1124                GPIOR1,
1125                GPIOR2,
1126                SPL,
1127                SPH,
1128                SREG,
1129                SRAM,
1130            }
1131        }
1132
1133        fn next_0010(state: &State, instruction: Bitvector<16>) -> State {
1134            let PC = state.PC;
1135            let mut R = Clone::clone(&state.R);
1136            let DDRB = state.DDRB;
1137            let PORTB = state.PORTB;
1138            let DDRC = state.DDRC;
1139            let PORTC = state.PORTC;
1140            let DDRD = state.DDRD;
1141            let PORTD = state.PORTD;
1142            let GPIOR0 = state.GPIOR0;
1143            let GPIOR1 = state.GPIOR1;
1144            let GPIOR2 = state.GPIOR2;
1145            let SPL = state.SPL;
1146            let SPH = state.SPH;
1147            let mut SREG = state.SREG;
1148            let SRAM = Clone::clone(&state.SRAM);
1149
1150            ::machine_check::bitmask_switch!(instruction {
1151
1152                // AND
1153                "----_00rd_dddd_rrrr" => {
1154                    // logical and
1155                    R[d] =  R[d] & R[r];
1156                    SREG = Self::compute_status_logical(SREG, R[d]);
1157
1158                }
1159
1160                // EOR
1161                "----_01rd_dddd_rrrr" => {
1162
1163                    // exclusive or
1164
1165                    // kludge: when zeroing the register through EOR,
1166                    // bypass unknown values by setting zero directly
1167                    // this is due to this special case being widely
1168                    // used to set a register to zero
1169                    if r == d {
1170                        R[d] = Bitvector::<8>::new(0);
1171                    } else {
1172                        R[d] = R[d] ^ R[r];
1173                    };
1174
1175                    SREG = Self::compute_status_logical(SREG, R[d]);
1176
1177                }
1178
1179                // OR
1180                "----_10rd_dddd_rrrr" => {
1181                    // logical or
1182                    R[d] = R[d] | R[r];
1183                    SREG = Self::compute_status_logical(SREG, R[d]);
1184                }
1185
1186                // MOV
1187                "----_11rd_dddd_rrrr" => {
1188                    // copy register, status flags not affected
1189                    R[d] = R[r];
1190                }
1191            });
1192
1193            State {
1194                PC,
1195                R,
1196                DDRB,
1197                PORTB,
1198                DDRC,
1199                PORTC,
1200                DDRD,
1201                PORTD,
1202                GPIOR0,
1203                GPIOR1,
1204                GPIOR2,
1205                SPL,
1206                SPH,
1207                SREG,
1208                SRAM,
1209            }
1210        }
1211
1212        fn next_0011(state: &State, instruction: Bitvector<16>) -> State {
1213            let PC = state.PC;
1214            let R = Clone::clone(&state.R);
1215            let DDRB = state.DDRB;
1216            let PORTB = state.PORTB;
1217            let DDRC = state.DDRC;
1218            let PORTC = state.PORTC;
1219            let DDRD = state.DDRD;
1220            let PORTD = state.PORTD;
1221            let GPIOR0 = state.GPIOR0;
1222            let GPIOR1 = state.GPIOR1;
1223            let GPIOR2 = state.GPIOR2;
1224            let SPL = state.SPL;
1225            let SPH = state.SPH;
1226            let mut SREG = state.SREG;
1227            let SRAM = Clone::clone(&state.SRAM);
1228
1229            ::machine_check::bitmask_switch!(instruction {
1230                // CPI
1231                "----_kkkk_dddd_kkkk" => {
1232                    // extend d to five bits and add 16
1233                    let d_unsigned = Into::<Unsigned<4>>::into(d);
1234                    let d_ext_unsigned = Ext::<5>::ext(d_unsigned);
1235                    let d_ext = Into::<Bitvector<5>>::into(d_ext_unsigned);
1236                    let reg_num = d_ext + Bitvector::<5>::new(16);
1237
1238                    // compare with immediate
1239                    let result = R[reg_num] - k;
1240
1241                    SREG = Self::compute_status_sub(SREG, R[reg_num], k, result);
1242                }
1243            });
1244
1245            State {
1246                PC,
1247                R,
1248                DDRB,
1249                PORTB,
1250                DDRC,
1251                PORTC,
1252                DDRD,
1253                PORTD,
1254                GPIOR0,
1255                GPIOR1,
1256                GPIOR2,
1257                SPL,
1258                SPH,
1259                SREG,
1260                SRAM,
1261            }
1262        }
1263
1264        fn next_01(state: &State, instruction: Bitvector<16>) -> State {
1265            let PC = state.PC;
1266            let mut R = Clone::clone(&state.R);
1267            let DDRB = state.DDRB;
1268            let PORTB = state.PORTB;
1269            let DDRC = state.DDRC;
1270            let PORTC = state.PORTC;
1271            let DDRD = state.DDRD;
1272            let PORTD = state.PORTD;
1273            let GPIOR0 = state.GPIOR0;
1274            let GPIOR1 = state.GPIOR1;
1275            let GPIOR2 = state.GPIOR2;
1276            let SPL = state.SPL;
1277            let SPH = state.SPH;
1278            let mut SREG = state.SREG;
1279            let SRAM = Clone::clone(&state.SRAM);
1280
1281            ::machine_check::bitmask_switch!(instruction {
1282
1283                // SBCI
1284                "--00_kkkk_dddd_kkkk" => {
1285                    // extend d to five bits and add 16
1286                    let d_unsigned = Into::<Unsigned<4>>::into(d);
1287                    let d_ext_unsigned = Ext::<5>::ext(d_unsigned);
1288                    let d_ext = Into::<Bitvector<5>>::into(d_ext_unsigned);
1289                    let reg_num = d_ext + Bitvector::<5>::new(16);
1290
1291                    // subtract immediate with carry
1292                    let prev = R[reg_num];
1293                    // carry is in bit 0
1294                    let carry = SREG & Bitvector::<8>::new(0b0000_0001);
1295                    R[reg_num] = R[reg_num] - k - carry;
1296                    SREG = Self::compute_status_sbc(SREG, prev, k, R[reg_num]);
1297                }
1298                // SUBI
1299                "--01_kkkk_dddd_kkkk" => {
1300                    // extend d to five bits and add 16
1301                    let d_unsigned = Into::<Unsigned<4>>::into(d);
1302                    let d_ext_unsigned = Ext::<5>::ext(d_unsigned);
1303                    let d_ext = Into::<Bitvector<5>>::into(d_ext_unsigned);
1304                    let reg_num = d_ext + Bitvector::<5>::new(16);
1305
1306                    // subtract immediate
1307                    let prev = R[reg_num];
1308                    R[reg_num] = R[reg_num] - k;
1309
1310                    SREG = Self::compute_status_sub(SREG, prev, k, R[reg_num]);
1311                }
1312                // ORI
1313                "--10_kkkk_dddd_kkkk" => {
1314                    // extend d to five bits and add 16
1315                    let d_unsigned = Into::<Unsigned<4>>::into(d);
1316                    let d_ext_unsigned = Ext::<5>::ext(d_unsigned);
1317                    let d_ext = Into::<Bitvector<5>>::into(d_ext_unsigned);
1318                    let reg_num = d_ext + Bitvector::<5>::new(16);
1319
1320                    // logical or with immediate
1321                    R[reg_num] = R[reg_num] | k;
1322                    SREG = Self::compute_status_logical(SREG, R[reg_num]);
1323                }
1324                // ANDI
1325                "--11_kkkk_dddd_kkkk" => {
1326                    // extend d to five bits and add 16
1327                    let d_unsigned = Into::<Unsigned<4>>::into(d);
1328                    let d_ext_unsigned = Ext::<5>::ext(d_unsigned);
1329                    let d_ext = Into::<Bitvector<5>>::into(d_ext_unsigned);
1330                    let reg_num = d_ext + Bitvector::<5>::new(16);
1331
1332                    // logical and with immediate
1333                    R[reg_num] = R[reg_num] & k;
1334                    SREG = Self::compute_status_logical(SREG, R[reg_num]);
1335                }
1336            });
1337
1338            State {
1339                PC,
1340                R,
1341                DDRB,
1342                PORTB,
1343                DDRC,
1344                PORTC,
1345                DDRD,
1346                PORTD,
1347                GPIOR0,
1348                GPIOR1,
1349                GPIOR2,
1350                SPL,
1351                SPH,
1352                SREG,
1353                SRAM,
1354            }
1355        }
1356
1357        fn load_with_displacement(
1358            state: &State,
1359            input: &Input,
1360            address_lo_index: Bitvector<5>,
1361            result_reg_index: Bitvector<5>,
1362            displacement: Bitvector<6>,
1363        ) -> BitvectorArray<5, 8> {
1364            let mut R = Clone::clone(&state.R);
1365
1366            let address_hi_index = address_lo_index + Bitvector::<5>::new(1);
1367
1368            let address_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_lo_index]));
1369            let address_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_hi_index]));
1370            let address = (address_hi << Unsigned::<16>::new(8)) | address_lo;
1371
1372            // add displacement, it is interpreted as 6-bit unsigned
1373            let address_with_displacement =
1374                address + Ext::<16>::ext(Into::<Unsigned<6>>::into(displacement));
1375
1376            // load
1377            let read_result: Bitvector<8> = Self::read_data_mem(
1378                state,
1379                input,
1380                Into::<Bitvector<16>>::into(address_with_displacement),
1381            );
1382            R[result_reg_index] = read_result;
1383            R
1384        }
1385
1386        fn store_with_displacement(
1387            state: &State,
1388            address_lo_index: Bitvector<5>,
1389            value_reg_index: Bitvector<5>,
1390            displacement: Bitvector<6>,
1391        ) -> State {
1392            let address_hi_index = address_lo_index + Bitvector::<5>::new(1);
1393
1394            let address_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[address_lo_index]));
1395            let address_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[address_hi_index]));
1396            let address = (address_hi << Unsigned::<16>::new(8)) | address_lo;
1397
1398            // add displacement, it is interpreted as 6-bit unsigned
1399            let address_with_displacement =
1400                address + Ext::<16>::ext(Into::<Unsigned<6>>::into(displacement));
1401
1402            let value = state.R[value_reg_index];
1403
1404            // store
1405            let write_result: State = Self::write_data_mem(
1406                state,
1407                Into::<Bitvector<16>>::into(address_with_displacement),
1408                value,
1409            );
1410            write_result
1411        }
1412
1413        fn next_10q0(state: &State, input: &Input, instruction: Bitvector<16>) -> State {
1414            let PC = state.PC;
1415            let DDRB = state.DDRB;
1416            let PORTB = state.PORTB;
1417            let DDRC = state.DDRC;
1418            let PORTC = state.PORTC;
1419            let DDRD = state.DDRD;
1420            let PORTD = state.PORTD;
1421            let GPIOR0 = state.GPIOR0;
1422            let GPIOR1 = state.GPIOR1;
1423            let GPIOR2 = state.GPIOR2;
1424            let SPL = state.SPL;
1425            let SPH = state.SPH;
1426            let SREG = state.SREG;
1427
1428            let mut result = Clone::clone(state);
1429
1430            ::machine_check::bitmask_switch!(instruction {
1431                // LD Rd, Z+q
1432                "--q-_qq0d_dddd_0qqq" => {
1433                    // load data memory pointed to by Z (30:31) with displacement
1434                    let SRAM = Clone::clone(&state.SRAM);
1435                    let R: BitvectorArray<5, 8> = Self::load_with_displacement(state, input, Bitvector::<5>::new(30), d, q);
1436                    result = State {
1437                        PC,
1438                        R,
1439                        DDRB,
1440                        PORTB,
1441                        DDRC,
1442                        PORTC,
1443                        DDRD,
1444                        PORTD,
1445                        GPIOR0,
1446                        GPIOR1,
1447                        GPIOR2,
1448                        SPL,
1449                        SPH,
1450                        SREG,
1451                        SRAM,
1452                    };
1453                }
1454
1455                // LD Rd, Y+q
1456                "--q-_qq0d_dddd_1qqq" => {
1457                    // load data memory pointed to by Y (28:29) with displacement
1458                    let SRAM = Clone::clone(&state.SRAM);
1459                    let R: BitvectorArray<5, 8>  = Self::load_with_displacement(state, input, Bitvector::<5>::new(28), d, q);
1460                    result = State {
1461                        PC,
1462                        R,
1463                        DDRB,
1464                        PORTB,
1465                        DDRC,
1466                        PORTC,
1467                        DDRD,
1468                        PORTD,
1469                        GPIOR0,
1470                        GPIOR1,
1471                        GPIOR2,
1472                        SPL,
1473                        SPH,
1474                        SREG,
1475                        SRAM,
1476                    };
1477                }
1478
1479                // ST Z+q, Rr
1480                "--q-_qq1r_rrrr_0qqq" => {
1481                    // store data memory pointed to by Y (30:31) with displacement
1482                    result = Self::store_with_displacement(state, Bitvector::<5>::new(30), r, q);
1483                }
1484
1485                // ST Y+q, Rr
1486                "--q-_qq1r_rrrr_1qqq" => {
1487                    // store data memory pointed to by Y (28:29) with displacement
1488                    result = Self::store_with_displacement(state, Bitvector::<5>::new(28), r, q);
1489                }
1490            });
1491            result
1492        }
1493
1494        fn load_post_increment(
1495            state: &State,
1496            input: &Input,
1497            address_lo_index: Bitvector<5>,
1498            result_reg_index: Bitvector<5>,
1499        ) -> BitvectorArray<5, 8> {
1500            let mut R = Clone::clone(&state.R);
1501
1502            let address_hi_index = address_lo_index + Bitvector::<5>::new(1);
1503
1504            let address_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_lo_index]));
1505            let address_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_hi_index]));
1506            let address = (address_hi << Unsigned::<16>::new(8)) | address_lo;
1507
1508            // load
1509            let read_result: Bitvector<8> =
1510                Self::read_data_mem(state, input, Into::<Bitvector<16>>::into(address));
1511            R[result_reg_index] = read_result;
1512
1513            // post-increment
1514            if (result_reg_index == address_lo_index) | (result_reg_index == address_hi_index) {
1515                panic!("Illegal load with post-increment from part of address register");
1516            }
1517            let address_post = address + Unsigned::<16>::new(1);
1518            let address_lo_post = Into::<Bitvector<8>>::into(Ext::<8>::ext(address_post));
1519            let address_hi_post =
1520                Into::<Bitvector<8>>::into(Ext::<8>::ext(address_post >> Unsigned::<16>::new(8)));
1521            R[address_lo_index] = address_lo_post;
1522            R[address_hi_index] = address_hi_post;
1523            R
1524        }
1525
1526        fn load_pre_decrement(
1527            state: &State,
1528            input: &Input,
1529            address_lo_index: Bitvector<5>,
1530            result_reg_index: Bitvector<5>,
1531        ) -> BitvectorArray<5, 8> {
1532            let mut R = Clone::clone(&state.R);
1533
1534            let address_hi_index = address_lo_index + Bitvector::<5>::new(1);
1535
1536            if (result_reg_index == address_lo_index) | (result_reg_index == address_hi_index) {
1537                panic!("Illegal load with pre-decrement from part of address register");
1538            }
1539
1540            let old_address_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_lo_index]));
1541            let old_address_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_hi_index]));
1542            let old_address = (old_address_hi << Unsigned::<16>::new(8)) | old_address_lo;
1543
1544            // pre-decrement
1545            let address = old_address - Unsigned::<16>::new(1);
1546            let address_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(address));
1547            let address_hi =
1548                Into::<Bitvector<8>>::into(Ext::<8>::ext(address >> Unsigned::<16>::new(8)));
1549            R[address_lo_index] = address_lo;
1550            R[address_hi_index] = address_hi;
1551
1552            // load
1553            let read_result: Bitvector<8> =
1554                Self::read_data_mem(state, input, Into::<Bitvector<16>>::into(address));
1555            R[result_reg_index] = read_result;
1556            R
1557        }
1558
1559        fn next_1001_000d(
1560            &self,
1561            state: &State,
1562            input: &Input,
1563            instruction: Bitvector<16>,
1564        ) -> State {
1565            let mut PC = state.PC;
1566            let mut R = Clone::clone(&state.R);
1567            let DDRB = state.DDRB;
1568            let PORTB = state.PORTB;
1569            let DDRC = state.DDRC;
1570            let PORTC = state.PORTC;
1571            let DDRD = state.DDRD;
1572            let PORTD = state.PORTD;
1573            let GPIOR0 = state.GPIOR0;
1574            let GPIOR1 = state.GPIOR1;
1575            let GPIOR2 = state.GPIOR2;
1576            let mut SPL = state.SPL;
1577            let mut SPH = state.SPH;
1578            let SREG = state.SREG;
1579            let SRAM = Clone::clone(&state.SRAM);
1580
1581            ::machine_check::bitmask_switch!(instruction {
1582                // LDS - 2 words
1583                "----_---d_dddd_0000" => {
1584                    // load direct from data space to register d
1585
1586                    // LDS is a 2-word instruction, the address is in program memory in the next instruction location
1587                    // PC is already incremented to point to the next instruction, fetch it and increment PC once again
1588                    let address = self.PROGMEM[PC];
1589                    PC = PC + Bitvector::<14>::new(1);
1590
1591                    let read_result: Bitvector<8> = Self::read_data_mem(state, input, Into::<Bitvector<16>>::into(address));
1592                    R[d] = read_result;
1593                }
1594
1595                // LD Rd, Z+
1596                "----_---d_dddd_0001" => {
1597                    // load data memory pointed to by Z (30:31) with post-increment
1598                    R = Self::load_post_increment(state, input, Bitvector::<5>::new(30), d);
1599                }
1600
1601                // LD Rd, -Z
1602                "----_---d_dddd_0010" => {
1603                    // load data memory pointed to by Z (30:31) with pre-decrement
1604                    R = Self::load_pre_decrement(state, input, Bitvector::<5>::new(30), d);
1605                }
1606
1607                // 0011 reserved
1608                "----_---d_dddd_0011" => {
1609                    panic!("Reserved opcode");
1610                }
1611
1612                // LPM Rd, Z
1613                "----_---d_dddd_0100" => {
1614                    unimplemented!("LPM instruction");
1615                    /*
1616                    // load program memory
1617                    //R[d] = fetchProgramByte(Z);
1618                    unimplemented();
1619
1620                    // LPM is a three-cycle instruction
1621                    increment_cycle_count();
1622                    increment_cycle_count();
1623                    */
1624                }
1625
1626                // LPM Rd, Z+
1627                "----_---d_dddd_0101" => {
1628                    unimplemented!("LPM instruction");
1629                    /*
1630                    // load program memory with post-increment
1631                    //R[d] = fetchProgramByte(Z);
1632                    unimplemented();
1633
1634                    Z = Z + 1;
1635
1636                    // LPM is a three-cycle instruction
1637                    increment_cycle_count();
1638                    increment_cycle_count();
1639                    */
1640                }
1641
1642                // ELPM Rd, Z
1643                "----_---d_dddd_0110" => {
1644                    unimplemented!("ELPM instruction");
1645                    //R[d] = PROGRAM[RAMPZ:Z];
1646                }
1647
1648                // ELPM Rd, Z+
1649                "----_---d_dddd_0111" => {
1650                    unimplemented!("ELPM instruction");
1651                    //R[d] = PROGRAM[RAMPZ:Z]; (RAMPZ:Z) = (RAMPZ:Z) + 1;
1652                }
1653
1654                // 1000 reserved
1655                "----_---d_dddd_1000" => {
1656                    panic!("Reserved opcode");
1657                }
1658
1659                // LD Rd, Y+
1660                "----_---d_dddd_1001" => {
1661                    // load data memory pointed to by Y (28:29) with post-increment
1662                    R = Self::load_post_increment(state, input, Bitvector::<5>::new(28), d);
1663                }
1664
1665                // LD Rd, -Y
1666                "----_---d_dddd_1010" => {
1667                    // load data memory pointed to by Y (28:29) with pre-decrement
1668                    R = Self::load_pre_decrement(state, input, Bitvector::<5>::new(28), d);
1669                }
1670
1671                // 1011  reserved
1672                "----_---d_dddd_1011" => {
1673                    panic!("Reserved opcode");
1674                }
1675
1676                // LD Rd, X
1677                "----_---d_dddd_1100" => {
1678                    // load data memory pointed to by X (26:27) into working register
1679                    // register X does not support displacement, it is always 0
1680                    R = Self::load_with_displacement(state, input, Bitvector::<5>::new(26), d, Bitvector::<6>::new(0));
1681                }
1682
1683                // LD Rd, X+
1684                "----_---d_dddd_1101" => {
1685                    // load data memory pointed to by X (26:27) with post-increment
1686                    R = Self::load_post_increment(state, input, Bitvector::<5>::new(26), d);
1687                }
1688
1689                // LD Rd, -X
1690                "----_---d_dddd_1110" => {
1691                    // load data memory pointed to by X (26:27) with pre-decrement
1692                    R = Self::load_pre_decrement(state, input, Bitvector::<5>::new(26), d);
1693                }
1694
1695                // POP Rd
1696                "----_---d_dddd_1111" => {
1697                    // pre-increment stack pointer, then load byte to register d
1698
1699                    // TODO: detect stack underflow/outside data memory
1700
1701                    let old_stack_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(SPL));
1702                    let old_stack_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(SPH));
1703                    let old_stack = (old_stack_hi << Unsigned::<16>::new(8)) | old_stack_lo;
1704
1705                    // pre-increment
1706                    let stack = old_stack + Unsigned::<16>::new(1);
1707                    let stack_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(stack));
1708                    let stack_hi =
1709                        Into::<Bitvector<8>>::into(Ext::<8>::ext(stack >> Unsigned::<16>::new(8)));
1710                    SPL = stack_lo;
1711                    SPH = stack_hi;
1712
1713                    // stack value should be in data memory
1714                    if stack < Unsigned::<16>::new(0x0100) {
1715                        panic!("Pop with overflowed stack");
1716                    };
1717                    let sram_address_full = stack - Unsigned::<16>::new(0x0100);
1718
1719                    let sram_address = Ext::<11>::ext(sram_address_full);
1720
1721                    if Ext::<16>::ext(sram_address) != sram_address_full {
1722                        panic!("Pop underflows stack from data memory");
1723                    };
1724
1725                    // load byte
1726                    R[d] = SRAM[Into::<Bitvector<11>>::into(sram_address)];
1727
1728                    // POP is a two-cycle instruction
1729                }
1730            });
1731
1732            State {
1733                PC,
1734                R,
1735                DDRB,
1736                PORTB,
1737                DDRC,
1738                PORTC,
1739                DDRD,
1740                PORTD,
1741                GPIOR0,
1742                GPIOR1,
1743                GPIOR2,
1744                SPL,
1745                SPH,
1746                SREG,
1747                SRAM,
1748            }
1749        }
1750
1751        fn store_post_increment(
1752            state: &State,
1753            address_lo_index: Bitvector<5>,
1754            value_reg_index: Bitvector<5>,
1755        ) -> State {
1756            let address_hi_index = address_lo_index + Bitvector::<5>::new(1);
1757
1758            if (value_reg_index == address_lo_index) | (value_reg_index == address_hi_index) {
1759                panic!("Illegal store with post-increment to part of address register");
1760            }
1761
1762            let value = state.R[value_reg_index];
1763
1764            let address_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[address_lo_index]));
1765            let address_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[address_hi_index]));
1766            let address = (address_hi << Unsigned::<16>::new(8)) | address_lo;
1767
1768            // store
1769            let write_state: State =
1770                Self::write_data_mem(state, Into::<Bitvector<16>>::into(address), value);
1771
1772            let PC = write_state.PC;
1773            let mut R = Clone::clone(&write_state.R);
1774            let DDRB = write_state.DDRB;
1775            let PORTB = write_state.PORTB;
1776            let DDRC = write_state.DDRC;
1777            let PORTC = write_state.PORTC;
1778            let DDRD = write_state.DDRD;
1779            let PORTD = write_state.PORTD;
1780            let GPIOR0 = write_state.GPIOR0;
1781            let GPIOR1 = write_state.GPIOR1;
1782            let GPIOR2 = write_state.GPIOR2;
1783            let SPL = write_state.SPL;
1784            let SPH = write_state.SPH;
1785            let SREG = write_state.SREG;
1786            let SRAM = Clone::clone(&write_state.SRAM);
1787
1788            // post-increment
1789            let address_post = address + Unsigned::<16>::new(1);
1790            let address_lo_post = Into::<Bitvector<8>>::into(Ext::<8>::ext(address_post));
1791            let address_hi_post =
1792                Into::<Bitvector<8>>::into(Ext::<8>::ext(address_post >> Unsigned::<16>::new(8)));
1793            R[address_lo_index] = address_lo_post;
1794            R[address_hi_index] = address_hi_post;
1795
1796            State {
1797                PC,
1798                R,
1799                DDRB,
1800                PORTB,
1801                DDRC,
1802                PORTC,
1803                DDRD,
1804                PORTD,
1805                GPIOR0,
1806                GPIOR1,
1807                GPIOR2,
1808                SPL,
1809                SPH,
1810                SREG,
1811                SRAM,
1812            }
1813        }
1814
1815        fn store_pre_decrement(
1816            state: &State,
1817            address_lo_index: Bitvector<5>,
1818            value_reg_index: Bitvector<5>,
1819        ) -> State {
1820            let PC = state.PC;
1821            let mut R = Clone::clone(&state.R);
1822            let DDRB = state.DDRB;
1823            let PORTB = state.PORTB;
1824            let DDRC = state.DDRC;
1825            let PORTC = state.PORTC;
1826            let DDRD = state.DDRD;
1827            let PORTD = state.PORTD;
1828            let GPIOR0 = state.GPIOR0;
1829            let GPIOR1 = state.GPIOR1;
1830            let GPIOR2 = state.GPIOR2;
1831            let SPL = state.SPL;
1832            let SPH = state.SPH;
1833            let SREG = state.SREG;
1834            let SRAM = Clone::clone(&state.SRAM);
1835
1836            let address_hi_index = address_lo_index + Bitvector::<5>::new(1);
1837
1838            if (value_reg_index == address_lo_index) | (value_reg_index == address_hi_index) {
1839                panic!("Illegal store with pre-decrement to part of address register");
1840            }
1841
1842            let value = R[value_reg_index];
1843
1844            let old_address_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_lo_index]));
1845            let old_address_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(R[address_hi_index]));
1846            let old_address = (old_address_hi << Unsigned::<16>::new(8)) | old_address_lo;
1847
1848            // pre-decrement
1849            let address = old_address - Unsigned::<16>::new(1);
1850            let address_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(address));
1851            let address_hi =
1852                Into::<Bitvector<8>>::into(Ext::<8>::ext(address >> Unsigned::<16>::new(8)));
1853            R[address_lo_index] = address_lo;
1854            R[address_hi_index] = address_hi;
1855
1856            let pre_decrement_state = State {
1857                PC,
1858                R,
1859                DDRB,
1860                PORTB,
1861                DDRC,
1862                PORTC,
1863                DDRD,
1864                PORTD,
1865                GPIOR0,
1866                GPIOR1,
1867                GPIOR2,
1868                SPL,
1869                SPH,
1870                SREG,
1871                SRAM,
1872            };
1873
1874            // store
1875            let write_result: State = Self::write_data_mem(
1876                &pre_decrement_state,
1877                Into::<Bitvector<16>>::into(address),
1878                value,
1879            );
1880            write_result
1881        }
1882
1883        fn next_1001_001r(&self, state: &State, instruction: Bitvector<16>) -> State {
1884            let mut result = Clone::clone(state);
1885
1886            ::machine_check::bitmask_switch!(instruction {
1887
1888                // STS - 2 words
1889                "----_---r_rrrr_0000" => {
1890                    // store direct to data space from register r
1891
1892                    let mut PC = state.PC;
1893                    let R = Clone::clone(&state.R);
1894                    let DDRB = state.DDRB;
1895                    let PORTB = state.PORTB;
1896                    let DDRC = state.DDRC;
1897                    let PORTC = state.PORTC;
1898                    let DDRD = state.DDRD;
1899                    let PORTD = state.PORTD;
1900                    let GPIOR0 = state.GPIOR0;
1901                    let GPIOR1 = state.GPIOR1;
1902                    let GPIOR2 = state.GPIOR2;
1903                    let SPL = state.SPL;
1904                    let SPH = state.SPH;
1905                    let SREG = state.SREG;
1906                    let SRAM = Clone::clone(&state.SRAM);
1907
1908                    let value = R[r];
1909
1910                    // STS is a 2-word instruction, the address is in program memory in the next instruction location
1911                    // PC is already incremented to point to the next instruction, fetch it and increment PC once again before writing
1912                    let address = self.PROGMEM[PC];
1913                    PC = PC + Bitvector::<14>::new(1);
1914
1915                    let pc_incremented_state = State {
1916                        PC,
1917                        R,
1918                        DDRB,
1919                        PORTB,
1920                        DDRC,
1921                        PORTC,
1922                        DDRD,
1923                        PORTD,
1924                        GPIOR0,
1925                        GPIOR1,
1926                        GPIOR2,
1927                        SPL,
1928                        SPH,
1929                        SREG,
1930                        SRAM,
1931                    };
1932
1933                    result = Self::write_data_mem(&pc_incremented_state, Into::<Bitvector<16>>::into(address), value);
1934                }
1935
1936
1937                // ST Z+, Rr
1938                "----_---r_rrrr_0001" => {
1939                    // store to data memory pointed to by Z (30:31) with post-increment
1940                    result = Self::store_post_increment(state, Bitvector::<5>::new(30), r);
1941                }
1942
1943                // ST -Z, Rr
1944                "----_---r_rrrr_0010" => {
1945                    // store to data memory pointed to by Z (30:31) with pre-decrement
1946                    result = Self::store_pre_decrement(state, Bitvector::<5>::new(30), r);
1947                }
1948
1949                // 0011, 01--, 1000 reserved
1950                "----_---r_rrrr_0011" => {
1951                    panic!("Reserved opcode");
1952                }
1953                "----_---r_rrrr_01--" => {
1954                    panic!("Reserved opcode");
1955                }
1956                "----_---r_rrrr_1000" => {
1957                    panic!("Reserved opcode");
1958                }
1959
1960                // ST Y+, Rr
1961                "----_---r_rrrr_1001" => {
1962                    // store to data memory pointed to by Y (28:29) with post-increment
1963                    result = Self::store_post_increment(state, Bitvector::<5>::new(28), r);
1964                }
1965
1966                // ST -Y, Rr
1967                "----_---r_rrrr_1010" => {
1968                    // store to data memory pointed to by Y (28:29) with pre-decrement
1969                    result = Self::store_pre_decrement(state, Bitvector::<5>::new(28), r);
1970                }
1971
1972                // 1011 reserved
1973                "----_---r_rrrr_1011" => {
1974                    panic!("Reserved opcode");
1975                }
1976
1977                // ST X, Rr
1978                "----_---r_rrrr_1100" => {
1979                    // store data memory pointed to by X (26:27)
1980                    // register X does not support displacement, it is always 0
1981                    result = Self::store_with_displacement(state, Bitvector::<5>::new(26), r, Bitvector::<6>::new(0));
1982                }
1983
1984                // ST X+, Rr
1985                "----_---r_rrrr_1101" => {
1986                    // store to data memory pointed to by X (26:27) with post-increment
1987                    result = Self::store_post_increment(state, Bitvector::<5>::new(26), r);
1988                }
1989
1990                // ST -X, Rr
1991                "----_---r_rrrr_1110"  => {
1992                    // store to data memory pointed to by X (26:27) with pre-decrement
1993                    result = Self::store_pre_decrement(state, Bitvector::<5>::new(26), r);
1994                }
1995
1996                // PUSH
1997                "----_---r_rrrr_1111" => {
1998                    // store to data memory pointed to by stack pointer and post-decrement
1999
2000                    // note the instruction set manual uses 'd' for the push register opcode
2001                    // but it is referred to as 'r' everywhere else
2002
2003                    let value = state.R[r];
2004
2005                    let stack_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(state.SPL));
2006                    let stack_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(state.SPH));
2007                    let stack = (stack_hi << Unsigned::<16>::new(8)) | stack_lo;
2008                    let stack_post = stack - Unsigned::<16>::new(1);
2009
2010                    // make sure that the stack does not overflow from data memory down to extended I/O
2011                    // pointing to last extended I/O is not an overflow, as the data is not written there
2012                    if (stack < Unsigned::<16>::new(0x0099)) | (stack_post < Unsigned::<16>::new(0x0099)) {
2013                        panic!("Push overflows stack from data memory to extended I/O");
2014                    };
2015
2016                    let stack_sram_address_full = stack - Unsigned::<16>::new(0x0100);
2017
2018                    // only SRAM can be written to
2019                    let stack_sram_address = Ext::<11>::ext(stack_sram_address_full);
2020
2021                    if Ext::<16>::ext(stack_sram_address) != stack_sram_address_full {
2022                        panic!("Stack address higher than data memory on push");
2023                    };
2024
2025                    let PC = state.PC;
2026                    let R = Clone::clone(&state.R);
2027                    let DDRB = state.DDRB;
2028                    let PORTB = state.PORTB;
2029                    let DDRC = state.DDRC;
2030                    let PORTC = state.PORTC;
2031                    let DDRD = state.DDRD;
2032                    let PORTD = state.PORTD;
2033                    let GPIOR0 = state.GPIOR0;
2034                    let GPIOR1 = state.GPIOR1;
2035                    let GPIOR2 = state.GPIOR2;
2036                    let SREG = state.SREG;
2037                    let mut SRAM = Clone::clone(&state.SRAM);
2038
2039                    // write pushed value
2040                    SRAM[Into::<Bitvector<11>>::into(stack_sram_address)] = value;
2041
2042                    // update SPL/SPH to post-decrement
2043                    let SPL = Into::<Bitvector<8>>::into(Ext::<8>::ext(stack_post));
2044                    let SPH = Into::<Bitvector<8>>::into(Ext::<8>::ext(stack_post >> Unsigned::<16>::new(8)));
2045
2046                    result = State {
2047                        PC,
2048                        R,
2049                        DDRB,
2050                        PORTB,
2051                        DDRC,
2052                        PORTC,
2053                        DDRD,
2054                        PORTD,
2055                        GPIOR0,
2056                        GPIOR1,
2057                        GPIOR2,
2058                        SPL,
2059                        SPH,
2060                        SREG,
2061                        SRAM,
2062                    };
2063                    // PUSH is a two-cycle instruction
2064                }
2065            });
2066
2067            result
2068        }
2069
2070        fn next_1001_010x(&self, state: &State, instruction: Bitvector<16>) -> State {
2071            let mut PC = state.PC;
2072            let mut R = Clone::clone(&state.R);
2073            let DDRB = state.DDRB;
2074            let PORTB = state.PORTB;
2075            let DDRC = state.DDRC;
2076            let PORTC = state.PORTC;
2077            let DDRD = state.DDRD;
2078            let PORTD = state.PORTD;
2079            let GPIOR0 = state.GPIOR0;
2080            let GPIOR1 = state.GPIOR1;
2081            let GPIOR2 = state.GPIOR2;
2082            let mut SPL = state.SPL;
2083            let mut SPH = state.SPH;
2084            let mut SREG = state.SREG;
2085            let mut SRAM = Clone::clone(&state.SRAM);
2086
2087            ::machine_check::bitmask_switch!(instruction {
2088                // COM Rd
2089                "----_---d_dddd_0000" => {
2090                    // one's complement
2091                    R[d] = Bitvector::<8>::new(0xFF) - R[d];
2092                    SREG = Self::compute_status_com(SREG, R[d]);
2093                }
2094
2095                // NEG Rd
2096                "----_---d_dddd_0001" => {
2097                    // two's complement
2098                    let prev = R[d];
2099                    R[d] = Bitvector::<8>::new(0x00) - R[d];
2100                    SREG = Self::compute_status_neg(SREG, prev, R[d]);
2101                }
2102
2103                // SWAP Rd
2104                "----_---d_dddd_0010" => {
2105
2106                    let prev_unsigned = Into::<Unsigned<8>>::into(R[d]);
2107                    // swap nibbles in register, status flags not affected
2108                    let prev_lo_half = prev_unsigned & Unsigned::<8>::new(0x0F);
2109                    let prev_hi_half = prev_unsigned & Unsigned::<8>::new(0xF0);
2110                    let current_lo_half = prev_hi_half >> Unsigned::<8>::new(4);
2111                    let current_hi_half = prev_lo_half << Unsigned::<8>::new(4);
2112                    R[d] = Into::<Bitvector<8>>::into(current_hi_half | current_lo_half);
2113                }
2114
2115                // INC Rd
2116                "----_---d_dddd_0011" => {
2117
2118                    // increment
2119                    R[d] = R[d] + Bitvector::<8>::new(1);
2120
2121                    // the V flag is set exactly when R[d] after increment is 0x80
2122                    let mut flag_V = Bitvector::<1>::new(0);
2123                    if R[d] == Bitvector::<8>::new(0x7F) {
2124                        flag_V = Bitvector::<1>::new(1);
2125                    }
2126
2127                    SREG = Self::compute_status_inc_dec(SREG, R[d], flag_V);
2128                }
2129
2130                // 0100 is reserved
2131                "----_---d_dddd_0100" => {
2132                    panic!("Reserved opcode");
2133                }
2134
2135                // ASR Rd
2136                "----_---d_dddd_0101" => {
2137                    // arithmetic shift right
2138                    // treat as signed and shift one place right
2139                    let prev = R[d];
2140                    let prev_signed = Into::<Signed<8>>::into(prev);
2141                    let shifted_signed = prev_signed >> Into::<Signed<8>>::into(Bitvector::<8>::new(1));
2142                    R[d] = Into::<Bitvector<8>>::into(shifted_signed);
2143                    SREG = Self::compute_status_right_shift(SREG, prev, R[d]);
2144                }
2145
2146                // LSR Rd
2147                "----_---d_dddd_0110" => {
2148                    // logical shift right
2149                    // treat as unsigned and shift one place right
2150                    let prev = R[d];
2151                    let prev_unsigned = Into::<Unsigned<8>>::into(prev);
2152                    let shifted_unsigned = prev_unsigned >> Unsigned::<8>::new(1);
2153                    R[d] = Into::<Bitvector<8>>::into(shifted_unsigned);
2154                    SREG = Self::compute_status_right_shift(SREG, prev, R[d]);
2155                }
2156
2157                // ROR Rd
2158                "----_---d_dddd_0111" => {
2159                    // logical shift right
2160                    // first, treat as unsigned and shift one place right
2161                    let prev = R[d];
2162                    let prev_unsigned = Into::<Unsigned<8>>::into(prev);
2163                    let shifted_unsigned = prev_unsigned >> Unsigned::<8>::new(1);
2164                    R[d] = Into::<Bitvector<8>>::into(shifted_unsigned);
2165
2166                    // emplace the carry bit into the highest bit of new Rd
2167                    // the carry bit is in bit 0 of SREG, so mask it and shift up to bit 7
2168                    let SREG_masked_carry = SREG & Bitvector::<8>::new(0b0000_0000);
2169                    R[d] = R[d] | (SREG_masked_carry << Bitvector::<8>::new(7));
2170
2171                    // compute status like normal, the shifted-out bit will be rotated to carry
2172                    SREG = Self::compute_status_right_shift(SREG, prev, R[d]);
2173                }
2174
2175                // - opcodes only in 1011_0101 -
2176
2177                // BSET s
2178                "----_---0_0sss_1000" => {
2179                    // bit set in status register
2180                    let amount = Ext::<8>::ext(Into::<Unsigned<3>>::into(s));
2181                    SREG = SREG | Into::<Bitvector<8>>::into(Unsigned::<8>::new(1) << amount);
2182                }
2183
2184                // BCLR s
2185                "----_---0_1sss_1000" => {
2186                    // bit clear in status register
2187                    let amount = Ext::<8>::ext(Into::<Unsigned<3>>::into(s));
2188                    SREG = SREG & !(Into::<Bitvector<8>>::into(Unsigned::<8>::new(1) << amount));
2189                }
2190
2191                // IJMP
2192                "----_---0_0000_1001" => {
2193                    unimplemented!("IJMP instruction");
2194                }
2195
2196                // EIJMP
2197                "----_---0_0001_1001" => {
2198                    unimplemented!("EIJMP instruction");
2199                }
2200
2201                // other 1001_0100_----_1001 reserved
2202                "----_---0_001-_1001" => {
2203                    panic!("Reserved opcode");
2204                }
2205                "----_---0_01--_1001" => {
2206                    panic!("Reserved opcode");
2207                }
2208                "----_---0_1---_1001" => {
2209                    panic!("Reserved opcode");
2210                }
2211
2212                // DEC Rd
2213                "----_---d_dddd_1010" => {
2214
2215                    // decrement
2216                    R[d] = R[d] - Bitvector::<8>::new(1);
2217
2218                    // the V flag is set exactly when R[d] after decrement is 0x7F
2219                    let mut flag_V = Bitvector::<1>::new(0);
2220                    if R[d] == Bitvector::<8>::new(0x7F) {
2221                        flag_V = Bitvector::<1>::new(1);
2222                    }
2223
2224
2225                    SREG = Self::compute_status_inc_dec(SREG, R[d], flag_V);
2226
2227                }
2228
2229                // DES on ATxmega, reserved for non-ATxmega
2230                "----_---0_----_1011" => {
2231                    panic!("Reserved opcode (DES on ATxmega)");
2232                }
2233
2234                // JMP - 2 words
2235                "----_---k_kkkk_110k" => {
2236                    // PC is 14-bit on ATmega328p, the higher bits should be zero
2237                    if k != Bitvector::<6>::new(0) {
2238                        panic!("Jump outside program memory due to high word bits");
2239                    }
2240
2241                    let low_word = Into::<Unsigned<16>>::into(self.PROGMEM[PC]);
2242                    let target_pc = Ext::<14>::ext(low_word);
2243                    if Ext::<16>::ext(target_pc) != low_word {
2244                        panic!("Jump outside program memory due to low word bits");
2245                    }
2246
2247                    PC = Into::<Bitvector<14>>::into(target_pc);
2248
2249                    // JMP is a three-cycle instruction
2250                }
2251
2252                // CALL - 2 words
2253                "----_---k_kkkk_111k" => {
2254                    // call subroutine
2255                    // save 2-byte return address to stack and post-decrement SP
2256
2257                    // PC is 14-bit on ATmega328p, the higher bits should be zero
2258                    if k != Bitvector::<6>::new(0) {
2259                        panic!("Call outside program memory due to high word bits");
2260                    }
2261
2262                    let low_word = Into::<Unsigned<16>>::into(self.PROGMEM[PC]);
2263                    let target_pc = Ext::<14>::ext(low_word);
2264                    if Ext::<16>::ext(target_pc) != low_word {
2265                        panic!("Call outside program memory due to low word bits");
2266                    }
2267
2268                    let stack_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(SPL));
2269                    let stack_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(SPH));
2270                    let stack = (stack_hi << Unsigned::<16>::new(8)) | stack_lo;
2271
2272                    // the stack is decremented by 2 at the end
2273                    let stack_post = stack - Unsigned::<16>::new(2);
2274
2275                    // make sure that the stack does not overflow from data memory down to extended I/O
2276                    // pointing to last extended I/O is not an overflow, as the data is not written there
2277                    if (stack < Unsigned::<16>::new(0x0099)) | (stack_post < Unsigned::<16>::new(0x0099)) {
2278                        panic!("Call overflows stack from data memory to extended I/O");
2279                    };
2280
2281                    let stack_sram_address_full = stack - Unsigned::<16>::new(0x0100);
2282
2283                    // only SRAM can be written to
2284                    let stack_sram_address = Ext::<11>::ext(stack_sram_address_full);
2285                    let stack_sram_address_minus_1 = stack_sram_address - Unsigned::<11>::new(1);
2286
2287                    if Ext::<16>::ext(stack_sram_address) != stack_sram_address_full {
2288                        panic!("Stack address higher than data memory on call");
2289                    };
2290
2291                    // the address after the 2-byte call instruction is loaded
2292                    // PC was already incremented once, increment a second time to get the return address
2293                    let pc_unsigned = Into::<Unsigned<14>>::into(PC);
2294                    let return_address_unsigned = pc_unsigned + Unsigned::<14>::new(1);
2295                    let return_address_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(return_address_unsigned));
2296                    let return_address_hi = Into::<Bitvector<8>>::into(Ext::<8>::ext(return_address_unsigned >> Unsigned::<14>::new(8)));
2297
2298                    SRAM[Into::<Bitvector<11>>::into(stack_sram_address)] = return_address_lo;
2299                    SRAM[Into::<Bitvector<11>>::into(stack_sram_address_minus_1)] = return_address_hi;
2300
2301                    // update PC
2302                    PC = Into::<Bitvector<14>>::into(target_pc);
2303
2304                    // update SPL/SPH
2305                    SPL = Into::<Bitvector<8>>::into(Ext::<8>::ext(stack_post));
2306                    SPH = Into::<Bitvector<8>>::into(Ext::<8>::ext(stack_post >> Unsigned::<16>::new(8)));
2307
2308                    // CALL is a four-cycle instruction on 16-bit PC devices
2309                }
2310
2311                // -  opcodes only in 1011_0110 -
2312
2313                // RET
2314                "----_---1_0000_1000" => {
2315                    // return from subroutine
2316                    // pre-increment SP and load 2-byte PC value from stack
2317
2318                    let old_stack_lo = Ext::<16>::ext(Into::<Unsigned<8>>::into(SPL));
2319                    let old_stack_hi = Ext::<16>::ext(Into::<Unsigned<8>>::into(SPH));
2320                    let old_stack = (old_stack_hi << Unsigned::<16>::new(8)) | old_stack_lo;
2321                    let address_pc_hi = old_stack + Unsigned::<16>::new(1);
2322                    let address_pc_lo = address_pc_hi + Unsigned::<16>::new(1);
2323
2324                    let new_stack = address_pc_lo;
2325
2326                    // update SPL/SPH
2327                    SPL = Into::<Bitvector<8>>::into(Ext::<8>::ext(new_stack));
2328                    SPH = Into::<Bitvector<8>>::into(Ext::<8>::ext(new_stack >> Unsigned::<16>::new(8)));
2329
2330                    // stack should be in data memory
2331                    if address_pc_hi < Unsigned::<16>::new(0x0100) {
2332                        panic!("Return with overflowed stack");
2333                    };
2334                    let sram_address_pc_hi_full = address_pc_hi - Unsigned::<16>::new(0x0100);
2335                    let sram_address_pc_lo_full = address_pc_lo - Unsigned::<16>::new(0x0100);
2336
2337                    let sram_address_pc_hi = Ext::<11>::ext(sram_address_pc_hi_full);
2338                    let sram_address_pc_lo = Ext::<11>::ext(sram_address_pc_lo_full);
2339
2340                    if (Ext::<16>::ext(sram_address_pc_hi) != sram_address_pc_hi_full)
2341                    | (Ext::<16>::ext(sram_address_pc_lo) != sram_address_pc_lo_full) {
2342                        panic!("Return underflows stack from data memory");
2343                    };
2344
2345                    let pc_lo = SRAM[Into::<Bitvector<11>>::into(sram_address_pc_lo)];
2346                    let pc_hi = SRAM[Into::<Bitvector<11>>::into(sram_address_pc_hi)];
2347
2348                    let pc_lo_ext = Ext::<16>::ext(Into::<Unsigned<8>>::into(pc_lo));
2349                    let pc_hi_ext = Ext::<16>::ext(Into::<Unsigned<8>>::into(pc_hi));
2350                    let new_pc_full = (pc_hi_ext << Unsigned::<16>::new(8)) | pc_lo_ext;
2351
2352                    let new_pc = Ext::<14>::ext(new_pc_full);
2353                    if Ext::<16>::ext(new_pc) != new_pc_full {
2354                        panic!("Return address does not fit into program counter");
2355                    }
2356
2357                    PC = Into::<Bitvector<14>>::into(new_pc);
2358
2359                    // RET is a four-cycle instruction on 16-bit PC devices
2360                }
2361
2362                // RETI
2363                "----_---1_0001_1000" => {
2364                    unimplemented!("RETI instruction");
2365                }
2366
2367                // next 6 reserved
2368
2369                "----_---1_001-_1000" => {
2370                    panic!("Reserved opcode");
2371                }
2372
2373                "----_---1_01--_1000" => {
2374                    panic!("Reserved opcode");
2375                }
2376
2377                // SLEEP
2378                "----_---1_1000_1000" => {
2379                    unimplemented!("SLEEP instruction");
2380                }
2381
2382                // BREAK
2383                "----_---1_1001_1000" => {
2384                    // break the execution when debugging
2385                    unimplemented!("BREAK instruction");
2386                }
2387
2388                // WDR
2389                "----_---1_1010_1000" => {
2390                    unimplemented!("WDR instruction");
2391                }
2392
2393                // next one reserved
2394                "----_---1_1011_1000" => {
2395                    unimplemented!("WDR instruction");
2396                }
2397
2398                // LPM (implied R0 destination)
2399                "----_---1_1100_1000" => {
2400                    unimplemented!("LPM instruction");
2401                    /*
2402                    // load program memory
2403
2404                    //R[0] = fetchProgramByte(Z);
2405                    unimplemented();
2406
2407                    // LPM is a three-cycle instruction
2408                    increment_cycle_count();
2409                    increment_cycle_count();
2410                    */
2411                }
2412
2413                // ELPM
2414                "----_---1_1101_1000" => {
2415                    unimplemented!("ELPM instruction");
2416                    /*
2417                    //R[0] = PROGRAM[RAMPZ:Z];
2418                    */
2419                }
2420
2421                // SPM
2422                "----_---1_1110_1000" => {
2423                    unimplemented!("SPM instruction");
2424                }
2425
2426                // next one reserved (SPM on ATxmega)
2427
2428                "----_---1_1111_1000" => {
2429                    unimplemented!("Reserved opcode (SPM on ATxmega)");
2430                }
2431
2432                // ICALL
2433                "----_---1_0000_1001" => {
2434                    unimplemented!("ICALL instruction");
2435                }
2436
2437                // EICALL
2438                "----_---1_0001_1001" => {
2439                    unimplemented!("EICALL instruction");
2440                }
2441
2442                // other 1001_010-_----_1001 reserved
2443                "----_---1_001-_1001" => {
2444                    panic!("Reserved opcode");
2445                }
2446                "----_---1_01--_1001" => {
2447                    panic!("Reserved opcode");
2448                }
2449                "----_---1_1---_1001" => {
2450                    panic!("Reserved opcode");
2451                }
2452                "----_---1_----_1011" => {
2453                    panic!("Reserved opcode");
2454                }
2455
2456            });
2457
2458            State {
2459                PC,
2460                R,
2461                DDRB,
2462                PORTB,
2463                DDRC,
2464                PORTC,
2465                DDRD,
2466                PORTD,
2467                GPIOR0,
2468                GPIOR1,
2469                GPIOR2,
2470                SPL,
2471                SPH,
2472                SREG,
2473                SRAM,
2474            }
2475        }
2476
2477        fn next_1001_011x(state: &State, instruction: Bitvector<16>) -> State {
2478            let PC = state.PC;
2479            let mut R = Clone::clone(&state.R);
2480            let DDRB = state.DDRB;
2481            let PORTB = state.PORTB;
2482            let DDRC = state.DDRC;
2483            let PORTC = state.PORTC;
2484            let DDRD = state.DDRD;
2485            let PORTD = state.PORTD;
2486            let GPIOR0 = state.GPIOR0;
2487            let GPIOR1 = state.GPIOR1;
2488            let GPIOR2 = state.GPIOR2;
2489            let SPL = state.SPL;
2490            let SPH = state.SPH;
2491            let mut SREG = state.SREG;
2492            let SRAM = Clone::clone(&state.SRAM);
2493
2494            ::machine_check::bitmask_switch!(instruction {
2495                // ADIW Rd, K
2496                "----_---0_kkdd_kkkk" => {
2497
2498                    // add immediate to register word
2499                    // only available for register pairs r24:r25, r26:r27, r28:29, r30:r31
2500                    // extend d to five bits, double it, and add 24 to get low register index
2501                    let d_unsigned = Into::<Unsigned<2>>::into(d);
2502                    let d_ext = Into::<Bitvector<5>>::into(Ext::<5>::ext(d_unsigned));
2503                    let double_d_ext = d_ext + d_ext;
2504                    let lo_reg_num = double_d_ext + Bitvector::<5>::new(24);
2505                    let hi_reg_num = lo_reg_num + Bitvector::<5>::new(1);
2506
2507                    // construct the little-endian pair (low index corresponds to low bits)
2508                    let lo_reg_unsigned = Into::<Unsigned<8>>::into(R[lo_reg_num]);
2509                    let hi_reg_unsigned = Into::<Unsigned<8>>::into(R[hi_reg_num]);
2510
2511                    let lo_reg_ext = Ext::<16>::ext(lo_reg_unsigned);
2512                    let hi_reg_ext = Ext::<16>::ext(hi_reg_unsigned);
2513                    let pair = (hi_reg_ext << Unsigned::<16>::new(8)) | lo_reg_ext;
2514
2515                    let k_unsigned = Into::<Unsigned<6>>::into(k);
2516                    let result_pair = pair + Ext::<16>::ext(k_unsigned);
2517
2518                    let result_lo = Ext::<8>::ext(result_pair);
2519                    let result_hi = Ext::<8>::ext(result_pair >> Unsigned::<16>::new(8));
2520
2521                    R[lo_reg_num] = Into::<Bitvector<8>>::into(result_lo);
2522                    R[hi_reg_num] = Into::<Bitvector<8>>::into(result_hi);
2523
2524
2525
2526                    SREG = Self::compute_status_adiw(SREG, Into::<Bitvector<16>>::into(pair), Into::<Bitvector<16>>::into(result_pair));
2527
2528                    // ADIW is a two-cycle instruction
2529
2530                }
2531
2532                // SBIW Rd, K
2533                "----_---1_kkdd_kkkk" => {
2534                    // subtract immediate from register word
2535                    // only available for register pairs r24:r25, r26:r27, r28:29, r30:r31
2536                    // extend d to five bits, double it, and add 24 to get low register index
2537                    let d_unsigned = Into::<Unsigned<2>>::into(d);
2538                    let d_ext = Into::<Bitvector<5>>::into(Ext::<5>::ext(d_unsigned));
2539                    let double_d_ext = d_ext + d_ext;
2540                    let lo_reg_num = double_d_ext + Bitvector::<5>::new(24);
2541                    let hi_reg_num = lo_reg_num + Bitvector::<5>::new(1);
2542
2543                    // construct the little-endian pair (low index corresponds to low bits)
2544                    let lo_reg_unsigned = Into::<Unsigned<8>>::into(R[lo_reg_num]);
2545                    let hi_reg_unsigned = Into::<Unsigned<8>>::into(R[hi_reg_num]);
2546
2547                    let lo_reg_ext = Ext::<16>::ext(lo_reg_unsigned);
2548                    let hi_reg_ext = Ext::<16>::ext(hi_reg_unsigned);
2549                    let pair = (hi_reg_ext << Unsigned::<16>::new(8)) | lo_reg_ext;
2550
2551                    let k_unsigned = Into::<Unsigned<6>>::into(k);
2552                    let result_pair = pair - Ext::<16>::ext(k_unsigned);
2553
2554
2555                    let result_lo = Ext::<8>::ext(result_pair);
2556                    let result_hi = Ext::<8>::ext(result_pair >> Unsigned::<16>::new(8));
2557
2558                    R[lo_reg_num] = Into::<Bitvector<8>>::into(result_lo);
2559                    R[hi_reg_num] = Into::<Bitvector<8>>::into(result_hi);
2560
2561                    SREG = Self::compute_status_sbiw(SREG, Into::<Bitvector<16>>::into(pair), Into::<Bitvector<16>>::into(result_pair));
2562
2563                    // SBIW is a two-cycle instruction
2564                }
2565            });
2566
2567            State {
2568                PC,
2569                R,
2570                DDRB,
2571                PORTB,
2572                DDRC,
2573                PORTC,
2574                DDRD,
2575                PORTD,
2576                GPIOR0,
2577                GPIOR1,
2578                GPIOR2,
2579                SPL,
2580                SPH,
2581                SREG,
2582                SRAM,
2583            }
2584        }
2585
2586        fn next_1001(&self, state: &State, input: &Input, instruction: Bitvector<16>) -> State {
2587            let mut result = Clone::clone(state);
2588
2589            ::machine_check::bitmask_switch!(instruction {
2590                "----_000-_----_----" => {
2591                    result = Self::next_1001_000d(self, state, input, instruction);
2592                }
2593                "----_001-_----_----" => {
2594                    result = Self::next_1001_001r(self, state, instruction);
2595                }
2596                "----_010-_----_----" => {
2597                    result = Self::next_1001_010x(self, state, instruction);
2598                }
2599                "----_011-_----_----" => {
2600                    result = Self::next_1001_011x(state, instruction);
2601                }
2602
2603                // v=0: CBI A, b
2604                // v=1: SBI A, b
2605                "----_10v0_aaaa_abbb" => {
2606                    // clear/set bit in I/O register, status flags not affected
2607
2608                    // we can do this by read-modify-write
2609                    // on all implemented I/O registers except for PINx, resolve these differently
2610
2611                    let b_shift = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<3>>::into(b)));
2612                    let b_mask = Bitvector::<8>::new(1) << b_shift;
2613                    let b_value = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<1>>::into(v))) << b_shift;
2614
2615                    // PINx can be set with all other bits being 0, so they do not flip
2616                    let mut retained_bits = Bitvector::<8>::new(0);
2617
2618                    // only lower 32 registers are supported by SBI/CBI, zero-extend
2619                    let ext_a = Into::<Bitvector<6>>::into(Ext::<6>::ext(Into::<Unsigned<5>>::into(a)));
2620
2621                    // get the retained bits for all others
2622                    if (a != Bitvector::<5>::new(0x3)) & (a != Bitvector::<5>::new(0x6)) & (a == Bitvector::<5>::new(0x9)) {
2623                        let read_bits: Bitvector<8> = Self::read_io_reg(state, input, ext_a);
2624                        retained_bits = read_bits & !b_mask;
2625                    }
2626                    // write the bits
2627                    let write_bits = retained_bits | b_value;
2628                    result = Self::write_io_reg(state, ext_a, write_bits);
2629                    // CBI / SBI is a two-cycle instruction
2630                }
2631
2632                // v=0: SBIC A, b
2633                // v=1: SBIS A, b
2634                "----_10v1_aaaa_abbb" => {
2635                    // skip if bit in I/O register is cleared/set
2636
2637                    // read I/O register value and determine if we should skip
2638
2639                    let b_shift = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<3>>::into(b)));
2640                    let b_mask = Bitvector::<8>::new(1) << b_shift;
2641                    let b_value = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<1>>::into(v))) << b_shift;
2642
2643                    // only lower 32 registers are supported by SBIS/SBIC, zero-extend
2644                    let ext_a = Into::<Bitvector<6>>::into(Ext::<6>::ext(Into::<Unsigned<5>>::into(a)));
2645
2646                    // read bits
2647                    let read_bits: Bitvector<8> = Self::read_io_reg(state, input, ext_a);
2648
2649                    let R = Clone::clone(&result.R);
2650                    let mut PC = state.PC;
2651                    let DDRB = state.DDRB;
2652                    let PORTB = state.PORTB;
2653                    let DDRC = state.DDRC;
2654                    let PORTC = state.PORTC;
2655                    let DDRD = state.DDRD;
2656                    let PORTD = state.PORTD;
2657                    let GPIOR0 = state.GPIOR0;
2658                    let GPIOR1 = state.GPIOR1;
2659                    let GPIOR2 = state.GPIOR2;
2660                    let SPL = state.SPL;
2661                    let SPH = state.SPH;
2662                    let SREG = state.SREG;
2663                    let SRAM = Clone::clone(&result.SRAM);
2664
2665                    // determine if we should skip
2666                    if (read_bits & b_mask) == b_value {
2667                        // skip next instruction
2668                        PC = Self::instruction_skip(self, PC);
2669                    }
2670
2671                    result =
2672                    State {
2673                        PC,
2674                        R,
2675                        DDRB,
2676                        PORTB,
2677                        DDRC,
2678                        PORTC,
2679                        DDRD,
2680                        PORTD,
2681                        GPIOR0,
2682                        GPIOR1,
2683                        GPIOR2,
2684                        SPL,
2685                        SPH,
2686                        SREG,
2687                        SRAM,
2688                    };
2689                }
2690
2691                // MUL
2692                "----_11rd_dddd_rrrr" => {
2693                    // multiply unsigned by unsigned
2694                    let d_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[d])));
2695                    let r_ext = Into::<Bitvector<16>>::into(Ext::<16>::ext(Into::<Unsigned<8>>::into(state.R[r])));
2696
2697                    let mul_result = d_ext * r_ext;
2698                    let mul_result_lo = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(mul_result)));
2699                    let mul_result_hi = Into::<Bitvector<8>>::into(Ext::<8>::ext(Into::<Unsigned<16>>::into(mul_result) >> Unsigned::<16>::new(8)));
2700
2701                    let mut R = Clone::clone(&result.R);
2702                    let PC = state.PC;
2703                    let DDRB = state.DDRB;
2704                    let PORTB = state.PORTB;
2705                    let DDRC = state.DDRC;
2706                    let PORTC = state.PORTC;
2707                    let DDRD = state.DDRD;
2708                    let PORTD = state.PORTD;
2709                    let GPIOR0 = state.GPIOR0;
2710                    let GPIOR1 = state.GPIOR1;
2711                    let GPIOR2 = state.GPIOR2;
2712                    let SPL = state.SPL;
2713                    let SPH = state.SPH;
2714                    let SRAM = Clone::clone(&result.SRAM);
2715
2716                    // store result low byte into register 0 and high byte into register 1
2717                    R[Bitvector::<5>::new(0)] = mul_result_lo;
2718                    R[Bitvector::<5>::new(1)] = mul_result_hi;
2719
2720                    // update status register
2721                    let SREG: Bitvector<8> = Self::compute_status_mul(state.SREG, mul_result, mul_result);
2722
2723                    result =
2724                    State {
2725                        PC,
2726                        R,
2727                        DDRB,
2728                        PORTB,
2729                        DDRC,
2730                        PORTC,
2731                        DDRD,
2732                        PORTD,
2733                        GPIOR0,
2734                        GPIOR1,
2735                        GPIOR2,
2736                        SPL,
2737                        SPH,
2738                        SREG,
2739                        SRAM,
2740                    };
2741                }
2742            });
2743
2744            result
2745        }
2746
2747        fn next_1011(state: &State, input: &Input, instruction: Bitvector<16>) -> State {
2748            let mut result = Clone::clone(state);
2749
2750            ::machine_check::bitmask_switch!(instruction {
2751                // IN
2752                "----_0aad_dddd_aaaa" => {
2753                    // load I/O location to register, status flags not affected
2754                    let PC = state.PC;
2755                    let mut R = Clone::clone(&state.R);
2756                    let DDRB = state.DDRB;
2757                    let PORTB = state.PORTB;
2758                    let DDRC = state.DDRC;
2759                    let PORTC = state.PORTC;
2760                    let DDRD = state.DDRD;
2761                    let PORTD = state.PORTD;
2762                    let GPIOR0 = state.GPIOR0;
2763                    let GPIOR1 = state.GPIOR1;
2764                    let GPIOR2 = state.GPIOR2;
2765                    let SPL = state.SPL;
2766                    let SPH = state.SPH;
2767                    let SREG = state.SREG;
2768                    let SRAM = Clone::clone(&state.SRAM);
2769
2770                    let io_result: Bitvector<8> = Self::read_io_reg(state, input, a);
2771                    R[d] = io_result;
2772
2773                    result = State {
2774                        PC,
2775                        R,
2776                        DDRB,
2777                        PORTB,
2778                        DDRC,
2779                        PORTC,
2780                        DDRD,
2781                        PORTD,
2782                        GPIOR0,
2783                        GPIOR1,
2784                        GPIOR2,
2785                        SPL,
2786                        SPH,
2787                        SREG,
2788                        SRAM,
2789                    };
2790                }
2791
2792                // OUT
2793                "----_1aar_rrrr_aaaa" => {
2794                    // store register to I/O location, status flags not affected
2795                    result = Self::write_io_reg(state, a, state.R[r]);
2796                }
2797            });
2798
2799            result
2800        }
2801
2802        fn next_11(&self, state: &State, instruction: Bitvector<16>) -> State {
2803            let mut PC = state.PC;
2804            let mut R = Clone::clone(&state.R);
2805            let DDRB = state.DDRB;
2806            let PORTB = state.PORTB;
2807            let DDRC = state.DDRC;
2808            let PORTC = state.PORTC;
2809            let DDRD = state.DDRD;
2810            let PORTD = state.PORTD;
2811            let GPIOR0 = state.GPIOR0;
2812            let GPIOR1 = state.GPIOR1;
2813            let GPIOR2 = state.GPIOR2;
2814            let SPL = state.SPL;
2815            let SPH = state.SPH;
2816            let mut SREG = state.SREG;
2817            let SRAM = Clone::clone(&state.SRAM);
2818
2819            ::machine_check::bitmask_switch!(instruction {
2820
2821                // RJMP
2822                "--00_kkkk_kkkk_kkkk" => {
2823
2824                    // relative jump
2825                    // we have already added 1 before case, just add adjusted k
2826                    // it is represented in 12-bit two's complement, we need to sign-extend to 14 bits
2827                    let k_signed = Into::<Signed<12>>::into(k);
2828                    let k_signed_ext = Ext::<14>::ext(k_signed);
2829                    let k_ext = Into::<Bitvector<14>>::into(k_signed_ext);
2830                    // jump
2831                    PC = PC + k_ext;
2832
2833                    // RJMP is a two-cycle instruction
2834                }
2835
2836                // --- 1101 ---
2837
2838                // RCALL
2839                "--01_kkkk_kkkk_kkkk" => {
2840                    unimplemented!("RCALL instruction");
2841                }
2842
2843                // --- 1110 ---
2844                // LDI
2845                "--10_kkkk_dddd_kkkk" => {
2846                    // extend d to five bits and add 16
2847                    let d_unsigned = Into::<Unsigned<4>>::into(d);
2848                    let d_ext_unsigned = Ext::<5>::ext(d_unsigned);
2849                    let d_ext = Into::<Bitvector<5>>::into(d_ext_unsigned);
2850                    let reg_num = d_ext + Bitvector::<5>::new(16);
2851
2852                    // load immediate, status flags not affected
2853                    R[reg_num] = k;
2854                }
2855
2856                // --- 1111 ---
2857
2858                // BRBS
2859                "--11_00kk_kkkk_ksss" => {
2860                    let s_unsigned = Into::<Unsigned<3>>::into(s);
2861                    let s_unsigned_ext =  Ext::<8>::ext(s_unsigned);
2862                    let unsigned_bit_mask = Unsigned::<8>::new(1) << s_unsigned_ext;
2863                    let bit_mask = Into::<Bitvector<8>>::into(unsigned_bit_mask);
2864
2865                    // branch if bit in SREG is set
2866                    // we have already added 1 to PC before case
2867                    if SREG & bit_mask == bit_mask {
2868                        // it is set, branch
2869                        // represent k as signed and sign-extend
2870
2871                        let k_signed = Into::<Signed<7>>::into(k);
2872                        let k_signed_ext = Ext::<14>::ext(k_signed);
2873                        let k_ext = Into::<Bitvector<14>>::into(k_signed_ext);
2874                        // jump
2875                        PC = PC + k_ext;
2876                        // since we branched, one more cycle is taken by this instruction
2877                    } else {
2878                        // it is cleared, do nothing
2879                    };
2880                }
2881
2882                // BRBC
2883                "--11_01kk_kkkk_ksss" => {
2884                    let s_unsigned = Into::<Unsigned<3>>::into(s);
2885                    let s_unsigned_ext =  Ext::<8>::ext(s_unsigned);
2886                    let unsigned_bit_mask = Unsigned::<8>::new(1) << s_unsigned_ext;
2887                    let bit_mask = Into::<Bitvector<8>>::into(unsigned_bit_mask);
2888
2889                    // branch if bit in SREG is cleared
2890                    // we have already added 1 to PC before case
2891                    if SREG & bit_mask == bit_mask {
2892                        // it is set, do nothing
2893                    } else {
2894                        // it is cleared, branch
2895                        // represent k as signed and sign-extend
2896
2897                        let k_signed = Into::<Signed<7>>::into(k);
2898                        let k_signed_ext = Ext::<14>::ext(k_signed);
2899                        let k_ext = Into::<Bitvector<14>>::into(k_signed_ext);
2900                        // jump
2901                        PC = PC + k_ext;
2902                        // since we branched, one more cycle is taken by this instruction
2903                    };
2904                }
2905
2906                // BLD
2907                "--11_100d_dddd_0bbb" => {
2908                    // copy from flag T (bit 6) of SREG to bit b of register Rd
2909
2910                    let SREG_unsigned = Into::<Unsigned<8>>::into(SREG);
2911                    let SREG_masked = SREG_unsigned & Unsigned::<8>::new(0b0100_0000);
2912                    let lowest_bit_T = SREG_masked >> Unsigned::<8>::new(6);
2913
2914                    let amount = Ext::<8>::ext(Into::<Unsigned<3>>::into(b));
2915                    let bit_only_mask = Into::<Bitvector<8>>::into(Unsigned::<8>::new(1) << amount);
2916                    let bit_only_T = Into::<Bitvector<8>>::into(lowest_bit_T << amount);
2917
2918                    R[d] = (R[d] & !bit_only_mask) | bit_only_T;
2919                }
2920
2921                // 1xxx part reserved
2922                "--11_100-_----_1---" => {
2923                    panic!("Reserved opcode");
2924                }
2925
2926                // BST
2927                "--11_101d_dddd_0bbb" => {
2928                    // store bit b from register Rd to flag T (bit 6) of SREG
2929                    let amount = Ext::<8>::ext(Into::<Unsigned<3>>::into(b));
2930                    let Rd_unsigned = Into::<Unsigned<8>>::into(R[d]);
2931                    let lowest_bit_T = (Rd_unsigned >> amount) & Unsigned::<8>::new(1);
2932
2933                    let retained_flags = Bitvector::<8>::new(0b1011_1111);
2934                    let bit_only_T = Into::<Bitvector<8>>::into(lowest_bit_T << Unsigned::<8>::new(6));
2935
2936                    SREG = (SREG & retained_flags) | bit_only_T;
2937                }
2938
2939                // 1xxx part reserved
2940                "--11_101-_----_1---" => {
2941                    panic!("Reserved opcode");
2942                }
2943
2944                // SBRC
2945                "--11_110r_rrrr_0bbb" => {
2946                    // skip if bit in register is cleared
2947                    let b_unsigned = Into::<Unsigned<3>>::into(b);
2948                    let b_unsigned_ext =  Ext::<8>::ext(b_unsigned);
2949                    let unsigned_bit_mask = Unsigned::<8>::new(1) << b_unsigned_ext;
2950                    let bit_mask = Into::<Bitvector<8>>::into(unsigned_bit_mask);
2951
2952                    if R[r] & bit_mask == bit_mask {
2953                        // it is set, do nothing
2954                    } else {
2955                        // it is cleared, skip next instruction
2956                        PC = Self::instruction_skip(self, PC);
2957                    };
2958                }
2959
2960                // 1xxx part reserved
2961                "--11_110-_----_1---" => {
2962                    panic!("Reserved opcode");
2963                }
2964
2965                // SBRS
2966                "--11_111r_rrrr_0bbb" => {
2967                    // skip if bit in register is set
2968                    let b_unsigned = Into::<Unsigned<3>>::into(b);
2969                    let b_unsigned_ext =  Ext::<8>::ext(b_unsigned);
2970                    let unsigned_bit_mask = Unsigned::<8>::new(1) << b_unsigned_ext;
2971                    let bit_mask = Into::<Bitvector<8>>::into(unsigned_bit_mask);
2972
2973                    if R[r] & bit_mask == bit_mask {
2974                        // it is set, skip next instruction
2975                        PC = Self::instruction_skip(self, PC);
2976                    } else {
2977                        // it is cleared, do nothing
2978                    };
2979                }
2980
2981                // 1xxx part reserved
2982                "--11_111-_----_1---" => {
2983                    panic!("Reserved opcode");
2984                }
2985            });
2986
2987            State {
2988                PC,
2989                R,
2990                DDRB,
2991                PORTB,
2992                DDRC,
2993                PORTC,
2994                DDRD,
2995                PORTD,
2996                GPIOR0,
2997                GPIOR1,
2998                GPIOR2,
2999                SPL,
3000                SPH,
3001                SREG,
3002                SRAM,
3003            }
3004        }
3005    }
3006
3007    impl ::machine_check::Machine for ATmega328P {
3008        type Input = Input;
3009        type Param = Param;
3010        type State = State;
3011
3012        fn init(&self, input: &Input, _param: &Param) -> State {
3013            // --- Program Counter ---
3014            // initialized to 0 after reset
3015            let PC = Bitvector::<14>::new(0);
3016
3017            // --- General Purpose Registers ---
3018            // uninitialized after reset
3019            let R = Clone::clone(&input.uninit_R);
3020
3021            // --- I/O Registers ---
3022
3023            // Port B: DDRB and PORTB initialized to 0 after reset
3024            let DDRB = Bitvector::<8>::new(0);
3025            let PORTB = Bitvector::<8>::new(0);
3026
3027            // Port C: DDRC and PORTC initialized to 0 after reset
3028            let DDRC = Bitvector::<7>::new(0);
3029            let PORTC = Bitvector::<7>::new(0);
3030
3031            // Port D: DDRD and PORTD initialized to 0 after reset
3032            let DDRD = Bitvector::<8>::new(0);
3033            let PORTD = Bitvector::<8>::new(0);
3034
3035            // General Purpose I/O registers
3036            // initialized to 0 after reset
3037            let GPIOR0 = Bitvector::<8>::new(0);
3038            let GPIOR1 = Bitvector::<8>::new(0);
3039            let GPIOR2 = Bitvector::<8>::new(0);
3040
3041            // Stack Pointer
3042            // initialized to last address of SRAM, known as RAMEND
3043            // in case of ATmega328P, RAMEND is 0x8FF (7810D–AVR–01/15 p. 13, 18)
3044            // SP = 0x08FF;
3045            let SPL = Bitvector::<8>::new(0xFF);
3046            let SPH = Bitvector::<8>::new(0x08);
3047
3048            // Status Register
3049            // initialized to 0 after reset
3050            let SREG = Bitvector::<8>::new(0x00);
3051
3052            // --- SRAM ---
3053            let SRAM = Clone::clone(&input.uninit_SRAM);
3054
3055            // --- EEPROM ---
3056            // EEPROM is unchangeable as SPM is not supported
3057
3058            State {
3059                PC,
3060                R,
3061                DDRB,
3062                PORTB,
3063                DDRC,
3064                PORTC,
3065                DDRD,
3066                PORTD,
3067                GPIOR0,
3068                GPIOR1,
3069                GPIOR2,
3070                SPL,
3071                SPH,
3072                SREG,
3073                SRAM,
3074            }
3075        }
3076
3077        fn next(&self, state: &State, input: &Input, _param: &Param) -> State {
3078            let mut PC = state.PC;
3079            let R = Clone::clone(&state.R);
3080            let DDRB = state.DDRB;
3081            let PORTB = state.PORTB;
3082            let DDRC = state.DDRC;
3083            let PORTC = state.PORTC;
3084            let DDRD = state.DDRD;
3085            let PORTD = state.PORTD;
3086            let GPIOR0 = state.GPIOR0;
3087            let GPIOR1 = state.GPIOR1;
3088            let GPIOR2 = state.GPIOR2;
3089            let SPL = state.SPL;
3090            let SPH = state.SPH;
3091            let SREG = state.SREG;
3092            let SRAM = Clone::clone(&state.SRAM);
3093
3094            // --- Instruction Step ---
3095
3096            // fetch instruction and increment PC
3097            let instruction = self.PROGMEM[state.PC];
3098
3099            // increment PC
3100            PC = PC + Bitvector::<14>::new(1);
3101
3102            let state = State {
3103                PC,
3104                R,
3105                DDRB,
3106                PORTB,
3107                DDRC,
3108                PORTC,
3109                DDRD,
3110                PORTD,
3111                GPIOR0,
3112                GPIOR1,
3113                GPIOR2,
3114                SPL,
3115                SPH,
3116                SREG,
3117                SRAM,
3118            };
3119
3120            let mut result = Clone::clone(&state);
3121
3122            ::machine_check::bitmask_switch!(instruction {
3123                "0000_----_----_----" => {
3124                    result = Self::next_0000(&state, instruction);
3125                }
3126                "0001_----_----_----" => {
3127                    result = Self::next_0001(self, &state, instruction);
3128                }
3129                "0010_----_----_----" => {
3130                    result = Self::next_0010(&state, instruction);
3131                }
3132                "0011_----_----_----" => {
3133                    result = Self::next_0011(&state, instruction);
3134                }
3135                "01--_----_----_----" => {
3136                    result = Self::next_01(&state, instruction);
3137                }
3138                "10-0_----_----_----" => {
3139                    result = Self::next_10q0(&state, input, instruction);
3140                }
3141                "1001_----_----_----" => {
3142                    result = Self::next_1001(self, &state, input, instruction);
3143                }
3144                "1011_----_----_----" => {
3145                    result = Self::next_1011(&state, input, instruction);
3146
3147                }
3148                "11--_----_----_----" => {
3149                    result = Self::next_11(self, &state, instruction);
3150                }
3151            });
3152
3153            // interrupts are not implemented, so make sure the Global Interrupt Flag
3154            // is not enabled
3155            if result.SREG & Bitvector::<8>::new(0x80) != Bitvector::<8>::new(0x00) {
3156                unimplemented!("Interrupts");
3157            }
3158
3159            result
3160        }
3161    }
3162}