trapezoid_core/
controller_mem_card.rs

1use crate::memory::{interrupts::InterruptRequester, BusLine, Result};
2use bitflags::bitflags;
3
4use std::collections::VecDeque;
5
6#[derive(Clone, Copy)]
7pub enum DigitalControllerKey {
8    Select,
9    L3,
10    R3,
11    Start,
12    Up,
13    Right,
14    Down,
15    Left,
16    L2,
17    R2,
18    L1,
19    R1,
20    Triangle,
21    Circle,
22    X,
23    Square,
24}
25
26impl DigitalControllerKey {
27    fn mask(&self) -> u16 {
28        1 << *self as u16
29    }
30}
31
32const JOY_CTRL_ACKKNOWLEDGE: u16 = 0b0000000000010000;
33const JOY_CTRL_RESET: u16 = 0b0000000001000000;
34bitflags! {
35    #[derive(Default, Debug)]
36    struct JoyControl: u16 {
37        const TX_ENABLE            = 0b0000000000000001;
38        const JOY_SELECT           = 0b0000000000000010;
39        const RX_FORCE_ENABLE      = 0b0000000000000100;
40        // ACKKNOWLEDGE and RESET are write only
41        // const ACKKNOWLEDGE      = 0b0000000000010000;
42        // const RESET             = 0b0000000001000000;
43        const RX_INTERRUPT_MODE    = 0b0000001100000000;
44        const TX_INTERRUPT_ENABLE  = 0b0000010000000000;
45        const RX_INTERRUPT_ENABLE  = 0b0000100000000000;
46        const ACK_INTERRUPT_ENABLE = 0b0001000000000000;
47        const JOY_SLOT             = 0b0010000000000000;
48        const UNKNOWN              = 0b0000000000101000;
49        // const NOT_USED          = 0b1100000010000000;
50    }
51}
52
53impl JoyControl {
54    fn tx_enable(&self) -> bool {
55        self.intersects(Self::TX_ENABLE)
56    }
57
58    fn rx_force_enable(&self) -> bool {
59        self.intersects(Self::RX_FORCE_ENABLE)
60    }
61
62    fn joy_selected(&self) -> bool {
63        self.intersects(Self::JOY_SELECT)
64    }
65
66    fn ack_interrupt_enable(&self) -> bool {
67        self.intersects(Self::ACK_INTERRUPT_ENABLE)
68    }
69
70    fn joy_slot(&self) -> u8 {
71        self.intersects(Self::JOY_SLOT) as u8
72    }
73}
74
75bitflags! {
76    #[derive(Default, Debug)]
77    struct JoyMode: u16 {
78        const BAUDRATE_RELOAD_FACTOR = 0b0000000000000011;
79        const CHARACTER_LENGTH       = 0b0000000000001100;
80        const PARITY_ENABLE          = 0b0000000000010000;
81        const PARITY_TYPE            = 0b0000000000100000;
82        const CLK_OUTPUT_POLARITY    = 0b0000000100000000;
83        // const NOT_USED            = 0b1111111011000000;
84    }
85}
86
87impl JoyMode {
88    fn baudrate_reload_factor_shift(&self) -> u32 {
89        let bits = (self.bits() & Self::BAUDRATE_RELOAD_FACTOR.bits()) as u32;
90
91        if bits == 1 {
92            0
93        } else {
94            // 0 => 0 (MUL1)
95            // 2 => 4 (MUL16)
96            // 3 => 6 (MUL64)
97            bits * 2
98        }
99    }
100
101    fn character_length(&self) -> u8 {
102        let bits = ((self.bits() & Self::CHARACTER_LENGTH.bits()) >> 2) as u8;
103
104        5 + bits
105    }
106
107    fn clk_idle_on_high(&self) -> bool {
108        !self.intersects(Self::CLK_OUTPUT_POLARITY)
109    }
110}
111
112bitflags! {
113    #[derive(Default)]
114    struct JoyStat: u32 {
115        const TX_READY_1             = 0b0000000000000001;
116        const RX_FIFO_NOT_EMPTY      = 0b0000000000000010;
117        const TX_READY_2             = 0b0000000000000100;
118        const RX_PARITY_ERROR        = 0b0000000000001000;
119        const ACK_INPUT_LEVEL_LOW    = 0b0000000010000000;
120        const INTERRUPT_REQUEST      = 0b0000001000000000;
121        // const NOT_USED            = 0b0000010101110000;
122        // the rest is for the timer
123    }
124}
125
126mod controller {
127    #[derive(Debug, Clone, Copy)]
128    pub enum ControllerMode {
129        ReadButtons,
130        Config,
131        SetLed,
132        GetLed,
133        SetRumble,
134        GetWhateverValues,
135        GetVariableResponseA,
136        GetVariableResponseB,
137
138        /// Unknown that will always return 6 zeros
139        Unknown60,
140        /// Unknown that will return 4 zeros, one, then zero
141        Unknown4010,
142    }
143
144    /// Emulate Digital pad controller communication
145    pub struct Controller {
146        state: u8,
147        device_id: u16,
148        digital_switches: u16,
149        connected: bool,
150        current_mode: ControllerMode,
151        in_config: bool,
152
153        led: bool,
154        rumble_config: [u8; 6],
155
156        /// Internal value with many purposes in the input state flow
157        /// Used to store a value that may be used later in the flow
158        cache_value: u8,
159    }
160
161    impl Controller {
162        pub fn new(connected: bool) -> Self {
163            Self {
164                state: 0,
165                in_config: false,
166                current_mode: ControllerMode::ReadButtons,
167                device_id: 0x5A41,        // digital controller
168                digital_switches: 0xFFFF, // all released
169                connected,
170
171                led: false,
172                rumble_config: [0xFF; 6],
173                cache_value: 0,
174            }
175        }
176
177        pub fn change_key_state(&mut self, key: super::DigitalControllerKey, pressed: bool) {
178            let mask = key.mask();
179
180            if pressed {
181                self.digital_switches &= !mask;
182            } else {
183                self.digital_switches |= mask;
184            }
185        }
186
187        pub fn start_access(&mut self) -> u8 {
188            if self.connected {
189                self.state = 1;
190                0
191            } else {
192                0xFF
193            }
194        }
195
196        fn exchange_bytes_normal(&mut self, inp: u8) -> (u8, bool) {
197            match self.state {
198                1 => {
199                    self.current_mode = match inp {
200                        0x42 => ControllerMode::ReadButtons,
201                        0x43 => ControllerMode::Config,
202                        _ => todo!("Controller first input {:02X} is not supported", inp),
203                    };
204
205                    self.state = 2;
206                    ((self.device_id & 0xFF) as u8, false)
207                }
208                2 => {
209                    // if `inp == 1`, then `multitap` is enabled
210                    // but this is not a multitap controller, so will return
211                    // the normal `device id`
212                    assert!(inp == 0 || inp == 1);
213                    self.state = 3;
214                    (((self.device_id >> 8) & 0xFF) as u8, false)
215                }
216                3 => {
217                    match self.current_mode {
218                        ControllerMode::ReadButtons => {
219                            // TODO: handle rumble
220                        }
221                        ControllerMode::Config => {
222                            assert!(inp == 1 || inp == 0);
223                            self.cache_value = inp;
224                        }
225                        _ => unreachable!(),
226                    }
227                    self.state = 4;
228                    ((self.digital_switches & 0xFF) as u8, false)
229                }
230                4 => {
231                    match self.current_mode {
232                        ControllerMode::ReadButtons => {
233                            // TODO: handle rumble
234                        }
235                        ControllerMode::Config => {
236                            assert_eq!(inp, 0);
237                            self.in_config = self.cache_value == 1;
238                        }
239                        _ => unreachable!(),
240                    }
241                    self.state = 0;
242                    (((self.digital_switches >> 8) & 0xFF) as u8, true)
243                }
244                // TODO: handle for analog input
245                _ => unreachable!(),
246            }
247        }
248
249        fn exchange_bytes_config(&mut self, inp: u8) -> (u8, bool) {
250            match self.state {
251                1 => {
252                    self.current_mode = match inp {
253                        0x40 | 0x41 | 0x49 | 0x4A | 0x4B | 0x4E | 0x4F => ControllerMode::Unknown60,
254                        0x42 => ControllerMode::ReadButtons,
255                        0x43 => ControllerMode::Config,
256                        0x44 => ControllerMode::SetLed,
257                        0x45 => ControllerMode::GetLed,
258                        0x46 => ControllerMode::GetVariableResponseA,
259                        0x47 => ControllerMode::GetWhateverValues,
260                        0x48 => ControllerMode::Unknown4010,
261                        0x4C => ControllerMode::GetVariableResponseB,
262                        0x4D => ControllerMode::SetRumble,
263                        _ => todo!("unknown controller mode: {:02X}", inp),
264                    };
265
266                    self.state = 2;
267                    (0xF3, false)
268                }
269                2 => {
270                    // if `inp == 1`, then `multitap` is enabled
271                    // but this is not a multitap controller, so will return
272                    // the normal `device id`
273                    assert!(inp == 0 || inp == 1);
274                    self.state = 3;
275                    (0x5A, false)
276                }
277                3 => {
278                    let ret = match self.current_mode {
279                        ControllerMode::ReadButtons => {
280                            // TODO: handle rumble
281                            (self.digital_switches & 0xFF) as u8
282                        }
283                        ControllerMode::Config => {
284                            assert!(inp == 1 || inp == 0);
285                            self.cache_value = inp;
286                            0
287                        }
288                        ControllerMode::SetLed => {
289                            assert!(inp == 1 || inp == 0);
290                            self.cache_value = inp;
291                            0
292                        }
293                        ControllerMode::GetLed => {
294                            assert!(inp == 0);
295                            1
296                        }
297                        ControllerMode::GetVariableResponseA => {
298                            self.cache_value = inp;
299                            0
300                        }
301                        ControllerMode::GetVariableResponseB => {
302                            // used to identify dual shock controllers
303                            self.cache_value = match inp {
304                                0 => 4,
305                                1 => 7,
306                                _ => 0,
307                            };
308                            0
309                        }
310                        ControllerMode::GetWhateverValues
311                        | ControllerMode::Unknown60
312                        | ControllerMode::Unknown4010 => {
313                            assert!(inp == 0);
314                            0
315                        }
316                        ControllerMode::SetRumble => {
317                            let ret = self.rumble_config[0];
318                            self.rumble_config[0] = inp;
319                            ret
320                        }
321                    };
322                    self.state = 4;
323                    (ret, false)
324                }
325                4 => {
326                    let ret = match self.current_mode {
327                        ControllerMode::ReadButtons => {
328                            // TODO: handle rumble
329                            ((self.digital_switches >> 8) & 0xFF) as u8
330                        }
331                        ControllerMode::Config => {
332                            assert_eq!(inp, 0);
333                            0
334                        }
335                        ControllerMode::SetLed => {
336                            // only apply LED if `inp == 2`
337                            if inp == 2 {
338                                self.led = self.cache_value == 1;
339                            }
340                            // Side effect reset rumble to 0xFF
341                            self.rumble_config = [0xFF; 6];
342                            0
343                        }
344                        ControllerMode::GetLed => {
345                            assert!(inp == 0);
346                            2
347                        }
348                        ControllerMode::GetVariableResponseA
349                        | ControllerMode::GetVariableResponseB
350                        | ControllerMode::GetWhateverValues
351                        | ControllerMode::Unknown60
352                        | ControllerMode::Unknown4010 => {
353                            assert!(inp == 0);
354                            0
355                        }
356                        ControllerMode::SetRumble => {
357                            let ret = self.rumble_config[1];
358                            self.rumble_config[1] = inp;
359                            ret
360                        }
361                    };
362                    self.state = 5;
363                    (ret, false)
364                }
365                5 => {
366                    let ret = match self.current_mode {
367                        ControllerMode::GetLed => self.led as u8,
368                        ControllerMode::GetWhateverValues => 2,
369                        ControllerMode::GetVariableResponseA => match self.cache_value {
370                            0 | 1 => 1,
371                            _ => 0,
372                        },
373                        ControllerMode::SetRumble => {
374                            let ret = self.rumble_config[2];
375                            self.rumble_config[2] = inp;
376                            ret
377                        }
378                        _ => 0,
379                    };
380                    self.state = 6;
381                    (ret, false)
382                }
383                6 => {
384                    let ret = match self.current_mode {
385                        ControllerMode::GetLed => 2,
386                        ControllerMode::GetVariableResponseA => match self.cache_value {
387                            0 => 2,
388                            1 => 1,
389                            _ => 0,
390                        },
391                        ControllerMode::GetVariableResponseB => self.cache_value,
392                        ControllerMode::SetRumble => {
393                            let ret = self.rumble_config[3];
394                            self.rumble_config[3] = inp;
395                            ret
396                        }
397                        _ => 0,
398                    };
399                    self.state = 7;
400                    (ret, false)
401                }
402                7 => {
403                    let ret = match self.current_mode {
404                        ControllerMode::GetLed => 1,
405                        ControllerMode::GetWhateverValues => 1,
406                        ControllerMode::GetVariableResponseA => match self.cache_value {
407                            1 => 1,
408                            _ => 0,
409                        },
410                        ControllerMode::SetRumble => {
411                            let ret = self.rumble_config[4];
412                            self.rumble_config[4] = inp;
413                            ret
414                        }
415                        ControllerMode::Unknown4010 => 1,
416                        _ => 0,
417                    };
418                    self.state = 8;
419                    (ret, false)
420                }
421                8 => {
422                    let ret = match self.current_mode {
423                        ControllerMode::GetVariableResponseA => match self.cache_value {
424                            0 => 0x0a,
425                            1 => 0x14,
426                            _ => 0,
427                        },
428                        ControllerMode::SetRumble => {
429                            let ret = self.rumble_config[5];
430                            self.rumble_config[5] = inp;
431                            ret
432                        }
433                        ControllerMode::Config => {
434                            self.in_config = self.cache_value == 1;
435                            0
436                        }
437                        _ => 0,
438                    };
439                    self.state = 0;
440                    (ret, true)
441                }
442                _ => unreachable!(),
443            }
444        }
445
446        pub fn exchange_bytes(&mut self, inp: u8) -> (u8, bool) {
447            let state = self.state;
448            if self.in_config {
449                let r = self.exchange_bytes_config(inp);
450                log::trace!(
451                    "C Config: State {state:?}: {:02X} -> ({:02X}, {})",
452                    inp,
453                    r.0,
454                    r.1
455                );
456                r
457            } else {
458                let r = self.exchange_bytes_normal(inp);
459                log::trace!(
460                    "C Normal: State {state:?}: {:02X} -> ({:02X}, {})",
461                    inp,
462                    r.0,
463                    r.1
464                );
465                r
466            }
467        }
468    }
469}
470
471mod memcard {
472    use std::{fmt::Write, fs};
473
474    #[derive(Debug, Clone, Copy, PartialEq)]
475    pub enum CardReadStage {
476        Command,
477        MemoryCardId1,
478        MemoryCardId2,
479        SendAddressMsb,
480        SendAddressLsb,
481        ConfirmAddressMsb,
482        ConfirmAddressLsb,
483        Data,
484        Checksum,
485        CommandAck1,
486        CommandAck2,
487        End,
488
489        CmdIdEnd1,
490        CmdIdEnd2,
491        CmdIdEnd3,
492        CmdIdEnd4,
493    }
494
495    pub enum CardCmd {
496        Read,
497        Write,
498        Id,
499        Invalid,
500    }
501
502    pub struct MemoryCard {
503        id: u8,
504        stage: CardReadStage,
505        cmd: CardCmd,
506        flag: u8,
507        address: u16,
508        read_pointer: u8,
509        checksum: u8,
510        status: u8,
511        previous: u8,
512        data: Box<[u8; 0x400 * 128]>,
513    }
514
515    impl MemoryCard {
516        pub fn new(id: u8) -> Self {
517            let mut data = Box::new([0; 0x400 * 128]);
518
519            let block0 = &mut data[0..0x400 * 8];
520
521            block0[0] = b'M';
522            block0[1] = b'C';
523            block0[0x7F] = 0xE;
524
525            // TODO: move to managed folder with resources
526            fs::read(format!("memcard{}.mcd", id))
527                .map(|m| {
528                    if m.len() == 0x400 * 128 {
529                        println!("Loaded memory card {}", id);
530                        data.copy_from_slice(&m);
531                    }
532                })
533                .ok();
534
535            Self {
536                id,
537                stage: CardReadStage::Command,
538                cmd: CardCmd::Read, // anything for now, will be overridden on cmd start
539                flag: 0x08,
540                read_pointer: 0,
541                address: 0,
542                checksum: 0,
543                status: 0,
544                previous: 0,
545                data,
546            }
547        }
548
549        pub fn start_access(&mut self) -> u8 {
550            log::trace!("Memory card {} started access", self.id);
551            self.stage = CardReadStage::Command;
552            self.read_pointer = 0;
553            self.address = 0;
554            self.checksum = 0;
555            self.status = 0;
556            self.previous = 0;
557            0
558        }
559
560        pub fn exchange_bytes(&mut self, inp: u8) -> (u8, bool) {
561            let r = match self.stage {
562                CardReadStage::Command => {
563                    self.cmd = match inp {
564                        b'R' => CardCmd::Read,
565                        b'W' => CardCmd::Write,
566                        b'S' => CardCmd::Id,
567                        _ => CardCmd::Invalid, // will abort after next byte
568                    };
569                    self.stage = CardReadStage::MemoryCardId1;
570                    (self.flag, false)
571                }
572                CardReadStage::MemoryCardId1 => {
573                    assert_eq!(inp, 0);
574                    self.stage = CardReadStage::MemoryCardId2;
575                    // In case of invalid command, the communication is aborted
576                    // with 0xFF
577                    match self.cmd {
578                        CardCmd::Invalid => {
579                            self.stage = CardReadStage::Command;
580                            (0xFF, true)
581                        }
582                        _ => (0x5A, false),
583                    }
584                }
585                CardReadStage::MemoryCardId2 => {
586                    assert_eq!(inp, 0);
587                    match self.cmd {
588                        CardCmd::Read | CardCmd::Write => {
589                            self.stage = CardReadStage::SendAddressMsb;
590                        }
591                        CardCmd::Id => {
592                            self.stage = CardReadStage::CommandAck1;
593                        }
594                        CardCmd::Invalid => unreachable!(),
595                    }
596
597                    (0x5D, false)
598                }
599                CardReadStage::SendAddressMsb => {
600                    // start of checksum
601                    self.checksum = inp;
602                    self.previous = inp;
603                    self.address = (inp as u16) << 8;
604                    self.stage = CardReadStage::SendAddressLsb;
605                    (self.previous, false)
606                }
607                CardReadStage::SendAddressLsb => {
608                    self.checksum ^= inp;
609                    self.address |= inp as u16;
610                    match self.cmd {
611                        CardCmd::Read => {
612                            self.stage = CardReadStage::CommandAck1;
613                        }
614                        CardCmd::Write => {
615                            self.stage = CardReadStage::Data;
616                        }
617                        _ => unreachable!("Id command cannot send Address"),
618                    }
619
620                    // invalid address
621                    if (self.address & !0x3FF) != 0 {
622                        self.status = 0xFF;
623                    }
624
625                    (self.previous, false)
626                }
627                CardReadStage::ConfirmAddressMsb => {
628                    assert_eq!(inp, 0);
629
630                    self.stage = CardReadStage::ConfirmAddressLsb;
631                    // invalid address
632                    if self.status == 0xFF {
633                        (0xFF, false)
634                    } else {
635                        ((self.address >> 8) as u8, false)
636                    }
637                }
638                CardReadStage::ConfirmAddressLsb => {
639                    assert_eq!(inp, 0);
640                    // invalid address
641                    if self.status == 0xFF {
642                        self.stage = CardReadStage::Command;
643                        // abort transfer for Read commands
644                        (0xFF, true)
645                    } else {
646                        self.stage = CardReadStage::Data;
647                        (self.address as u8, false)
648                    }
649                }
650                CardReadStage::Data => {
651                    let r = match self.cmd {
652                        CardCmd::Read => {
653                            assert_eq!(inp, 0);
654                            let addr = self.address as usize * 128 + self.read_pointer as usize;
655                            let data = self.data[addr];
656                            self.checksum ^= data;
657                            data
658                        }
659                        CardCmd::Write => {
660                            if self.read_pointer == 0 {
661                                // reset flag on write
662                                self.flag = 0x00;
663                            }
664                            // valid address
665                            if self.status != 0xFF {
666                                self.checksum ^= inp;
667                                let addr = self.address as usize * 128 + self.read_pointer as usize;
668                                self.data[addr] = inp;
669                            }
670                            // return previous and set it
671                            std::mem::replace(&mut self.previous, inp)
672                        }
673                        _ => unreachable!("Id command cannot send/recv Data"),
674                    };
675
676                    self.read_pointer += 1;
677
678                    // for debugging
679                    if self.read_pointer == 128 {
680                        let mut buf = String::new();
681                        for i in 0..128 {
682                            let addr = self.address as usize * 128 + i as usize;
683                            let data = self.data[addr];
684                            write!(buf, "{:02X} ", data).unwrap();
685                        }
686                        log::info!(
687                            "[{}]: address: 0x{:04X}\n {}",
688                            if let CardCmd::Read = self.cmd {
689                                'R'
690                            } else {
691                                'W'
692                            },
693                            self.address,
694                            buf
695                        );
696                        self.stage = CardReadStage::Checksum;
697                    }
698
699                    (r, false)
700                }
701                CardReadStage::Checksum => match self.cmd {
702                    CardCmd::Read => {
703                        assert_eq!(inp, 0);
704                        self.stage = CardReadStage::End;
705                        self.status = 0x47; // Good
706                        (self.checksum, false)
707                    }
708                    CardCmd::Write => {
709                        if self.status == 0 {
710                            if self.checksum == inp {
711                                self.status = 0x47; // Good
712                            } else {
713                                self.status = 0x4E; // Bad checksum
714                            }
715                        } else {
716                            self.status = 0xFF;
717                        }
718                        self.stage = CardReadStage::CommandAck1;
719                        (self.previous, false)
720                    }
721                    _ => unreachable!("Id command cannot send/recv Checksum"),
722                },
723                CardReadStage::CommandAck1 => {
724                    assert_eq!(inp, 0);
725                    // late /ACK after this byte-pair on Read command
726                    self.stage = CardReadStage::CommandAck2;
727                    (0x5C, false)
728                }
729                CardReadStage::CommandAck2 => {
730                    assert_eq!(inp, 0);
731                    match self.cmd {
732                        CardCmd::Read => {
733                            self.stage = CardReadStage::ConfirmAddressMsb;
734                        }
735                        CardCmd::Write => {
736                            self.stage = CardReadStage::End;
737                        }
738                        CardCmd::Id => {
739                            self.stage = CardReadStage::CmdIdEnd1;
740                        }
741                        CardCmd::Invalid => unreachable!(),
742                    }
743
744                    (0x5D, false)
745                }
746                CardReadStage::End => {
747                    assert_eq!(inp, 0);
748
749                    // if we finished a write command successfully, flush it to disk.
750                    if let CardCmd::Write = self.cmd {
751                        self.flush();
752                    }
753
754                    self.stage = CardReadStage::Command;
755                    (0x4 | self.status, true)
756                }
757                CardReadStage::CmdIdEnd1 => {
758                    assert_eq!(inp, 0);
759                    self.stage = CardReadStage::CmdIdEnd2;
760                    (0x04, false)
761                }
762                CardReadStage::CmdIdEnd2 => {
763                    assert_eq!(inp, 0);
764                    self.stage = CardReadStage::CmdIdEnd3;
765                    (0x00, false)
766                }
767                CardReadStage::CmdIdEnd3 => {
768                    assert_eq!(inp, 0);
769                    self.stage = CardReadStage::CmdIdEnd4;
770                    (0x00, false)
771                }
772                CardReadStage::CmdIdEnd4 => {
773                    assert_eq!(inp, 0);
774                    self.stage = CardReadStage::Command;
775                    (0x80, true)
776                }
777            };
778
779            log::trace!(
780                "M{}: Stage {:?}: {:02X} -> ({:02X}, {})",
781                self.id,
782                self.stage,
783                inp,
784                r.0,
785                r.1
786            );
787            r
788        }
789
790        /// Saves the data to disk
791        fn flush(&mut self) {
792            fs::write(format!("memcard{}.mcd", self.id), &self.data[..]).unwrap();
793        }
794    }
795}
796
797/// Groups the controller and memory_card components for communication
798struct CommunicationHandler {
799    /// which component we are communicating with now
800    state: u8,
801    controller: controller::Controller,
802    memory_card: memcard::MemoryCard,
803}
804
805impl CommunicationHandler {
806    /// `id` is used to indicate which memory card file to save/load from
807    fn new(id: u8, controller_connected: bool) -> Self {
808        Self {
809            state: 0,
810            controller: controller::Controller::new(controller_connected),
811            memory_card: memcard::MemoryCard::new(id),
812        }
813    }
814}
815
816impl CommunicationHandler {
817    fn exchange_bytes(&mut self, inp: u8) -> u8 {
818        match self.state {
819            0 => match inp {
820                0x01 => {
821                    let out = self.controller.start_access();
822                    if out != 0xFF {
823                        self.state = 1;
824                    }
825                    out
826                }
827                0x81 => {
828                    let out = self.memory_card.start_access();
829                    if out != 0xFF {
830                        self.state = 2;
831                    }
832                    out
833                }
834                _ => {
835                    log::warn!("Invalid first received: 0x{:02X}", inp);
836                    self.state = 0;
837                    0
838                }
839            },
840            1 => {
841                let (result, done) = self.controller.exchange_bytes(inp);
842                if done {
843                    self.state = 0;
844                }
845                result
846            }
847            2 => {
848                let (result, done) = self.memory_card.exchange_bytes(inp);
849                if done {
850                    self.state = 0;
851                }
852                result
853            }
854            _ => unreachable!(),
855        }
856    }
857
858    fn change_controller_key_state(&mut self, key: DigitalControllerKey, pressed: bool) {
859        self.controller.change_key_state(key, pressed);
860    }
861
862    fn has_more(&self) -> bool {
863        self.state != 0
864    }
865}
866
867pub struct ControllerAndMemoryCard {
868    ctrl: JoyControl,
869    mode: JoyMode,
870    stat: JoyStat,
871    baudrate_timer_reload: u32,
872    baudrate_timer: u32,
873    clk_position_high: bool,
874    transfered_bits: u8,
875    tx_fifo: VecDeque<u8>,
876    rx_fifo: VecDeque<u8>,
877
878    communication_handlers: [CommunicationHandler; 2],
879}
880
881impl Default for ControllerAndMemoryCard {
882    fn default() -> Self {
883        let baudrate_timer_reload = 0x0088;
884        let baudrate_timer = baudrate_timer_reload / 2;
885        Self {
886            ctrl: JoyControl::empty(),
887            mode: JoyMode::from_bits_retain(0x000D),
888            stat: JoyStat::TX_READY_1 | JoyStat::TX_READY_2,
889            baudrate_timer_reload,
890            baudrate_timer,
891            transfered_bits: 0,
892            clk_position_high: false,
893            tx_fifo: VecDeque::new(),
894            rx_fifo: VecDeque::new(),
895
896            communication_handlers: [
897                CommunicationHandler::new(0, true),
898                CommunicationHandler::new(1, false),
899            ],
900        }
901    }
902}
903
904impl ControllerAndMemoryCard {
905    pub fn clock(&mut self, interrupt_requester: &mut impl InterruptRequester, mut cycles: u32) {
906        while cycles > 0 {
907            let (r, overflow) = cycles.overflowing_sub(self.baudrate_timer);
908
909            if overflow {
910                // this cannot overflow, because the `self.baudrate_timer` is
911                // larger than `cycles`, so no need to check
912                self.baudrate_timer -= cycles;
913                return;
914            }
915
916            cycles = r;
917            // reset to zero (as if we subtracted from `cycles`)
918            self.baudrate_timer = 0;
919
920            // reload timer
921            self.trigger_baudrate_reload();
922            // advance the clock one step
923            self.clk_position_high = !self.clk_position_high;
924
925            // if there is anything to transfer and
926            // the clock changes from idle to active, transfer one bit
927            if !self.tx_fifo.is_empty()
928                && self.ctrl.tx_enable()
929                && (self.clk_position_high ^ self.mode.clk_idle_on_high())
930            {
931                self.transfered_bits += 1;
932
933                if self.transfered_bits == self.mode.character_length() {
934                    self.transfered_bits = 0;
935                    let byte_to_send = self.tx_fifo.pop_front().unwrap();
936                    let byte_mask = 0xFF >> (8 - self.mode.character_length());
937                    // make sure we don't have extra stuff to send and we are not sending
938                    assert!(byte_to_send & !byte_mask == 0);
939                    log::info!("sending byte {:02X}", byte_to_send);
940
941                    let slot = self.ctrl.joy_slot() as usize;
942
943                    let received_byte =
944                        self.communication_handlers[slot].exchange_bytes(byte_to_send);
945                    // make sure we don't have extra stuff to send and we are not sending
946                    assert!(received_byte & !byte_mask == 0);
947                    log::info!("got byte {:02X}", received_byte);
948                    if self.ctrl.joy_selected() || self.ctrl.rx_force_enable() {
949                        self.push_to_rx_fifo(received_byte);
950                    }
951
952                    if self.communication_handlers[slot].has_more() {
953                        self.send_ack_interrupt();
954                        interrupt_requester.request_controller_mem_card();
955                    }
956                }
957            }
958        }
959    }
960
961    pub fn change_controller_key_state(&mut self, key: DigitalControllerKey, pressed: bool) {
962        self.communication_handlers[0].change_controller_key_state(key, pressed);
963    }
964}
965
966impl ControllerAndMemoryCard {
967    fn get_stat(&self) -> u32 {
968        let timer = self.baudrate_timer & 0x1FFFFF;
969        self.stat.bits() | (timer << 11)
970    }
971
972    fn trigger_baudrate_reload(&mut self) {
973        let factored_reload =
974            self.baudrate_timer_reload << self.mode.baudrate_reload_factor_shift();
975        self.baudrate_timer = factored_reload / 2;
976    }
977
978    fn push_to_tx_fifo(&mut self, data: u8) {
979        // max size is 2
980        assert!(self.tx_fifo.len() < 2);
981        self.tx_fifo.push_back(data);
982    }
983
984    fn push_to_rx_fifo(&mut self, data: u8) {
985        // max size is 8
986        assert!(self.tx_fifo.len() < 8);
987        self.rx_fifo.push_back(data);
988        self.stat.insert(JoyStat::RX_FIFO_NOT_EMPTY);
989    }
990
991    fn pop_from_rx_fifo(&mut self) -> u8 {
992        let out = self.rx_fifo.pop_front().unwrap_or(0);
993        if self.rx_fifo.is_empty() {
994            self.stat.remove(JoyStat::RX_FIFO_NOT_EMPTY);
995        }
996        out
997    }
998
999    fn send_ack_interrupt(&mut self) {
1000        // self.stat.insert(JoyStat::ACK_INPUT_LEVEL_LOW);
1001        if self.ctrl.ack_interrupt_enable() {
1002            self.stat.insert(JoyStat::INTERRUPT_REQUEST);
1003        }
1004    }
1005
1006    fn acknowledge_interrupt(&mut self) {
1007        self.stat
1008            .remove(JoyStat::INTERRUPT_REQUEST | JoyStat::RX_PARITY_ERROR);
1009    }
1010}
1011
1012impl BusLine for ControllerAndMemoryCard {
1013    fn read_u32(&mut self, addr: u32) -> Result<u32> {
1014        let r = match addr {
1015            0x4 => self.get_stat(),
1016            _ => unreachable!(),
1017        };
1018        Ok(r)
1019    }
1020
1021    fn read_u16(&mut self, addr: u32) -> Result<u16> {
1022        let r = match addr {
1023            0x4 => self.get_stat() as u16,
1024            0x8 => self.mode.bits(),
1025            0xA => self.ctrl.bits(),
1026            0xE => self.baudrate_timer_reload as u16,
1027            _ => unreachable!(),
1028        };
1029        Ok(r)
1030    }
1031
1032    fn write_u16(&mut self, addr: u32, data: u16) -> Result<()> {
1033        match addr {
1034            0x8 => {
1035                self.mode = JoyMode::from_bits_retain(data);
1036                log::info!("joy mode write {:04X} => {:?}", data, self.mode);
1037            }
1038            0xA => {
1039                self.ctrl = JoyControl::from_bits_retain(data);
1040                log::info!("joy ctrl write {:04X} => {:?}", data, self.ctrl);
1041                if data & JOY_CTRL_ACKKNOWLEDGE != 0 {
1042                    log::info!("joy acknowledge interrupt");
1043                    self.acknowledge_interrupt();
1044                }
1045                if data & JOY_CTRL_RESET != 0 {
1046                    // TODO: not sure what it means by "Reset most JOY_registers to zero"
1047                    log::info!("joy reset");
1048
1049                    self.trigger_baudrate_reload();
1050                    self.transfered_bits = 0;
1051                    self.tx_fifo.clear();
1052                    self.rx_fifo.clear();
1053                    self.clk_position_high = false;
1054
1055                    // reset the communication handlers
1056                    self.communication_handlers[0].state = 0;
1057                    self.communication_handlers[1].state = 0;
1058                }
1059
1060                // zero, reset communication handlers
1061                if data == 0 {
1062                    self.trigger_baudrate_reload();
1063                    self.transfered_bits = 0;
1064                    self.tx_fifo.clear();
1065                    self.rx_fifo.clear();
1066                    self.clk_position_high = false;
1067
1068                    self.communication_handlers[0].state = 0;
1069                    self.communication_handlers[1].state = 0;
1070                }
1071            }
1072            0xE => {
1073                log::info!("baudrate reload value {:04X}", data);
1074                self.baudrate_timer_reload = data as u32;
1075                self.trigger_baudrate_reload();
1076            }
1077            _ => unreachable!(),
1078        }
1079        Ok(())
1080    }
1081
1082    // only used with 0x1F801040
1083    fn read_u8(&mut self, addr: u32) -> Result<u8> {
1084        assert!(addr == 0);
1085        Ok(self.pop_from_rx_fifo())
1086    }
1087
1088    // only used with 0x1F801040
1089    fn write_u8(&mut self, addr: u32, data: u8) -> Result<()> {
1090        assert!(addr == 0);
1091        self.push_to_tx_fifo(data);
1092        log::info!("Add to TX fifo {:02X}", data);
1093        Ok(())
1094    }
1095}